Taktiken zur Verwendung von PHP in einer Hochlast-Site


242

Bevor Sie darauf antworten, habe ich noch nie etwas entwickelt, das populär genug ist, um eine hohe Serverlast zu erreichen. Behandle mich als (Seufzer) einen Außerirdischen, der gerade auf dem Planeten gelandet ist, obwohl er PHP und einige Optimierungstechniken kennt.


Ich entwickle ein Tool in PHP , das eine Menge Benutzer erreichen könnte, wenn es richtig funktioniert. Obwohl ich in der Lage bin, das Programm zu entwickeln, bin ich ziemlich ahnungslos, wenn es darum geht, etwas zu entwickeln, das mit großem Datenverkehr umgehen kann. Hier sind ein paar Fragen dazu (Sie können diese Frage auch in einen Ressourcen-Thread verwandeln).

Datenbanken

Im Moment plane ich, die MySQLi-Funktionen in PHP5 zu verwenden. Wie soll ich die Datenbanken jedoch in Bezug auf Benutzer und Inhalte einrichten? Muss ich wirklich brauchen mehrere Datenbanken? Im Moment ist alles in einer Datenbank durcheinander - obwohl ich überlegt habe, Benutzerdaten auf eine, tatsächliche Inhalte auf eine andere und schließlich Kerninhalte der Website (Vorlagenmaster usw.) auf eine andere zu verteilen. Meine Argumentation dahinter ist, dass das Senden von Abfragen an verschiedene Datenbanken das Laden dieser Anfragen als eine Datenbank = 3 Ladequellen erleichtert. Wäre dies auch dann noch effektiv, wenn sich alle auf demselben Server befänden?

Caching

Ich habe ein Vorlagensystem, mit dem die Seiten erstellt und Variablen ausgetauscht werden. Master-Vorlagen werden in der Datenbank gespeichert und jedes Mal, wenn eine Vorlage aufgerufen wird, wird ihre zwischengespeicherte Kopie (ein HTML-Dokument) aufgerufen. Im Moment habe ich zwei Arten von Variablen in diesen Vorlagen - eine statische und eine dynamische Variable. Statische Variablen sind normalerweise Dinge wie Seitennamen, der Name der Site - Dinge, die sich nicht oft ändern; Dynamische Vars sind Dinge, die sich bei jedem Laden der Seite ändern.

Meine Frage dazu:

Angenommen, ich habe Kommentare zu verschiedenen Artikeln. Was eine bessere Lösung ist: Speichern Sie die einfache Kommentarvorlage und rendern Sie Kommentare (aus einem DB-Aufruf) jedes Mal, wenn die Seite geladen wird, oder speichern Sie eine zwischengespeicherte Kopie der Kommentarseite als HTML-Seite - jedes Mal, wenn ein Kommentar hinzugefügt / bearbeitet / gelöscht wird Die Seite wird zwischengespeichert.

Schließlich

Hat jemand irgendwelche Tipps / Hinweise zum Ausführen einer Hochlast-Site auf PHP. Ich bin mir ziemlich sicher, dass es eine funktionierende Sprache ist - Facebook und Yahoo! Geben Sie ihm großen Vorrang - aber gibt es irgendwelche Erfahrungen, auf die ich achten sollte?


9
3,5 Jahre später und ich kann mich nicht einmal daran erinnern, woran ich gearbeitet habe, würde ich gerne wissen, was ich auch so cool fand :)
Ross

8
Lassen Sie dies eine Lektion über vorzeitige Optimierung für Sie sein :)
Rimu Atkinson

Antworten:


89

Keine zwei Standorte sind gleich. Sie benötigen wirklich ein Tool wie jmeter und Benchmark, um zu sehen, wo Ihre Problempunkte liegen. Sie können viel Zeit damit verbringen, zu raten und sich zu verbessern, aber Sie werden erst dann echte Ergebnisse sehen, wenn Sie Ihre Änderungen messen und vergleichen.

Zum Beispiel war der MySQL-Abfragecache viele Jahre lang die Lösung für alle unsere Leistungsprobleme. Wenn Ihre Site langsam war, schlugen MySQL-Experten vor, den Abfragecache zu aktivieren. Es stellt sich heraus, dass der Cache bei hoher Schreiblast tatsächlich lähmt. Wenn Sie es ohne Test einschalten würden, würden Sie es nie erfahren.

Und vergessen Sie nicht, dass Sie nie mit dem Skalieren fertig sind. Eine Site, die 10 req / s verarbeitet, muss geändert werden, um 1000 req / s zu unterstützen. Und wenn Sie das Glück haben, 10.000 req / s unterstützen zu müssen, wird Ihre Architektur wahrscheinlich auch ganz anders aussehen.

Datenbanken

  • Verwenden Sie MySQLi nicht - PDO ist die 'moderne' OO-Datenbankzugriffsschicht. Die wichtigste Funktion sind Platzhalter in Ihren Abfragen. Es ist intelligent genug, um serverseitige Vorbereitungen und andere Optimierungen auch für Sie zu verwenden.
  • Sie möchten Ihre Datenbank an dieser Stelle wahrscheinlich nicht auflösen. Wenn Sie feststellen, dass eine Datenbank nicht schneidet, können Sie je nach App verschiedene Techniken skalieren. Das Replizieren auf zusätzliche Server funktioniert normalerweise gut, wenn Sie mehr Lese- als Schreibvorgänge haben. Sharding ist eine Technik, mit der Sie Ihre Daten auf viele Computer aufteilen können.

