Optimierung von Kohana-basierten Websites auf Geschwindigkeit und Skalierbarkeit


80

Eine Site, die ich mit Kohana erstellt habe, war gestern mit einem enormen Verkehrsaufkommen überfüllt, was mich veranlasste, einen Schritt zurückzutreten und einen Teil des Designs zu bewerten. Ich bin gespannt, welche Standardtechniken zur Optimierung von Kohana-basierten Anwendungen verwendet werden.

Ich interessiere mich auch für Benchmarking. Muss ich für jede Controller-Methode einrichten Benchmark::start()und Benchmark::stop()ausführen, um die Ausführungszeiten für alle Seiten anzuzeigen, oder kann ich Benchmarking global und schnell anwenden?

Ich werde die Cache-Bibliothek in der kommenden Zeit mehr nutzen, bin aber offen für weitere Vorschläge, da ich sicher bin, dass ich eine Menge tun kann, die mir im Moment einfach nicht bewusst ist.


Haben Sie den Build in Kohana Profiler ausprobiert, um Informationen zur Anwendung zu erhalten? Es ist ziemlich gut
Yasen Zhelev

Antworten:


211

Was ich in dieser Antwort sagen werde, ist nicht spezifisch für Kohana und kann wahrscheinlich für viele PHP-Projekte gelten.

Hier sind einige Punkte, die mir einfallen, wenn ich über Leistung, Skalierbarkeit, PHP usw. spreche.
Ich habe viele dieser Ideen bei der Arbeit an mehreren Projekten verwendet - und sie haben geholfen. also könnten sie wahrscheinlich auch hier helfen.


Erstens müssen bei Performances viele Aspekte / Fragen berücksichtigt werden :

  • Konfiguration des Servers (sowohl Apache, PHP, MySQL, andere mögliche Daemons als auch System) ; Sie könnten darüber auf mehr Hilfe bekommen ServerFault , nehme ich an,
  • PHP-Code,
  • Datenbankabfragen,
  • Verwenden oder nicht Ihren Webserver?
  • Können Sie irgendeine Art von Caching-Mechanismus verwenden? Oder benötigen Sie immer mehr als aktuelle Daten auf der Website?


Verwenden eines Reverse-Proxys

