Optimieren Sie Apache / PHP / MySQL auf VPS für hohe Belastung


17

Frage zur Optimierung eines Apache / MySQL-Servers auf einem VPS mit 512m RAM. Unter normaler Last läuft alles schnell, keine Verbindungsverzögerung. Wenn wir jedoch unsere verkehrsreichen Tage (über 50.000 Besuche) haben, crawlt die Site und es dauert mindestens 30 Sekunden, bis der Inhalt von Apache zurückkommt.

Die Site läuft auf Expression Engine (CMS) (in PHP), und ich habe die Anleitung zur Optimierung der Schwerlast befolgt. Ich habe einige gegoogelt und mit etwas Glück auf Apache verfolgt, um es dort hin zu bringen, wo es jetzt ist, aber ich muss konstante Antwortzeiten bekommen.

Ich gehe davon aus, dass dies anders ist als die Frage "Optimiere für wenig Arbeitsspeicher", da ich genug RAM habe (für das, was ich versuche). Ich muss nur den Server dazu bringen, unter hoher Last nicht zu ersticken.

Empfehlungen?


1
Nur eine Nachbereitung - auf Lighttpd umgestellt und schon ist der Unterschied erstaunlich, die Last viel besser zu handhaben. Ich bin mir sicher, dass weitere Optimierungen folgen werden, aber das hat sehr geholfen. Und ich benutzte eaccelerator, den ich über APC ausgewählt hatte, seit es gefragt wurde.
Papageien

Antworten:


18

Für PHP gibt es zwei wichtige Dinge, die die Kapazität erhöhen:

  1. Advanced PHP Caching (APC) wie erwähnt. Das verwenden wir bei Yahoo !. Es gibt andere ähnliche Projekte, aber dieses ist Rasmus 'Baby.
  2. FastCGI anstelle von mod_php. Es gibt Debatten zu diesem Thema, da mod_php normalerweise am schnellsten ist. Ich gehe jedoch davon aus, dass Sie einen einzigen Apache-Server haben, der sowohl dynamischen PHP-Inhalt als auch statische Assets (JS, CSS, Flash, Bilder, PDFs usw.) bereitstellt. Die Anforderungen für diese statischen Assets müssen nicht so viel Speicher belegen, aber da PHP ein Modul ist, ist es in jedem Apache-Thread enthalten.

Für Apache:

  1. Verwenden Sie Worker-MPM
  2. Aktivieren Keep - Alive

Sie können auch einen Wechsel von Apache zu Lighttpd oder Nginx in Betracht ziehen . Ich liebe Apache. Ich benutze den Narren aus vielen seiner erweiterten Funktionen. Ich akzeptiere seinen Overhead, weil ich brauche, was es bietet. Für den gemeinsamen LAMP-Stack ist dies mehr als erforderlich und eine Verschwendung von Ressourcen.

Für MySQL:

  1. Ihre Optimierungsbemühungen zahlen sich zehnmal aus, wenn Sie Abfragen analysieren und korrigieren, anstatt Ihre my.cnf-Werte zu optimieren. Ich sage nicht, dass es nicht wichtig ist, Caching, Verbindungen usw. zu korrigieren ... aber für die meisten Menschen sind es nur 9% des Problems.
  2. Aktivieren Sie während der Qualitätssicherung das allgemeine Abfrageprotokoll in Ihrem Staging- / Dev-MySQL, um alle gesendeten Abfragen zu erfassen. (Tun Sie das NICHT auf Ihrem Produktions-MySQL-Server!)
  3. Verwenden Sie EXPLAIN , um die Abfragen zu analysieren. Insbesondere wenn Sie ein Framework mit einem ORM verwenden (das die Datenbank abstrahiert und Sie davon abhält, Ihr eigenes SQL zu schreiben), müssen Sie überflüssige JOINs, SELECTs ohne WHERE-Klausel, ORDER BYs, die "using filesort" hervorrufen, und Abfragen bereinigen die keine Indizes verwenden.
  4. Wenn Sie MySQL 5.1 verwenden , nutzen Sie den Abfrageprofiler .

Weitere in Betracht zu ziehende Tools sind mk-visual-explain

Ich habe 10 großartige Referenzen zitiert. Diese Dinge sollten dich zum Brummen bringen. Bitte lassen Sie uns wissen, wie es ausgeht.


6