Caching

  • Sie möchten wahrscheinlich nicht in Ihrer Datenbank zwischenspeichern. Die Datenbank ist in der Regel Ihr Engpass, daher ist das Hinzufügen weiterer E / A-Vorgänge in der Regel eine schlechte Sache. Es gibt mehrere PHP-Caches, die ähnliche Aufgaben wie APC und Zend ausführen .
  • Messen Sie Ihr System mit ein- und ausgeschaltetem Caching. Ich wette, Ihr Cache ist schwerer als das direkte Bereitstellen der Seiten.
  • Wenn das Erstellen Ihrer Kommentare und Artikeldaten aus der Datenbank lange dauert, integrieren Sie memcache in Ihr System. Sie können die Abfrageergebnisse zwischenspeichern und in einer zwischengespeicherten Instanz speichern. Es ist wichtig zu bedenken, dass das Abrufen der Daten aus dem Memcache schneller sein muss als das Zusammenstellen aus der Datenbank, um einen Nutzen zu erzielen.
  • Wenn Ihre Artikel nicht dynamisch sind oder Sie nach der Generierung einfache dynamische Änderungen haben, sollten Sie HTML oder PHP auf die Festplatte schreiben. Sie könnten eine index.php-Seite haben, die auf der Festplatte nach dem Artikel sucht. Wenn er dort ist, wird er an den Client gestreamt. Ist dies nicht der Fall, wird der Artikel generiert, auf die Festplatte geschrieben und an den Client gesendet. Das Löschen von Dateien von der Festplatte würde dazu führen, dass Seiten neu geschrieben werden. Wenn einem Artikel ein Kommentar hinzugefügt wird, löschen Sie die zwischengespeicherte Kopie - sie wird neu generiert.

10
@writing auf Festplatte. Sie könnten sogar die index.php fallen lassen und Apache die Arbeit für Sie erledigen lassen, so dass index.php nur aufgerufen wird, wenn der Pfad nicht existiert. Sie würden dafür mode_rewrite verwenden.
Troelskn

5
-1, PDO ist deutlich langsamer als MySQLi oder sogar die MySQL-Erweiterung.
Alix Axel

4
PDO war viel langsamer als mysqli und funktionierte bei verschachtelten Abfragen für mich nicht richtig. Mysqli unterstützt ebenso wie PDO serverseitige Vorbereitungen und gebundene Parameter.
Daren Schwenke

5
Ich kann nicht glauben, dass dies als Antwort akzeptiert wurde. Es ist nicht sehr gut.
Symcbean

1
about: caching - images, css, htm und js helfen, deaktivieren Sie Cookies auch für Bilder!
Talvi Watia

61

Ich bin ein leitender Entwickler auf einer Website mit über 15 Millionen Benutzern. Wir hatten sehr wenig Skalierungsprobleme, weil wir es FRÜH geplant und nachdenklich skaliert haben. Hier sind einige der Strategien, die ich aus meiner Erfahrung vorschlagen kann.

SCHEMA Denormalisieren Sie zunächst Ihre Schemata. Dies bedeutet, dass Sie sich nicht für mehrere relationale Tabellen entscheiden sollten, sondern für eine große Tabelle. Im Allgemeinen sind Verknüpfungen eine Verschwendung wertvoller DB-Ressourcen, da durch mehrere Vorbereitungen und Sortierungen Festplatten-E / A-Vorgänge gebrannt werden. Vermeiden Sie sie, wenn Sie können.

Der Nachteil hierbei ist, dass Sie redundante Daten speichern / abrufen. Dies ist jedoch akzeptabel, da Daten und Bandbreite innerhalb des Käfigs sehr billig sind (größere Festplatten), während mehrere Vorbereitungs-E / A um Größenordnungen teurer sind (mehr Server). .

INDEXIERUNG Stellen Sie sicher, dass Ihre Abfragen mindestens einen Index verwenden. Beachten Sie jedoch, dass Indizes Sie kosten, wenn Sie häufig schreiben oder aktualisieren. Es gibt einige experimentelle Tricks, um dies zu vermeiden.

Sie können versuchen, zusätzliche nicht indizierte Spalten hinzuzufügen, die parallel zu Ihren indizierten Spalten ausgeführt werden. Anschließend können Sie einen Offline-Prozess ausführen, bei dem die nicht indizierten Spalten stapelweise über die indizierten Spalten geschrieben werden. Auf diese Weise können Sie besser steuern, wann mySQL den Index neu berechnen muss.

Vermeiden Sie berechnete Abfragen wie eine Pest. Wenn Sie eine Abfrage berechnen müssen, versuchen Sie dies einmal beim Schreiben.

CACHING Ich kann Memcached nur empfehlen. Es wurde von den größten Spielern auf dem PHP-Stack (Facebook) bewiesen und ist sehr flexibel. Dazu gibt es zwei Methoden: Eine wird in Ihrer DB-Schicht zwischengespeichert, die andere in Ihrer Geschäftslogikschicht.

Die DB-Layer-Option würde das Zwischenspeichern des Ergebnisses von Abfragen erfordern, die aus der DB abgerufen wurden. Sie können Ihre SQL-Abfrage mit md5 () hashen und als Suchschlüssel verwenden, bevor Sie zur Datenbank wechseln. Das Beste daran ist, dass es ziemlich einfach zu implementieren ist. Der Nachteil (abhängig von der Implementierung) ist, dass Sie an Flexibilität verlieren, weil Sie alle Caching-Vorgänge hinsichtlich des Cache-Ablaufs gleich behandeln.

In dem Shop, in dem ich arbeite, verwenden wir Business-Layer-Caching. Dies bedeutet, dass jede konkrete Klasse in unserem System ihr eigenes Caching-Schema und Cache-Timeouts steuert. Dies hat bei uns ziemlich gut funktioniert, aber beachten Sie, dass Elemente, die aus der Datenbank abgerufen werden, möglicherweise nicht mit Elementen aus dem Cache identisch sind. Daher müssen Sie Cache und Datenbank gemeinsam aktualisieren.

DATA SHARDING Replication bringt Sie nur so weit. Früher als erwartet werden Ihre Schreibvorgänge zu einem Engpass. Stellen Sie zum Ausgleich sicher, dass Sie das Daten-Sharding so früh wie möglich unterstützen. Sie werden sich wahrscheinlich später erschießen wollen, wenn Sie dies nicht tun.