Das erste, was wirklich nützlich sein könnte, ist die Verwendung eines Reverse-Proxys wie Lack vor Ihrem Webserver: Lassen Sie so viele Dinge wie möglich zwischenspeichern , also nur Anfragen, die wirklich PHP / MySQL-Berechnungen benötigen (und natürlich einige andere Anfragen, wenn sie sich nicht im Cache des Proxys befinden , gelangen zu Apache / PHP / MySQL.

  • Zunächst müssen Ihr CSS / Javascript / Ihre Bilder - also alles, was statisch ist - wahrscheinlich nicht immer von Apache bereitgestellt werden
    • Sie können also alle diese über den Reverse-Proxy-Cache verfügen.
    • Das Bereitstellen dieser statischen Dateien ist für Apache keine große Sache, aber je weniger es für diese funktionieren muss, desto mehr kann es mit PHP tun.
    • Denken Sie daran: Apache kann nur eine begrenzte Anzahl von Anforderungen gleichzeitig bedienen.
  • Lassen Sie dann den Reverse-Proxy so viele PHP-Seiten wie möglich aus dem Cache bereitstellen: Es gibt wahrscheinlich einige Seiten, die sich nicht so oft ändern und aus dem Cache bereitgestellt werden könnten. Anstatt einen PHP-basierten Cache zu verwenden, können Sie diese von einem anderen, leichteren Server bedienen lassen (und sie von Zeit zu Zeit vom PHP-Server abrufen, damit sie immer fast auf dem neuesten Stand sind) .
    • Wenn Sie beispielsweise einige RSS-Feeds haben (wir neigen im Allgemeinen dazu, diejenigen zu vergessen, wenn wir versuchen, die Leistung zu optimieren) , die sehr häufig angefordert werden, können Sie Hunderte / Tausende von Anfragen an Apache + PHP sparen , wenn Sie diese für ein paar Minuten im Cache haben + MySQL!
    • Das Gleiche gilt für die am häufigsten besuchten Seiten Ihrer Website. Wenn sie sich mindestens einige Minuten lang nicht ändern (Beispiel: Homepage?) , Müssen Sie nicht die CPU verschwenden, um sie jedes Mal neu zu generieren, wenn ein Benutzer sie anfordert.
  • Vielleicht gibt es einen Unterschied zwischen Seiten, die für anonyme Benutzer bereitgestellt werden (dieselbe Seite für alle anonymen Benutzer) und Seiten, die für identifizierte Benutzer bereitgestellt werden (z. B. "Hallo Herr X, Sie haben neue Nachrichten") ?
    • In diesem Fall können Sie den Reverse-Proxy wahrscheinlich so konfigurieren, dass die Seite, die für anonyme Benutzer bereitgestellt wird, zwischengespeichert wird (basierend auf einem Cookie, wie z. B. dem Sitzungscookie).
    • Dies bedeutet, dass Apache + PHP weniger zu tun hat: nur identifizierte Benutzer - was möglicherweise nur ein kleiner Teil Ihrer Benutzer ist.

Informationen zur Verwendung eines Reverse-Proxys als Cache für eine PHP-Anwendung finden Sie beispielsweise unter Benchmark-Ergebnisse. 400% -700% Steigerung der Serverfunktionen mit APC und Squid-Cache .
(Ja, sie verwenden Squid, und ich habe über Lack gesprochen - das ist nur eine weitere Möglichkeit ^^ Lack ist neuer, aber eher dem Caching gewidmet.)

Wenn Sie das gut genug machen und es schaffen, nicht mehr zu viele Seiten immer wieder neu zu generieren, müssen Sie vielleicht nicht einmal Ihren Code optimieren ;-)
Zumindest vielleicht nicht in Eile ... Und es ist immer besser, Optimierungen durchzuführen, wenn Sie nicht zu stark unter Druck stehen ...


Als Nebenbemerkung: Sie sagen im OP:

Eine Site, die ich mit Kohana gebaut habe, war gestern mit einem enormen Verkehrsaufkommen überfüllt.

Dies ist die Art von plötzlicher Situation, in der ein Reverse-Proxy buchstäblich den Tag retten kann , wenn Ihre Website damit fertig wird, nicht sekundengenau auf dem neuesten Stand zu sein:

  • Installieren Sie es, konfigurieren Sie es, lassen Sie es immer - jeden normalen Tag - laufen:
    • Konfigurieren Sie es so, dass PHP-Seiten nicht im Cache bleiben. oder nur für kurze Zeit; Auf diese Weise werden immer aktuelle Daten angezeigt
  • Und an dem Tag, an dem Sie einen Slashdot- oder Digg-Effekt erzielen:
    • Konfigurieren Sie den Reverse-Proxy so, dass PHP-Seiten im Cache bleiben. oder für einen längeren Zeitraum; Vielleicht sind Ihre Seiten nicht im Sekundentakt auf dem neuesten Stand, aber Ihre Website kann den Digg-Effekt überleben!

Wie kann ich erkennen und überleben, dass ich „Slashdotted“ bin? könnte eine interessante Lektüre sein.


Auf der PHP-Seite der Dinge:

Zunächst einmal: Verwenden Sie eine aktuelle Version von PHP ? Mit neuen Versionen wird die Geschwindigkeit regelmäßig verbessert ;-)
Schauen Sie sich zum Beispiel Benchmark of PHP Branches 3.0 bis 5.3-CVS an .

Beachten Sie, dass die Leistung ein guter Grund ist, PHP 5.3 zu verwenden ( ich habe einige Benchmarks (auf Französisch) erstellt und die Ergebnisse sind großartig) ...
Ein weiterer guter Grund ist natürlich, dass PHP 5.2 das Ende seiner Lebensdauer erreicht hat und wird nicht mehr gewartet!

