Warum läuft Apache wild und tötet MySQL?

8

Apache ist in den letzten Tagen außer Kontrolle geraten und hat MySQL zweimal zum Absturz gebracht. Alles begann, als ich eine WordPress-Website migrierte, über die auch ein phpBB-Forum enthält.

Ich bin nicht sehr erfahren in der Serververwaltung, daher war es für mich sehr schwierig, genau zu bestimmen, was das Problem verursacht. Als ich bemerkte, dass MySQL nicht verfügbar war, führte ich TOP aus und sah einen Anstieg der Systemlast auf 98,00. Auf dem Server werden 10 V-HOSTS ausgeführt, die alle eine gute Menge an Datenverkehr empfangen. Daher wurden offensichtlich viele Apache-2-Prozesse ausgeführt.

Die hohe Serverlast dauerte 10 Minuten und kehrte dann in den normalen Zustand zurück. Zu diesem Zeitpunkt habe ich keinen Anstieg des Netzwerkverkehrs festgestellt.

Leider wurde die MySQL-Fehlerprotokollierung deaktiviert (sie ist jetzt wieder aktiviert), daher gibt es dort keine Hinweise. Aber ich bin mir ziemlich sicher, dass Apache alle Ressourcen verbraucht hat, sodass die MySQL-Prozess-ID gelöscht wurde.

Meine Fragen sind:

Wie kann ich beim nächsten Mal feststellen, was die Systemlastspitze verursacht? Könnte es ein PHP-Skript sein, das verrückt geworden ist? Könnte es ein DDOS-Angriff sein?

Gibt es eine Möglichkeit, MySQL automatisch neu zu starten, wenn es abstürzt?

Ich habe jetzt installiert htop. Könnte dies nützlicher sein als top?

Hier meine Serverstatistik:

m1.xlarge (8 ECUs, 4 vCPUs, 15 GiB memory, 4 x 420 GiB Storage Capacity)
Ubuntu Server 12.04.3 LTS 
Bob Flemming
quelle
Obwohl Protokolle deaktiviert waren, würde dmesghelfen?
Daniel W.

Antworten:

9

MySQL protokolliert möglicherweise immer noch nichts, da es wahrscheinlich passiert, dass es vom System aufgrund des Systemspeicherdrucks von Apaches Kindern kurzerhand getötet wird. Es sollte eine Spur davon in / var / log / syslog geben.

MySQL sollte versuchen, sich bei einem Absturz oder einer erzwungenen Beendigung neu zu starten, aber wenn nicht genügend Speicher verfügbar ist, kann es das nicht tun ... und dieser zweite Fehler wird von mysqld_safe nicht als "Absturz", sondern als "Ablehnung" angesehen Start ", so wird es nicht weiter versuchen. Der fehlgeschlagene Neustartversuch wird von Administratoren häufig als "Absturz" interpretiert, da die Art des ursprünglichen Fehlers hinter einer leicht zu übersehenden Meldung im MySQL-Fehlerprotokoll verborgen ist:

mysqld_safe Number of processes running now: 0

Siehe InnoDB Crash Post Mortem für einen Umstand, von dem ich vermute, dass er Ihrem ähnlich ist.

Die scheinbar einfache Antwort auf das "Warum" ist, dass zwischen Apache und MySQL, der Last, die Sie haben, und Ihren aktuellen Konfigurationen nicht genügend Speicher auf dem Computer vorhanden ist und es einen Wendepunkt im Zusammenhang mit der Verkehrslast gibt, der diesen Zustand hervorruft .

Apache bedient jede gleichzeitige Browseranforderung eines untergeordneten Prozesses. Wenn also die Anzahl der gleichzeitigen Verbindungen steigt, steigt die Anzahl der untergeordneten Verbindungen. Sie müssen diesen Wert zunächst in der Apache-Konfiguration begrenzen, damit Sie verstehen, was tatsächlich die Zunahme gleichzeitiger Verbindungen verursacht. Ist dies einfach eine starke, aber legitime Verkehrsspitze? Eine Art Denial-of-Service? DB-Abfragen, die Anforderungen verzögern, weil sie zu lange ausgeführt werden? Etwas, das optimiert werden muss?

http://httpd.apache.org/docs/2.2/mod/mpm_common.html#maxclients