Es ist ziemlich einfach zu implementieren. Grundsätzlich möchten Sie die Schlüsselberechtigung vom Datenspeicher trennen. Verwenden Sie eine globale Datenbank, um eine Zuordnung zwischen Primärschlüsseln und Cluster-IDs zu speichern. Sie fragen diese Zuordnung ab, um einen Cluster abzurufen, und fragen dann den Cluster ab, um die Daten abzurufen. Sie können diese Suchoperation zum Teufel zwischenspeichern, was sie zu einer vernachlässigbaren Operation macht.

Der Nachteil dabei ist, dass es möglicherweise schwierig ist, Daten aus mehreren Shards zusammenzufügen. Aber Sie können sich auch darum kümmern.

OFFLINE-VERARBEITUNG Lassen Sie den Benutzer nicht auf Ihr Backend warten, wenn dies nicht erforderlich ist. Erstellen Sie eine Jobwarteschlange und verschieben Sie alle Verarbeitungen, die Sie offline ausführen können, getrennt von der Benutzeranforderung.


9
+1 Zweifellos sollte dies die akzeptierte Antwort sein. Es ist interessant, dass alles, was ich jemals über das Erstellen von Datenbanken gelesen habe, immer lautet: "Normalisieren Sie alle Daten so weit wie möglich", ohne den Leistungseinbruch bei Joins zu erwähnen. Ich hatte immer intuitiv das Gefühl, dass Joins (insbesondere mehrere) viel Overhead verursachen, habe aber bis jetzt noch keine explizite Aussage gehört. Ich wünschte, ich hätte besser verstanden, wovon Sie gesprochen haben, als MySQL die Indizes berechnet. Das klingt nach einem sehr interessanten Hack.
Evan Plaice

Data Sharding ist wichtig für Datenbanken, die zu groß werden. Google (das Unternehmen, nicht die Suchmaschine) hat viele interessante Dinge über die Implementierung von Sharding-Schemata zu sagen. Die Offline-Verarbeitung ist auch enorm, wenn es darum geht, die Anzahl der Datenbankschreibvorgänge (und die Anzahl der Neuberechnungen des Tabellenindex) zu begrenzen. Ich habe viele Blogs gesehen (und ich denke sogar Stack Overflow), die diese Technik für ihre benutzergenerierten Kommentar- / Feedbacksysteme verwenden.
Evan Plaice

1
Vielen Dank für die Kommentare. Es ist erstaunlich, dass einige für die Profilerstellung von Code der mittleren Ebene argumentieren, wenn die VAST-Ausführungszeit entweder für Daten-E / A oder für Client-Server-E / A verwendet wird. Eine überaus komplizierte Optimierung, die 20% der Ausführungszeit eines PHP-Prozesses einspart und 40 ms dauert, ist sinnlos im Vergleich zu einfachen 5% Einsparungen bei einer 1s-Datenbankabfrage.
Thesmart

42

Ich habe an einigen Websites gearbeitet, die Millionen / Zugriffe / Monat mit PHP & MySQL unterstützen. Hier sind einige Grundlagen:

  1. Cache, Cache, Cache. Caching ist eine der einfachsten und effektivsten Methoden, um die Belastung Ihres Webservers und Ihrer Datenbank zu verringern. Cache-Seiteninhalt, Abfragen, teure Berechnungen, alles, was an E / A gebunden ist. Memcache ist kinderleicht und effektiv.
  2. Verwenden Sie mehrere Server, sobald Sie das Maximum erreicht haben. Sie können mehrere Webserver und mehrere Datenbankserver (mit Replikation) haben.
  3. Reduzieren Sie die Gesamtzahl der Anfragen an Ihre Webserver. Dies beinhaltet das Zwischenspeichern von JS, CSS und Bildern mithilfe abgelaufener Header. Sie können Ihren statischen Inhalt auch auf ein CDN verschieben, um die Benutzererfahrung zu beschleunigen.
  4. Messen & Benchmarking. Führen Sie Nagios auf Ihren Produktionsmaschinen aus und testen Sie die Last auf Ihrem dev / qa-Server. Sie müssen wissen, wann Ihr Server in Brand gerät, damit Sie dies verhindern können.

Ich würde empfehlen, Building Scalable Websites zu lesen . Es wurde von einem der Flickr-Ingenieure geschrieben und ist eine großartige Referenz.

Schauen Sie sich auch meinen Blog-Beitrag über Skalierbarkeit an. Er enthält viele Links zu Präsentationen über Skalierung mit mehreren Sprachen und Plattformen: http://www.ryandoherty.net/2008/07/13/unicorns-and-scalability/


1
+1 Hier gibt es viele gute Infos. Ich habe in letzter Zeit mehr zu diesem Thema recherchiert und Ihre Antwort stimmt mit allem überein, was ich gelesen habe. Memcache, Caching, CDN für statischen Inhalt, Reduzierung von Anforderungen; alles gute Zeug. Ich würde auch hinzufügen, Hashes auf statischen Inhaltsdateien (wenn Sie sich hinter einem CDN / Cache befinden) serverseitig generieren, damit die aktualisierten Dateien eine eindeutige Signatur im Cache haben. Kombinieren Sie außerdem statische Quelldateien (CSS, Javascript) im laufenden Betrieb (und zwischenspeichern Sie sie mit Dateinamen-Hashes), um Anforderungen zu reduzieren. Generieren Sie außerdem dynamisch Daumen (und speichern Sie sie im Cache)
Evan Plaice