Verschieben Sie Ihre PHP-Sitzungsdateien in ein tmpfs , verwenden Sie APC (oder ein anderes) und entfernen Sie alle PHP-Module, die Sie nicht benötigen. Entfernen Sie alle Apache-Module, die Sie nicht benötigen / verwenden.

So erstellen Sie ein tmpfs (ein Verzeichnis im RAM!)

mkdir /tmpfs; chmod 777 /tmpfs
mount -t tmpfs -o size=256M tmpfs /tmpfs

Fügen Sie in / etc / fstab die folgende Zeile hinzu, um sie beim Neustart zu erstellen!

tmpfs     /tmpfs    tmpfs   size=256m,mode=0777    0       0

In /etc/apache2/php.ini passen Sie Ihre Sitzungen im RAM zu speichern (tmpfs)!

session.save_handler = files
session.save_path = "/tmpfs"

Hinweis: Mit Ihren PHP-Dateien UND Sitzungsdateien im RAM berühren Sie die Festplatte kaum!

Verwenden Sie expires_module in Apache, damit Browser die meisten Dinge zwischenspeichern können.

ExpiresActive On
ExpiresDefault "access plus 90 days"
ExpiresByType image/gif "access plus 90 days"
ExpiresByType image/ico "access plus 90 days"
ExpiresByType image/png "access plus 90 days"
ExpiresByType image/jpeg "access plus 90 days"
ExpiresByType image/x-icon "access plus 90 days"
ExpiresByType text/css "Access plus 90 days"
ExpiresByType text/html "Access plus 90 days"
ExpiresByType application/x-shockwave-flash "Access plus 90 days"
ExpiresByType application/x-javascript "Access plus 90 days"

Verwenden Sie keine .htaccess- Dateien! Code sie stattdessen hart in der vhost-Konfigurationsdatei! Ermöglicht eine drastische Reduzierung der Festplattenüberprüfungen für alle HTTP-Anforderungen. Das summiert sich wirklich.

Options FollowSymLinks 
AllowOverride None

Beispiel für .htaccess in Ihrer vhost.conf-Datei ...

<Directory /home/user/www/site.com/secure>
    Order Allow,Deny
    Deny from All
</Directory>

5

Ein paar Dinge fallen mir ein.

Opcode-Cache ist immer eine gute Idee. Ich bevorzuge http://eaccelerator.net/ gegenüber APC. Wenn Sie nicht mit APC entwickelt haben, ist der Versuch, es hinzuzufügen, fast immer schmerzhaft. Beschleuniger während nicht so schick scheint nur zu funktionieren.

Ein Reverse-Proxy ist auch eine gute Idee, aber Sie müssen die RAM-Auslastung beobachten. Ich finde, dass Apache 2.2 mit mpm-worker eine ganze Menge RAM alleine beansprucht. In Ihrem Fall würde ich etwas Leichteres wie Nginx empfehlen und Apache mit PHP als FASTCGI ausführen oder es einfach wie prozess lassen. Mit Varnish, Squid, Nginx usw. sollen statische Inhalte bereitgestellt, Benutzerverbindungen verwaltet und nur PHP-Anforderungen an Apache weitergeleitet werden, die Sie als Anwendungsserver behandeln.

Wenn Sie eine relativ neue Version von Mysql 5.1 verwenden, wie mindestens 5.1.24, haben Sie jetzt Zugriff auf langsame Protokolle von weniger als einer Sekunde. Ich würde long_query_time bei 1 oder 2 beginnen und es dann auf 0.5 senken, wenn Sie die wirklich langen in den Griff bekommen. Es gibt auch viele allgemeine Tuning-Informationen für MySQL im Internet, aber Sie haben nicht viel RAM. Haben Sie eine der Standardeinstellungen erhöht? Die meisten my.cnf-Standarddateien sind für die Verwendung von ca. 64 MB RAM konfiguriert. Zumindest würde ich den key_buffer von 16MB auf 64MB erhöhen.

Verwenden Sie zusätzlich Myisam- oder Innodb-Tabellen? Wenn Sie die Sitzung in der Datenbank beibehalten, möchten Sie die Sitzungstabelle in Innodb ändern (oder stattdessen als Cookie festlegen), anstatt eine Mysiam-Tabelle zu belassen, die das Sperren auf Tabellenebene anstelle des Sperrens auf Zeilenebene ausführt. Grundsätzlich ist jede Tabelle, die mehr als 20% Schreibzugriff auf 80% Lesezugriff hat, ein Kandidat für den Wechsel zu Innodb. Denken Sie daran, dass Sie die Größe des Arbeitsspeichers zwischen Myisam-Tabellen und Innodb-Tabellen ausgleichen müssen, da die Puffer für jede Tabelle separat konfiguriert werden.