Verwenden Sie einen Opcode-Cache?

  • Ich denke an APC - Alternative PHP Cache , zum Beispiel ( PECL , manuell ) , die die Lösung , die ich gesehen habe , die am häufigsten verwenden - und das auf allen Servern , auf die verwendet wird , die ich gearbeitet habe.
  • In einigen Fällen kann die CPU-Auslastung eines Servers erheblich gesenkt werden (ich habe festgestellt, dass die CPU-Auslastung auf einigen Servern von 80% auf 40% steigt, indem nur APC installiert und die Opcode-Cache-Funktionalität aktiviert wird!).
  • Grundsätzlich erfolgt die Ausführung eines PHP-Skripts in zwei Schritten:
    • Kompilierung des PHP-Quellcodes zu Opcodes (eine Art Äquivalent zum JAVA-Bytecode)
    • Ausführung dieser Opcodes
    • APC speichert diese im Speicher, sodass bei jeder Ausführung eines PHP-Skripts / jeder PHP-Datei weniger Arbeit zu erledigen ist: Rufen Sie nur die Opcodes aus dem RAM ab und führen Sie sie aus.
  • Möglicherweise müssen Sie sich übrigens die Konfigurationsoptionen von APC ansehen
    • Es gibt einige davon, und einige können für Sie einen großen Einfluss auf Geschwindigkeit, CPU-Auslastung und Benutzerfreundlichkeit haben
    • Zum Beispiel kann das Deaktivieren [apc.stat](https://php.net/manual/en/apc.configuration.php#ini.apc.stat)für die Systemlast gut sein. Dies bedeutet jedoch, dass Änderungen an PHP-Dateien nur berücksichtigt werden, wenn Sie den gesamten Opcode-Cache leeren. Weitere Informationen hierzu finden Sie beispielsweise unter To stat () oder Not To stat ().


Cache für Daten verwenden

So viel wie möglich ist es besser, nicht immer wieder dasselbe zu tun .

Die Hauptsache, über die ich nachdenke, sind natürlich SQL-Abfragen: Viele Ihrer Seiten führen wahrscheinlich dieselben Abfragen aus, und die Ergebnisse einiger dieser Abfragen sind wahrscheinlich fast immer dieselben ... Was viele "nutzlose" Abfragen bedeutet gemacht an die Datenbank, die Zeit damit verbringen muss, immer wieder dieselben Daten zu liefern.
Dies gilt natürlich auch für andere Dinge wie Webdienstaufrufe, das Abrufen von Informationen von anderen Websites, umfangreiche Berechnungen, ...

Es könnte für Sie sehr interessant sein, Folgendes zu identifizieren:

  • Welche Abfragen werden häufig ausgeführt und geben immer die gleichen Daten zurück
  • Welche anderen (schweren) Berechnungen werden viel Zeit durchgeführt, wobei immer das gleiche Ergebnis zurückgegeben wird

Speichern Sie diese Daten / Ergebnisse in einer Art Cache, damit sie leichter abgerufen werden können - schneller - und Sie nicht für "nichts" zu Ihrem SQL Server gehen müssen.

Große Caching-Mechanismen sind zum Beispiel:

  • APC : Zusätzlich zu dem Opcode-Cache, über den ich zuvor gesprochen habe, können Sie Daten im Speicher speichern.
  • Und / oder Memcached ( siehe auch ) , was sehr nützlich ist , wenn Sie buchstäblich haben viele von Daten und / oder mehrere Server mit , wie es verteilt wird.
  • Natürlich können Sie über Dateien nachdenken. und wahrscheinlich viele andere Ideen.

Ich bin mir ziemlich sicher, dass Ihr Framework einige Cache-bezogene Dinge enthält. das weißt du wahrscheinlich schon, wie du gesagt hast "Ich werde die Cache-Bibliothek in der kommenden Zeit mehr nutzen" im OP ;-)


Profilerstellung

Nun wäre es eine gute Sache, die Xdebug- Erweiterung zu verwenden , um Ihre Anwendung zu profilieren : Sie ermöglicht es oft, ein paar Schwachstellen ganz einfach zu finden - zumindest, wenn es eine Funktion gibt, die viel Zeit in Anspruch nimmt.