Google hat ein Apache-Modul namens mod_pagespeed erstellt, das alle Dateiverkettungen, Minimierungen, Umbenennungen von Dateien mit Hash usw. für alle statischen Inhalte verarbeiten kann. Zunächst sollte den Servern nur ein geringer Verarbeitungsaufwand hinzugefügt werden, bis die Caches (und CDNs) mit dem größten Teil des Inhalts gefüllt sind. Aus Sicherheitsgründen ist es im Allgemeinen eine schlechte Idee, öffentlich zugängliche Tabellen (Benutzer) in dieselbe Datenbank wie Tabellen zu stellen, um das Back-End zu verwalten (wenn aus irgendeinem Grund eine der Tabellen gehackt werden sollte).
Evan Plaice

39

Betreff: PDO / MySQLi / MySQLND

@ Gary

Sie können nicht einfach sagen, dass Sie MySQLi nicht verwenden, da diese unterschiedliche Ziele haben. PDO ähnelt fast einer Abstraktionsschicht (obwohl dies nicht der Fall ist) und soll die Verwendung mehrerer Datenbankprodukte vereinfachen, während MySQLi spezifisch für MySQL-Verbindungen ist. Es ist falsch zu sagen, dass PDO die moderne Zugriffsschicht im Zusammenhang mit dem Vergleich mit MySQLi ist, da Ihre Aussage impliziert, dass der Fortschritt mysql -> mysqli -> PDO war, was nicht der Fall ist.

Die Wahl zwischen MySQLi und PDO ist einfach. Wenn Sie mehrere Datenbankprodukte unterstützen müssen, verwenden Sie PDO. Wenn Sie nur MySQL verwenden, können Sie zwischen PDO und MySQLi wählen.

Warum sollten Sie MySQLi anstelle von PDO wählen? Siehe unten...

@ross

Sie haben Recht mit MySQLnd, der neuesten Bibliothek auf MySQL-Kernsprachenebene. Sie ist jedoch kein Ersatz für MySQLi. MySQLi (wie bei PDO) bleibt die Art und Weise, wie Sie mit MySQL über Ihren PHP-Code interagieren würden. Beide verwenden libmysql als C-Client hinter dem PHP-Code. Das Problem ist, dass sich libmysql außerhalb der Kern-PHP-Engine befindet und hier mysqlnd ins Spiel kommt, dh es handelt sich um einen nativen Treiber, der die Kern-PHP-Interna verwendet, um die Effizienz zu maximieren, insbesondere wenn es um die Speichernutzung geht.

MySQLnd wird von MySQL selbst entwickelt und ist kürzlich auf dem PHP 5.3-Zweig gelandet, der sich in RC-Tests befindet und später in diesem Jahr veröffentlicht werden kann. Sie können dann MySQLnd mit MySQLi verwenden ... aber nicht mit PDO. Dies gibt MySQLi in vielen Bereichen (nicht in allen) einen Leistungsschub und macht es zur besten Wahl für die MySQL-Interaktion, wenn Sie nicht die abstraktionsähnlichen Funktionen von PDO benötigen.

Allerdings ist MySQLnd jetzt in PHP 5.3 für PDO verfügbar, sodass Sie die Vorteile der Leistungsverbesserungen von ND auf PDO nutzen können. PDO ist jedoch immer noch eine generische Datenbankschicht und wird daher wahrscheinlich nicht so viel davon profitieren können die Verbesserungen in ND wie MySQLi kann .

Einige nützliche Benchmarks finden sich hier , obwohl sie ab dem Jahr 2006 sind Sie müssen auch wie bewusst Dinge dieser Option .

Bei der Entscheidung zwischen MySQLi und PDO müssen viele Überlegungen berücksichtigt werden. In der Realität spielt es keine Rolle, bis Sie zu unglaublich hohen Anforderungsnummern gelangen. In diesem Fall ist es sinnvoller, eine Erweiterung zu verwenden, die speziell für MySQL entwickelt wurde, als eine, die Dinge abstrahiert und zufällig einen MySQL-Treiber bereitstellt .

Es ist keine einfache Sache, die am besten ist, weil jede Vor- und Nachteile hat. Sie müssen die von mir bereitgestellten Links lesen und Ihre eigene Entscheidung treffen, sie dann testen und herausfinden. Ich habe PDO in früheren Projekten verwendet und es ist eine gute Erweiterung, aber meine Wahl für reine Leistung wäre MySQLi mit der neuen kompilierten MySQLND-Option (wenn PHP 5.3 veröffentlicht wird).


6
Ich wechselte von PDO zu mysqli und reguläre Abfragen wurden genau zweimal schneller ausgeführt.
Serg

5
@serg: Möchten Sie einige Tests veröffentlichen, um dies zu bestätigen? Ich bezweifle ernsthaft, dass ein einfacher Wechsel von PDO zu mysqli Ihnen einen solchen Geschwindigkeitsschub bringen würde.
Stann

23

Allgemeines

  • Versuchen Sie nicht zu optimieren, bevor Sie die reale Last sehen. Sie könnten richtig raten, aber wenn Sie dies nicht tun, haben Sie Ihre Zeit verschwendet.
  • Verwenden Sie jmeter , xdebug oder ein anderes Tool, um die Site zu bewerten .
  • Wenn das Laden ein Problem darstellt, ist wahrscheinlich entweder das Objekt- oder das Daten-Caching beteiligt. Informieren Sie sich daher im Allgemeinen über die Caching-Optionen (Memcached, MySQL-Caching-Optionen).

Code

  • Profilieren Sie Ihren Code so, dass Sie wissen, wo der Engpass liegt und ob er sich im Code oder in der Datenbank befindet

Datenbanken

  • Verwenden Sie MYSQLi, wenn die Portabilität auf andere Datenbanken nicht unbedingt erforderlich ist, andernfalls PDO
  • Wenn Benchmarks ergeben, dass die Datenbank das Problem ist, überprüfen Sie die Abfragen, bevor Sie mit dem Caching beginnen. Verwenden Sie EXPLAIN, um zu sehen, wo Ihre Abfragen langsamer werden.
  • Nachdem die Abfragen optimiert und die Datenbank auf irgendeine Weise zwischengespeichert wurden, möchten Sie möglicherweise mehrere Datenbanken verwenden. Abhängig von den Daten, den Abfragen und der Art des Lese- / Schreibverhaltens kann entweder eine Replikation auf mehrere Server oder ein Sharding (Aufteilung der Daten auf mehrere Datenbanken / Server) angebracht sein.