Das Einschränken gleichzeitiger Apache-Prozesse sollte dazu beitragen, dies zu verhindern. Um es klar auszudrücken, ist es naiv zu glauben, dass dies die vollständige Lösung ist, daher möchte ich dies nicht implizieren. Sobald die Prozesse auf ein vernünftiges oder zumindest sichereres Maß beschränkt sind, können Sie feststellen, was wirklich vor sich geht. (Es gibt andere Rückhaltekontrollen bei Apache, aber das ist nicht mein Fachgebiet.)

Die "Best Practice" besteht natürlich darin, Ihre Datenbank auf einer anderen Hardware auszuführen, damit die Anwendung sie nicht beenden kann. Oberflächlich betrachtet scheint es zwar effizienter zu sein, die Auslastung einer Maschine durch gemeinsame Nutzung zu maximieren, dies ist jedoch eine falsche Wirtschaftlichkeit. Der größte Teil des von MySQL in einer typischen Arbeitslast verwendeten Speichers wird beim Start zugewiesen und so lange gehalten, wie MySQL Server ausgeführt wird. Die Anforderungen an die CPU teilen sich wahrscheinlich die Spitzenzeiten für MySQL und Apache, da sie letztendlich die gleiche Last bedienen. Mit zwei m1.large-Maschinen anstelle der einzelnen m1.xlarge-Maschine sind Sie möglicherweise besser dran, und die Kosten wären gleich, da die kleinere genau die Hälfte des Preises der größeren ist ... selbst wenn Sie bereits im Voraus bezahlt haben Für den zusätzlichen Rabatt kann diese Änderung durchgeführt werden .

Michael - sqlbot
quelle
Vielen Dank für Ihre Antwort, es war wirklich hilfreich. Ich habe / ver / log / syslog überprüft und die folgenden Zeilen gefunden: 18. Dezember 15:48:38 ip-10-33-164-173 Kernel: [29714591.071719] Nicht genügend Speicher: Prozess beenden 28369 (mysqld) Punktzahl 21 oder Opfer Kind 18. Dezember 15:48:38 ip-10-33-164-173 Kernel: [29714591.071753] Abgetöteter Prozess 28369 (mysqld) total-vm: 2520332kB, anon-rss: 335304kB, file-rss: 0kB Sie denken also, Sie beschränken den Die Einstellung von maxclients in Apache ist die beste Wahl, um dies zu verhindern. Was denkst du wäre ein sicherer Wert?
Bob Flemming
1
Ich würde vorschlagen, dass die Begrenzung von maxclients der beste Weg ist, um den Prozess des Verstehens der Umstände zu beginnen, die zu der Lawine beitragen, die Sie erleben. Sie müssen einen sichereren Wert ermitteln, der auf Ihren Umständen, der Menge an freiem Speicher auf dem System und der typischen Menge an Speicher basiert, die die Apache-Kinder verwenden. Zu niedrig, und die Anforderungen werden gesichert. zu hoch und du bist da, wo du jetzt bist. Überwachen Sie dann die erzeugten Prozesse und beobachten Sie Ihre freien Speicher- und Serverprotokolle.
Michael - sqlbot
1

Sie müssen einige Punkte überprüfen:

-Überprüfen Sie die Datei / var / log / messages: oomkiller kann den MySQL-Prozess beenden, wenn kein Speicher mehr verwendet werden kann. Überprüfen Sie den RAM mit free -lm (ohne Cache)

-Wenn Sie Apache mit Prefork MPM verwenden: Überprüfen Sie die Anzahl der Prozesse. Wenn Apache eine wichtige Anzahl von Prozessen (während einer hohen Arbeitslast) mit einem Link zu MySQL stapelt, können die Latenz und der verwendete Speicher schnell zunehmen.

-Überprüfen Sie die Anzahl der von mysql gestarteten Threads mit dem Status show global : threads_cached, threads_created und threads_running müssen überprüft werden (threads_created sollte nahe 0 sein).

-Überprüfen Sie den von MySQL verwendeten RAM.

Jérémy Munoz
quelle
0

Sie können sich auch mit der Implementierung von cpusets und der Reservierung von Ressourcen für MySQL befassen . Dies kommt der Ausführung dieser Dienste auf unterschiedlicher Hardware am nächsten und bietet Ihnen dennoch die Vorteile der Wartung eines einzelnen Servers.

Skohrs
quelle