Bei ordnungsgemäßer Konfiguration werden Profildateien generiert, die mit einigen Grafikwerkzeugen analysiert werden können, z.

  • KCachegrind : mein Favorit, funktioniert aber nur unter Linux / KDE
  • Wincachegrind für Fenster; Leider macht es ein bisschen weniger als KCacheGrind - normalerweise werden keine Callgraphs angezeigt.
  • Webgrind, das auf einem PHP-Webserver ausgeführt wird, funktioniert also überall - hat aber wahrscheinlich weniger Funktionen.

Zum Beispiel hier ein paar Screenshots von KCacheGrind:

KCacheGrind: Hauptbildschirm
(Quelle: pascal-martin.fr ) (Quelle: pascal-martin.fr )
KCacheGrind: Callgraph als Bild exportiert

(Übrigens, der auf dem zweiten Screenshot dargestellte Callgraph kann normalerweise weder WinCacheGrind noch Webgrind, wenn ich mich richtig erinnere ^^)


(Danke @Mikushi für den Kommentar) Eine andere Möglichkeit, die ich nicht viel genutzt habe, ist die xhprof- Erweiterung: Sie hilft auch bei der Profilerstellung, kann Callgraphs generieren - ist aber leichter als Xdebug, was bedeutet, dass Sie sie installieren können sollten ein Produktionsserver.

Sie sollten es auch außerhalb von XHGui verwenden können , um Daten zu visualisieren.


Auf der SQL-Seite der Dinge:

Nachdem wir ein wenig über PHP gesprochen haben, beachten Sie, dass es mehr als möglich ist, dass Ihr Engpass nicht die PHP-Seite der Dinge ist , sondern die Datenbank ...

Mindestens zwei oder drei Dinge hier:

  • Sie sollten bestimmen:
    • Was sind die häufigsten Abfragen, die Ihre Anwendung ausführt?
    • Ob diese optimiert werden ( hauptsächlich mit den richtigen Indizes ?) , Verwenden Sie die EXPLAINAnweisung, wenn Sie MySQL verwenden
    • ob Sie einige dieser Abfragen zwischenspeichern könnten (siehe, was ich zuvor gesagt habe)
  • Ist Ihr MySQL gut konfiguriert? Ich weiß nicht viel darüber, aber es gibt einige Konfigurationsoptionen, die Auswirkungen haben könnten.

Dennoch sind die beiden wichtigsten Dinge:

  • Gehen Sie nicht in die Datenbank, wenn Sie nicht müssen: so viel wie möglich zwischenspeichern !
  • Wenn Sie zur Datenbank gehen müssen, verwenden Sie effiziente Abfragen: Verwenden Sie Indizes; und Profil!


Und was nun?

Wenn Sie noch lesen, was könnte noch optimiert werden?

Nun, es gibt noch Raum für Verbesserungen ... Einige architekturorientierte Ideen könnten sein:

  • Wechseln Sie zu einer n-Tier-Architektur:
    • Stellen Sie MySQL auf einen anderen Server (2-Tier: einer für PHP; der andere für MySQL)
    • Verwenden Sie mehrere PHP-Server (und gleichen Sie die Benutzer zwischen diesen aus)
    • Verwenden Sie für statische Dateien einen anderen Computer mit einem leichteren Webserver wie:
    • Verwenden Sie mehrere Server für MySQL, mehrere Server für PHP und mehrere Reverse-Proxys davor
    • Natürlich: installieren Memcached - Daemons auf welchem Server eine beliebige Menge an freiem RAM hat, und sie in den Cache verwenden , wie viel Sie können / Sinn macht.
  • Verwenden Sie etwas "effizienter" als Apache?
    • Ich höre immer öfter von Nginx , was großartig sein soll, wenn es um PHP und hochvolumige Websites geht. Ich habe es selbst nie benutzt, aber vielleicht finden Sie einige interessante Artikel darüber im Internet.

Nun, vielleicht sind einige dieser Ideen in Ihrer Situation etwas übertrieben ^^
Aber trotzdem ... Warum studieren Sie sie nicht ein bisschen, nur für den Fall? ;-);


Und was ist mit Kohana?