Caching

  • Es wurde viel über das Zwischenspeichern von Code, Objekten und Daten geschrieben. Suchen Sie nach Artikeln zu APC , Zend Optimizer , Memcached , QuickCache und JPCache . Tun Sie etwas davon, bevor Sie es wirklich brauchen, und Sie werden weniger besorgt darüber sein, nicht optimiert anzufangen.
  • APC und Zend Optimizer sind Opcode-Caches. Sie beschleunigen den PHP-Code, indem sie das erneute Analysieren und Kompilieren von Code vermeiden. Im Allgemeinen einfach zu installieren, es lohnt sich, dies frühzeitig zu tun.
  • Memcached ist ein generischer Cache, mit dem Sie Abfragen, PHP-Funktionen oder -Objekte oder ganze Seiten zwischenspeichern können. Der Code muss speziell für die Verwendung geschrieben werden. Dies kann ein komplizierter Prozess sein, wenn keine zentralen Punkte für die Erstellung, Aktualisierung und Löschung zwischengespeicherter Objekte vorhanden sind.
  • QuickCache und JPCache sind Datei-Caches, ansonsten ähnlich wie Memcached. Das Grundkonzept ist einfach, erfordert aber auch Code und ist mit zentralen Punkten zum Erstellen, Aktualisieren und Löschen einfacher.

Verschiedenes

  • Erwägen Sie alternative Webserver für hohe Auslastung. Server wie lighthttp und nginx können große Datenmengen in viel weniger Speicher als Apache verarbeiten , wenn Sie die Leistung und Flexibilität von Apache opfern können (oder wenn Sie diese Dinge einfach nicht benötigen, was häufig nicht der Fall ist ).
  • Denken Sie daran, dass Hardware heutzutage überraschend billig ist. Achten Sie also darauf, den Aufwand für die Optimierung eines großen Codeblocks im Vergleich zu "Kaufen wir einen Monsterserver" zu kosten.
  • Erwägen Sie, dieser Frage die Tags "MySQL" und "Skalierung" hinzuzufügen

9

APC ist ein absolutes Muss. Dies ist nicht nur ein großartiges Caching-System, sondern der Gewinn aus den automatisch zwischengespeicherten PHP-Dateien ist ein Glücksfall. Was die Idee mit mehreren Datenbanken betrifft, denke ich nicht, dass Sie viel davon haben würden, wenn Sie verschiedene Datenbanken auf demselben Server haben. Es kann Ihnen während der Abfragezeit einen gewissen Geschwindigkeitsgewinn bringen, aber ich bezweifle, dass sich der Aufwand lohnt, den Code für alle drei bereitzustellen und zu warten, während sichergestellt wird, dass sie synchron sind.

Ich empfehle außerdem dringend, Xdebug auszuführen , um Engpässe in Ihrem Programm zu finden. Die Optimierung war für mich ein Kinderspiel.


9

Erstens, wie ich glaube, sagte Knuth: "Vorzeitige Optimierung ist die Wurzel allen Übels". Wenn Sie sich jetzt nicht mit diesen Problemen befassen müssen, konzentrieren Sie sich darauf, etwas zu liefern, das zuerst richtig funktioniert. Davon abgesehen, wenn die Optimierungen nicht warten können.

Versuchen Sie, Ihre Datenbankabfragen zu profilieren, herauszufinden, was langsam ist und was häufig passiert, und entwickeln Sie daraus eine Optimierungsstrategie.

Ich würde Memcached untersuchen, da es das ist, was viele Websites mit höherer Last zum effizienten Zwischenspeichern von Inhalten aller Art verwenden, und die PHP-Objektschnittstelle dazu ist sehr schön.

Das Aufteilen von Datenbanken auf Server und die Verwendung einer Lastausgleichstechnik (z. B. Generieren einer Zufallszahl zwischen 1 und # redundanten Datenbanken mit den erforderlichen Daten - und Verwenden dieser Nummer, um zu bestimmen, mit welchem ​​Datenbankserver eine Verbindung hergestellt werden soll) kann ebenfalls eine hervorragende Möglichkeit zur Erhöhung sein Effizienz.

Diese haben alle in der Vergangenheit für einige Websites mit ziemlich hoher Last ziemlich gut funktioniert. Hoffe das hilft dir den Einstieg :-)


1
RequiredFullQuote: "Wir sollten kleine Wirkungsgrade vergessen, etwa in 97% der Fälle: Vorzeitige Optimierung ist die Wurzel allen Übels"
Alister Bulman

RequiredReallyFullQuote: "Programmierer verschwenden enorm viel Zeit damit, über die Geschwindigkeit unkritischer Teile ihrer Programme nachzudenken oder sich darüber Gedanken zu machen, und diese Effizienzversuche wirken sich tatsächlich stark negativ aus, wenn Debugging und Wartung in Betracht gezogen werden. Wir sollten kleine Effizienzvorteile vergessen." Sagen wir ungefähr 97% der Zeit: Vorzeitige Optimierung ist die Wurzel allen Übels. Dennoch sollten wir unsere Chancen in diesen kritischen 3% nicht verpassen. "
CHao

6

Das Profilieren Ihrer App mit etwas wie Xdebug (wie empfohlen von tj9991) wird definitiv ein Muss sein. Es macht nicht viel Sinn, Dinge blind zu optimieren. Xdebug hilft Ihnen dabei, die tatsächlichen Engpässe in Ihrem Code zu finden, sodass Sie Ihre Optimierungszeit mit Bedacht verbringen und Codestücke reparieren können, die tatsächlich zu Verlangsamungen führen.