Und zu guter Letzt würden weitere 512 MB RAM in Ihrem Setup viel bewirken, oder sogar weitere 512 MB VPS, um MySQL zu betreiben, wenn dies billiger oder ungefähr zum gleichen Preis ist. Ich würde mich tatsächlich zu einer zweiten Instanz neigen, da dies die verfügbaren Festplatten-E / A verdoppelt. Eines der Probleme mit VPS-Servern ist, dass Ihre E / A nicht vor anderen Personen auf demselben physischen Server geschützt ist.

Hmmm, mein Beitrag ist ein bisschen zerstreut, aber es gibt dir viele Orte, an denen du nachsehen kannst. Viel Glück.


2
  • Verwenden Sie einen Opcode-Cache für PHP wie apc.
  • Verwenden Sie einen http-Beschleuniger wie Tintenfisch oder Lack.

1

In einer Situation mit geringem Arbeitsspeicher (512 MB sind für einen Server mit hohem Datenverkehr niedrig) sollten Sie überlegen, welchen Webserver und welche DB-Engine Sie auswählen.

Lighttp ist im Auslieferungszustand leichter als Apache normalerweise nach vielen Optimierungen und es gibt sogar leichtere Optionen. Dies ist natürlich nicht möglich, wenn es Apache-Funktionen gibt, von denen Sie abhängig sind und die von anderen Servern nicht unterstützt werden.

sqlite ist viel enger als mySQL und unter vielen Bedingungen auch schneller. Überprüfen Sie, ob die von Ihnen verwendete Engine dies ebenfalls unterstützt, und probieren Sie es aus.

Die andere Option, die einfache Option, besteht darin, mehr RAM in die VM zu laden, wenn Sie es sich leisten können.


1

Abgesehen von den großartigen Vorschlägen hier sollte angemerkt werden, dass nicht alle VPS gleich sind. Meiner Erfahrung nach erwies sich PHP als CPU-lastig.

Ein Wordpress AB-Benchmark (ab -n 500 -c 25 http://domain.com/index.php ) von nginx / apc / phpfpm / mysql (lokal) auf EC2 führte zu ~ 2 Anfragen / Sekunde auf der Einstiegsstufe "2 GB" RAM / 1 Compute Unit Server ".

Der gleiche Benchmark-Lauf auf einem 512-MB-Rackspace-Cloudserver mit genau demselben Stack (per Skript für dasselbe Betriebssystem bereitgestellt) ergibt ~ 80 Req / Sekunde. Also 4x weniger RAM, 40x Leistung in diesem rudimentären Experiment.

Wenn Sie während des AB nach oben schauen, sehen Sie, dass EC2 die Parallelität einfach nicht bewältigen konnte und sofort 100% CPU-Last traf und abstürzte. Wenn Sie oben auf dem 512-MB-Server (virtualisierte Quad-Core-CPU) nach dem gleichen Benchmark sehen, würden die Kerne eine Auslastung von ~ 60% erreichen und den Benchmark reibungslos verarbeiten.

VPS sind extrem einfach zu starten und zu deaktivieren. Es schadet nicht, die Infrastruktur, in der sich Ihre VM / VPS befindet, auf den Prüfstand zu stellen!

EDIT 1: Außerdem konnte die kleine EC2-Instanz "High CPU" nur ~ 10 / req Sekunde liefern, wobei die CPU immer noch der Engpass war. Mein Fazit war, dass Sie mit EC2 Leistung für Stabilität / Robustheit opfern, und es gibt natürlich viele Anwendungsfälle, die eine solche Umgebung erfordern.


Denken Sie auch an Nginx (Version 1, die heute veröffentlicht wurde). wordpress.com hat seine Litespeed-Konfiguration gegen Nginx ausgetauscht, so dass es sich eindeutig um einen fähigen Webserver handelt.
iainlbc

Nginx ist in der Tat beeindruckend. Ich wünschte nur, es könnte mod_rewrite-Regeln aus .htaccess-Dateien lesen.
Martijn Heemels
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.