Ihre erste Frage betraf die Optimierung einer Anwendung, die Kohana verwendet ... Nun, ich habe einige Ideen veröffentlicht, die für jede PHP-Anwendung gelten ... Das heißt, sie gelten auch für Kohana ;-)
(Auch wenn sie nicht spezifisch dafür sind ^^)

Ich sagte: Cache verwenden; Kohana scheint einige Caching-Sachen zu unterstützen (Du hast selbst darüber gesprochen, also nichts Neues hier ...)
Wenn es etwas gibt, das schnell erledigt werden kann, probiere es aus ;-)

Ich sagte auch, Sie sollten nichts tun, was nicht notwendig ist. Gibt es in Kohana standardmäßig etwas, das Sie nicht benötigen?
Beim Surfen im Internet scheint es zumindest etwas mit XSS-Filterung zu tun zu haben. brauchst du das?

Dennoch sind hier einige Links, die nützlich sein könnten:


Fazit?

Und zum Schluss ein einfacher Gedanke:

  • Wie viel kostet es Ihr Unternehmen, Ihnen 5 Tage zu zahlen? - wenn man bedenkt, dass es eine angemessene Zeit ist, einige großartige Optimierungen vorzunehmen
  • Wie viel kostet es Ihr Unternehmen, einen zweiten Server zu kaufen (zu bezahlen?) Und dessen Wartung?
  • Was ist, wenn Sie größer skalieren müssen?
    • Wie viel kostet es, 10 Tage zu verbringen? Mehr? Optimieren Sie jeden möglichen Teil Ihrer Anwendung?
    • Und wie viel für ein paar weitere Server?

Ich sage nicht, dass Sie nicht optimieren sollten: Sie sollten definitiv!
Aber entscheiden Sie sich für "schnelle" Optimierungen, die Ihnen zuerst große Vorteile bringen : Wenn Sie einen Opcode-Cache verwenden, können Sie die CPU-Auslastung Ihres Servers um 10 bis 50 Prozent senken ... Die Einrichtung dauert nur ein paar Minuten. ) Auf der anderen Seite 3 Tage für 2 Prozent verbringen ...

Übrigens: Bevor Sie etwas unternehmen: Setzen Sie einige Überwachungsfunktionen ein , damit Sie wissen, welche Verbesserungen vorgenommen wurden und wie!
Ohne Überwachung haben Sie keine Ahnung, was Sie getan haben ... Nicht einmal, ob es sich um eine echte Optimierung handelt oder nicht!

Zum Beispiel könnten Sie so etwas wie RRDtool + Kakteen verwenden .
Und es ist immer großartig, deinem Chef ein paar schöne Grafiken mit einem CPU-Lastverlust von 40% zu zeigen ;-)


Wie auch immer, und um wirklich zu schließen: Viel Spaß!
(Ja, das Optimieren macht Spaß!)
(Ergh, ich hätte nicht gedacht, dass ich so viel schreiben würde ... Ich hoffe, zumindest einige Teile davon sind nützlich ... Und ich sollte mich an diese Antwort erinnern: könnte zu anderen Zeiten nützlich sein. ..)


Das Hinzufügen neuer Server ist möglicherweise billiger als das 5-tägige Arbeiten eines Entwicklers. Vergessen Sie jedoch nicht, dass Ihre Software möglicherweise nicht ordnungsgemäß funktioniert, wenn sie von mehreren Servern ausgeführt wird (möglicherweise müssen Sie Dateien auf mehreren Servern freigeben - NFS kann schmerzhaft sein Wenn Sie Sitzungen verwenden, verschieben Sie diese besser in die Datenbank usw.). und das an sich erfordert, dass der Entwickler auch an Dingen arbeitet.
NSSec

16
Tolle Erklärung! Haben Sie einen Blog, den ich abonnieren kann? :-)
Grey Panther

@ dnh828: Ich habe es geschrieben in der Hoffnung, es für einige andere Gelegenheiten wiederzuverwenden (ich habe es tatsächlich schon getan) ;; @MathieuK: definitiv wahr (über Sitzungen, obwohl Sie anstelle von DB auch die Verwendung von Memcache in Betracht ziehen könnten) ;; @ Cd-MaN: Danke! Ich habe tatsächlich ein Blog, aber es ist auf Französisch und ich blogge
Pascal MARTIN