Wenn Sie Apache verwenden, ist Siege ein weiteres Dienstprogramm, das beim Testen helfen kann . Es hilft Ihnen, vorauszusehen, wie Ihr Server und Ihre Anwendung auf hohe Lasten reagieren, indem Sie sie wirklich auf Herz und Nieren prüfen.

Jede Art von Opcode-Cache für PHP (wie APC oder einer der vielen anderen) wird ebenfalls sehr hilfreich sein.


6

Ich betreibe eine Website mit 7-8 Millionen Seitenaufrufen pro Monat. Nicht sehr viel, aber genug, dass unser Server die Last spürte. Die von uns gewählte Lösung war einfach: Memcache auf Datenbankebene. Diese Lösung funktioniert gut, wenn das Laden der Datenbank Ihr Hauptproblem ist.

Wir haben Memcache verwendet, um ganze Objekte und die am häufigsten verwendeten Datenbankergebnisse zwischenzuspeichern. Es hat funktioniert, aber es hat auch Fehler verursacht (wir hätten einige davon vermieden, wenn wir vorsichtiger gewesen wären).

Also haben wir unseren Ansatz geändert. Wir haben einen Datenbank-Wrapper erstellt (mit genau den gleichen Methoden wie unsere alte Datenbank, daher war das Wechseln einfach) und haben ihn dann in Unterklassen unterteilt, um zwischengespeicherte Datenbankzugriffsmethoden bereitzustellen.

Jetzt müssen Sie nur noch entscheiden, ob eine Abfrage zwischengespeicherte (und möglicherweise veraltete) Ergebnisse verwenden kann oder nicht. Die meisten von den Benutzern ausgeführten Abfragen werden jetzt direkt aus Memcache abgerufen. Ausnahmen sind Aktualisierungen und Einfügungen, die für die Hauptwebsite nur aufgrund der Protokollierung erfolgen. Diese recht einfache Maßnahme reduzierte unsere Serverlast um etwa 80%.


6

Für das, was es wert ist, ist Caching in PHP SCHMUTZIG EINFACH, auch ohne ein Erweiterungs- / Hilfspaket wie memcached.

Sie müssen lediglich einen Ausgabepuffer mit erstellen ob_start().

Erstellen Sie eine globale Cache-Funktion. Rufen Sie an ob_start, übergeben Sie die Funktion als Rückruf. Suchen Sie in der Funktion nach einer zwischengespeicherten Version der Seite. Wenn es existiert, dienen Sie es und beenden Sie.

Wenn es nicht vorhanden ist, wird das Skript weiter verarbeitet. Wenn es das passende ob_end () erreicht, ruft es die von Ihnen angegebene Funktion auf. Zu diesem Zeitpunkt erhalten Sie nur den Inhalt des Ausgabepuffers, legen ihn in einer Datei ab, speichern die Datei und beenden sie.

Fügen Sie eine Ablauf- / Speicherbereinigung hinzu.

Und viele Leute wissen nicht, dass Sie nisten ob_start()/ ob_end()rufen können. Wenn Sie also bereits einen Ausgabepuffer verwenden, um beispielsweise Werbung zu analysieren oder Syntaxhervorhebungen vorzunehmen oder was auch immer, können Sie einfach einen weiteren ob_start/ob_endAufruf verschachteln .


+1, weil es nach einer interessanten Idee aussieht. Ich weiß nicht, wie gut es in
Bezug auf die

+1, weil dies eine interessante Idee ist. Diese Rückrufe könnten meine Caching-Klasse für mich anrufen!
Xeoncross

5

Vielen Dank für den Rat zu den Caching-Erweiterungen von PHP. Können Sie die Gründe für die Verwendung untereinander erläutern? Ich habe großartige Dinge über Memcached durch IRC gehört, aber noch nie von APC gehört - wie sind Ihre Meinungen dazu? Ich gehe davon aus, dass die Verwendung mehrerer Caching-Systeme ziemlich kontraproduktiv ist.

Tatsächlich verwenden viele APC und memcached zusammen ...


4

Es sieht so aus, als hätte ich mich geirrt . MySQLi wird noch entwickelt. Dem Artikel zufolge wird PDO_MySQL jetzt vom MySQL-Team bereitgestellt. Aus dem Artikel:

Die MySQL Improved Extension - mysqli - ist das Flaggschiff. Es unterstützt alle Funktionen des MySQL-Servers, einschließlich Zeichensätze, vorbereitete Anweisungen und gespeicherte Prozeduren. Der Treiber bietet eine Hybrid-API: Sie können je nach Wunsch einen prozeduralen oder objektorientierten Programmierstil verwenden. mysqli kommt mit PHP 5 und höher. Beachten Sie, dass das Ende der Lebensdauer von PHP 4 der 08.08.2008 ist.

Die PHP-Datenobjekte (PDO) sind eine Abstraktionsschicht für den Datenbankzugriff. Mit PDO können Sie dieselben API-Aufrufe für verschiedene Datenbanken verwenden. PDO bietet keinen Grad an SQL-Abstraktion. PDO_MYSQL ist ein MySQL-Treiber für PDO. PDO_MYSQL wird mit PHP 5 geliefert. Ab PHP 5.3 tragen MySQL-Entwickler aktiv dazu bei. Der PDO-Vorteil einer einheitlichen API besteht darin, dass MySQL-spezifische Funktionen, z. B. mehrere Anweisungen, über die einheitliche API nicht vollständig unterstützt werden.

Bitte hören Sie auf, den ersten jemals veröffentlichten MySQL-Treiber für PHP zu verwenden: ext / mysql. Seit der Einführung der MySQL Improved Extension - mysqli - im Jahr 2004 mit PHP 5 gibt es keinen Grund mehr, den ältesten Treiber zu verwenden. ext / mysql unterstützt keine Zeichensätze, vorbereiteten Anweisungen und gespeicherten Prozeduren. Es ist auf den Funktionsumfang von MySQL 4.0 beschränkt. Beachten Sie, dass die erweiterte Unterstützung für MySQL 4.0 am 31.12.2008 endet. Beschränken Sie sich nicht auf die Funktionen einer solchen alten Software! Upgrade auf mysqli, siehe auch Converting_to_MySQLi. MySQL befindet sich aus unserer Sicht nur im Wartungsmodus.