Wenn Sie sich XHProf ( pecl.php.net/package/xhprof ) ansehen , finde ich es besser als XDebug, meinen Code zu profilieren, insbesondere auf Produktionsservern, kombiniert mit XHGui ( github.com/preinheimer/xhprof ). Es ist ein echtes Vergnügen arbeiten mit.
Mikushi

Schade, nicht wahr? ;-) ;; Sie können jedoch den Link stackoverflow.com/q/1260134/138475 verwenden , um diese Frage zu teilen, damit mehr Menschen diese Antwort lesen können (genau deshalb habe ich eine so lange Antwort geschrieben: dafür gelesen werden ^^)
Pascal MARTIN


5

Profilcode mit XDebug .

Verwenden Sie viel Caching. Wenn Ihre Seiten relativ statisch sind, ist Reverse Proxy möglicherweise der beste Weg, dies zu tun.


5

Kohana ist sehr schnell einsatzbereit, mit Ausnahme der Verwendung von Datenbankobjekten. Um Zombor zu zitieren: "Sie können die Speichernutzung reduzieren, indem Sie sicherstellen, dass Sie das Datenbank-Ergebnisobjekt anstelle von Ergebnis-Arrays verwenden." Dies macht einen RIESIGEN Leistungsunterschied auf einer Site, die zugeschlagen wird. Es verbraucht nicht nur mehr Speicher, sondern verlangsamt auch die Ausführung von Skripten.

Außerdem müssen Sie Caching verwenden. Ich bevorzuge Memcache und verwende es in meinen Modellen wie folgt:

public function get($e_id)
{
    $event_data = $this->cache->get('event_get_'.$e_id.Kohana::config('config.site_domain'));

    if ($event_data === NULL)
    {
        $this->db_slave
            ->select('e_id,e_name')
            ->from('Events')
            ->where('e_id', $e_id);

        $result = $this->db_slave->get();
        $event_data = ($result->count() ==1)? $result->current() : FALSE;

        $this->cache->set('event_get_'.$e_id.Kohana::config('config.site_domain'), $event_data, NULL, 300); // 5 minutes
    }

    return $event_data;
}

Dies erhöht auch die Leistung erheblich. Die beiden oben genannten Techniken verbesserten die Leistung einer Site um 80%.

Wenn Sie weitere Informationen darüber geben, wo Ihrer Meinung nach der Engpass liegt, könnten wir sicher bessere Ideen geben.

Schauen Sie sich auch yslow (google it) an, um weitere Leistungstipps zu erhalten.


1

Eng verwandt mit Kohana (wahrscheinlich haben Sie dies bereits getan oder nicht):

Im Produktionsmodus:

  1. Aktivieren Sie das interne Caching (dadurch werden nur die Ergebnisse von Kohana :: find_file zwischengespeichert, dies kann jedoch sehr hilfreich sein.
  2. Profiler deaktivieren

Nur meine 2 Cent :)


0

Ich stimme den XDebug- und Caching-Antworten voll und ganz zu. Schauen Sie nicht in die Kohana-Ebene, um sie zu optimieren, bis Sie Ihre größten Geschwindigkeits- und Skalierungsengpässe identifiziert haben.

XDebug teilt Ihnen mit, wo Sie die meiste Zeit verbracht haben, und identifiziert "Hotspots" in Ihrem Code. Bewahren Sie diese Profilinformationen auf, damit Sie Leistungsverbesserungen durchführen und messen können.

Beispielproblem und Lösung: Wenn Sie feststellen, dass Sie jedes Mal teure Objekte aus der Datenbank erstellen, die sich nicht oft ändern, können Sie sie mit memcached oder einem anderen Mechanismus zwischenspeichern. Alle diese Leistungskorrekturen nehmen Zeit in Anspruch und erhöhen die Komplexität Ihres Systems. Achten Sie daher auf Ihre Engpässe, bevor Sie mit der Korrektur beginnen.

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.