Mir scheint, der Artikel ist voreingenommen gegenüber MySQLi. Ich bin wohl voreingenommen gegenüber PDO. Ich mag PDO über MySQLi. Es ist direkt für mich. Die API ist viel näher an anderen Sprachen, in denen ich programmiert habe. OO-Datenbankschnittstellen scheinen besser zu funktionieren.

Ich habe keine spezifischen MySQL-Funktionen gefunden, die nicht über PDO verfügbar waren. Ich wäre überrascht, wenn ich es jemals tun würde.


3

PDO ist auch sehr langsam und seine API ist ziemlich kompliziert. Niemand, der bei Verstand ist, sollte es verwenden, wenn die Portabilität kein Problem darstellt. Und seien wir ehrlich, in 99% aller Webapps ist dies nicht der Fall. Sie bleiben einfach bei MySQL oder PostrgreSQL oder was auch immer Sie arbeiten.

Was die PHP-Frage betrifft und was zu berücksichtigen ist. Ich denke, vorzeitige Optimierung ist die Wurzel allen Übels. ;) Lassen Sie Ihre Anwendung zuerst fertig werden, versuchen Sie, sie beim Programmieren sauber zu halten, führen Sie eine kleine Dokumentation durch und schreiben Sie Komponententests. Mit all dem haben Sie zu gegebener Zeit keine Probleme, Code neu zu gestalten. Aber zuerst möchten Sie fertig sein und es herausdrücken, um zu sehen, wie die Leute darauf reagieren.


2

Sicher gU ist schön, aber es hat schon einige Kontroversen über seine Leistung im Vergleich zu mysql und mysqli, obwohl es nun behoben zu sein scheint.

Sie sollten pdo verwenden, wenn Sie sich Portabilität vorstellen, aber wenn nicht, sollte mysqli der richtige Weg sein. Es verfügt über eine OO-Schnittstelle, vorbereitete Anweisungen und das meiste, was pdo bietet (außer Portabilität).

Wenn Leistung wirklich benötigt wird, bereiten Sie sich auf den (nativen MySQL-) MysqLnd- Treiber in PHP 5.3 vor, der viel enger in PHP integriert ist, eine bessere Leistung und eine verbesserte Speichernutzung bietet (und Statistiken zur Leistungsoptimierung).

Memcache ist nett, wenn Sie Cluster-Server haben (und YouTube-ähnliche Last), aber ich würde auch zuerst APC ausprobieren .


2

Es wurden bereits viele gute Antworten gegeben, aber ich möchte Sie auf einen alternativen Opcode-Cache namens XCache verweisen . Es wird von einem leichten Mitwirkenden erstellt.

Wenn Sie in Zukunft möglicherweise einen Lastausgleich für Ihren Datenbankserver benötigen, kann MySQL Proxy Ihnen dabei helfen.

Beide Tools sollten sich problemlos in eine vorhandene Anwendung einbinden lassen, sodass diese Optimierung bei Bedarf ohne großen Aufwand durchgeführt werden kann.


2

Die erste Frage ist, wie groß Sie wirklich erwarten? Und wie viel planen Sie in Ihre Infrastruktur zu investieren? Da Sie das Bedürfnis haben, die Frage hier zu stellen, gehe ich davon aus, dass Sie mit einem begrenzten Budget klein anfangen werden.

Die Leistung ist irrelevant, wenn die Website nicht verfügbar ist. Und für die Verfügbarkeit benötigen Sie eine horizontale Skalierung. Das Minimum, mit dem Sie vernünftigerweise davonkommen können, sind 2 Server, auf denen Apache, PHP und MySQL ausgeführt werden. Richten Sie ein DBMS als Slave für das andere ein. Führen Sie alle Schreibvorgänge auf dem Master und alle Lesevorgänge in der lokalen Datenbank durch (was auch immer das ist) - es sei denn, Sie müssen aus irgendeinem Grund die gerade gelesenen Daten zurücklesen (verwenden Sie den Master). Stellen Sie sicher, dass die Maschinen vorhanden sind, um den Slave automatisch zu befördern und den Master zu zäunen. Verwenden Sie Round-Robin-DNS für die Webserver-Adressen, um mehr Affinität für den Slave-Knoten zu erhalten.

Die Partitionierung Ihrer Daten auf verschiedene Datenbankknoten zu diesem Zeitpunkt ist eine sehr schlechte Idee. Sie sollten jedoch in Betracht ziehen, sie auf verschiedene Datenbanken auf demselben Server aufzuteilen (was die Partitionierung zwischen Knoten erleichtert, wenn Sie Facebook überholen).

Stellen Sie sicher, dass Sie über die Tools zur Überwachung und Datenanalyse verfügen, mit denen Sie die Leistung Ihrer Websites messen und Engpässe identifizieren können. Die meisten Leistungsprobleme können behoben werden, indem besseres SQL geschrieben / das Datenbankschema repariert wird.

Es ist eine blöde Idee, den Vorlagencache in der Datenbank zu belassen. Die Datenbank sollte ein zentrales gemeinsames Repository für strukturierte Daten sein. Behalten Sie Ihren Vorlagen-Cache im lokalen Dateisystem Ihrer Webserver - er ist schneller verfügbar und verlangsamt Ihren Datenbankzugriff nicht.

Verwenden Sie einen Op-Code-Cache.

Verbringen Sie viel Zeit damit, Ihre Website und ihre Protokolle zu studieren, um zu verstehen, warum sie so langsam verläuft.

Schieben Sie so viel Caching wie möglich auf den Client.

Verwenden Sie mod_gzip, um alles zu komprimieren, was Sie können.

C.


2

Mein erster Rat ist, über dieses Problem nachzudenken und es bei der Gestaltung der Website zu berücksichtigen, aber nicht über Bord zu gehen . Es ist oft schwierig, den Erfolg einer neuen Website vorherzusagen, und ich werde Ihre Zeit besser damit verbringen, früh fertig zu werden und sie später zu optimieren.

Im Allgemeinen ist Simple schnell . Vorlagen verlangsamen Sie. Datenbanken verlangsamen Sie. Komplexe Bibliotheken verlangsamen Sie. Überlagern Sie Vorlagen, indem Sie sie aus Datenbanken abrufen und in einer komplexen Bibliothek analysieren -> die Zeitverzögerungen multiplizieren sich miteinander.

Sobald Sie die Basis-Site eingerichtet haben, führen Sie Tests durch, um zu zeigen, wo Sie Ihre Anstrengungen unternehmen müssen. Es ist schwer zu erkennen, wohin man zielen soll. Um die Dinge zu beschleunigen, müssen Sie häufig die Komplexität des Codes entschlüsseln. Dies macht ihn größer und schwieriger zu warten, sodass Sie ihn nur bei Bedarf ausführen möchten.

Nach meiner Erfahrung war der Aufbau der Datenbankverbindung relativ teuer. Wenn Sie damit durchkommen können, stellen Sie auf den am häufigsten frequentierten Seiten wie der Startseite der Website keine Verbindung zur Datenbank für allgemeine Besucher her. Das Erstellen mehrerer Datenbankverbindungen ist Wahnsinn mit sehr geringem Nutzen.


1

@ Gary

Verwenden Sie MySQLi nicht - PDO ist die 'moderne' OO-Datenbankzugriffsschicht. Die wichtigste Funktion sind Platzhalter in Ihren Abfragen. Es ist intelligent genug, um serverseitige Vorbereitungen und andere Optimierungen auch für Sie zu verwenden.

Ich beschäftige mich momentan mit PDO und es sieht so aus, als ob Sie Recht haben - aber ich weiß, dass MySQL die MySQLd-Erweiterung für PHP entwickelt - ich denke, dass MySQL oder MySQLi erfolgreich sein werden - was denken Sie darüber?


@ Ryan , Eric , tj9991

Vielen Dank für den Rat zu den Caching-Erweiterungen von PHP. Können Sie die Gründe für die Verwendung untereinander erläutern? Ich habe großartige Dinge über Memcached durch IRC gehört, aber noch nie von APC gehört - wie sind Ihre Meinungen dazu? Ich gehe davon aus, dass die Verwendung mehrerer Caching-Systeme ziemlich kontraproduktiv ist.

Ich werde auf jeden Fall einige Profiling-Tester aussortieren - vielen Dank für Ihre Empfehlungen dazu.


1

Ich sehe mich nicht in absehbarer Zeit von MySQL wechseln - daher brauche ich wohl nicht die Abstraktionsfunktionen von PDO. Vielen Dank für diese Artikel, DavidM, sie haben mir sehr geholfen.


1

Schauen Sie sich mod_cache an , einen Ausgabecache für den Apache-Webserver, ähnlich dem Ausgabecaching in ASP.NET.

Ja, ich kann sehen, dass es noch experimentell ist, aber es wird eines Tages endgültig sein.


1

Ich kann nicht glauben, dass dies bereits niemand erwähnt hat: Modularisierung und Abstraktion. Wenn Sie glauben, dass Ihre Site auf viele Maschinen anwachsen muss , müssen Sie sie so gestalten, dass sie es kann! Das bedeutet, dass dumme Dinge wie nicht davon ausgehen, dass sich die Datenbank auf localhost befindet. Es bedeutet auch Dinge, die zuerst stören werden, wie das Schreiben einer Datenbankabstraktionsschicht (wie PDO, aber viel viel leichter, weil es nur das tut, wofür Sie es brauchen).

Und es bedeutet Dinge wie die Arbeit mit einem Framework. Sie benötigen Ebenen für Ihren Code, damit Sie später Leistung erzielen können, indem Sie die Datenabstraktionsschicht umgestalten, indem Sie ihr beispielsweise beibringen, dass sich einige Objekte in einer anderen Datenbank befinden - und der Code muss es nicht wissen oder sich darum kümmern .

Achten Sie schließlich auf speicherintensive Vorgänge, z. B. unnötiges Kopieren von Zeichenfolgen. Wenn Sie die Speichernutzung von PHP niedrig halten können, wird Ihr Webserver mehr Leistung bringen. Dies wird skaliert, wenn Sie sich für eine Lösung mit Lastenausgleich entscheiden.


1

Wenn Sie mit großen Datenmengen arbeiten und das Caching diese nicht schneidet, schauen Sie sich Sphinx an. Wir haben großartige Ergebnisse mit der Verwendung von SphinxSearch erzielt, nicht nur für eine bessere Textsuche, sondern auch als Ersatz für das Abrufen von Daten für MySQL beim Umgang mit größeren Tabellen. Wenn Sie SphinxSE (MySQL-Plugin) verwenden, hat es unsere Leistungssteigerungen durch mehrmaliges Zwischenspeichern übertroffen, und die Implementierung von Anwendungen ist eine Sünde.


1

Die Punkte, die über den Cache gemacht werden, sind genau richtig; Dies ist der am wenigsten komplizierte und wichtigste Teil beim Erstellen einer effizienten Anwendung. Ich möchte hinzufügen, dass memcached zwar großartig ist, APC jedoch etwa fünfmal schneller ist, wenn Ihre Anwendung auf einem einzelnen Server ausgeführt wird.

Der Beitrag "Cache-Leistungsvergleich" im MySQL-Leistungsblog enthält einige interessante Benchmarks zu diesem Thema: http://www.mysqlperformanceblog.com/2006/08/09/cache-performance-comparison/ .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.