Apache Tuning
Damit der Server möglichst viele Requests handeln kann, habe ich mich für Apache Worker entschieden. PHP rät zwar davon ab etwas anderes als Apache Prefork zu benutzen, aber mit Apache Worker hab ich bisher keine schlechten Erfahrungen gemacht – im Gegenteil 😉
Hier werden die verschiedenen Direktiven von Apache Worker MPM behandelt. Die Installations Anleitung für Apache gibt hier.
Grundsätzliches / Default Settings
Das Tuning der MPM Einstellungen ist natürlich von der verwendeten Server Hardware abhängig. Das hier sind die Default Einstellungen im File:
vi /www/server/apache/extra/httpd-mpm.conf
# worker MPM
# StartServers: initial number of server processes to start
# MaxClients: maximum number of simultaneous client connections
# MinSpareThreads: minimum number of worker threads which are kept spare
# MaxSpareThreads: maximum number of worker threads which are kept spare
# ThreadsPerChild: constant number of worker threads in each server process
# MaxRequestsPerChild: maximum number of requests a server process serves
<IfModule mpm_worker_module>
StartServers 2
MaxClients 150
MinSpareThreads 25
MaxSpareThreads 75
ThreadsPerChild 25
MaxRequestsPerChild 0
</IfModule>
Der Server Status (http://127.0.0.1/server-status) sieht bei dieser Konfiguration etwa so aus:
Current Time: Saturday, 11-Feb-2012 12:52:23 CET
Restart Time: Saturday, 11-Feb-2012 11:07:01 CET
Parent Server Generation: 2
Server uptime: 1 hour 45 minutes 22 seconds
Total accesses: 72531 - Total Traffic: 28.7 MB
CPU Usage: u6.04688 s5.07813 cu0 cs0 - .176% CPU load
11.5 requests/sec - 4767 B/second - 415 B/request
97 requests currently being processed, 53 idle workers
_W_L_L____LCL_R___C_____L....................................... WL_W__LLLW___LL_____CWW_L....................................... LLLWCWLW_W_WWWRW___LW_W__....................................... LLLLLWLRW___LW_LWLWLLLRWL....................................... LWRLLLWWLLLRR_LLLWLLWLLLL....................................... _LLW__LW_W_L__LW__L___LRL....................................... ................................................................ ................................................................ ................................................................ ................................................................ ................................................................ ................................................................ ................................................................ ................................................................ ................................................................ ................................................................
- Jede Zeile ( = Server ) besteht aus 64 Punkten.
- Jeder Punkt (.) steht für einen möglichen Client.
- Im Beispiel oben wurden also 6 Server gestartet. Und jeder Server handelt 25 Clients (ThreadsPerChild). Und wir haben 6 x 25 = 150 Maxclients
Tuning
Schauen wir mal, was für uns eine optimale Einstellung wäre. Zuerst einmal wieviel Speicher möchten wir Apache zur Verfügung geben. Wir haben total 2.5GB RAM. Da auf dem Server praktisch nur Apache läuft, geb ich für Apache 2GB frei.
Ein Apache Prozess benötigt ca. 100MB RAM. php-ftp benöigt dann pro Prozess ebenfalls nochmal je 145MB RAM.
ps auxf | grep http
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND root 47958 0.0 0.4 104496 7512 ?? Ss 11:01AM 0:01.09 /usr/local/sbin/httpd -k start
[..]
ps auxf | grep fpm
USER PID %CPU %MEM VSZ RSS TT STAT STARTED TIME COMMAND
www 48754 1.0 0.6 149116 11484 ?? S 12:44PM 0:00.81 php-fpm: pool www (php-fpm)
[..]
VSZ ist der Virtuelle Speicher in kB. Somit 104496 / 1024 = 102 MB
VSZ / RSS
VSZ steht für „virtual set size“, RSS für „resident set size“. Sie werden benötigt um zu sehen wieviel Memory ein Prozess benötigt. Mit PS wird die Grösse in Kb ausgegeben. Wichtig ist, dass man nicht die eine oder die andere Zahl als die „echte“ Memory Usage nehmen kann. Um jedoch einen groben Überblick des Memories zu bekommen, nimmt man am besten die RSS Spalte. Dort sind keine Buffers oder Cache Daten included – wie es beim VSS der Fall wäre.
ServerLimit / StartServers
Damit er also die 2GB nicht übersteigt, limitieren wir die Prozesse auf 10 (dann werden zwar 11 gestartet, aber immerhin 😉 Zu Beginn sollen gleich 8 Prozesse gestartet werden. Werden mehr benötigt, dann startet er die restlichen 2 von selber.
ServerLimit 10 StartServers 3
In der Regel werden nicht mehr als 6 Server (Linien) benötigt.
Jetzt kann man auch im Server-Status sehen, dass es auf 10 Limitiert ist (die restlichen 10 Linien sind frei und werden auch unter hohem load nicht mehr belegt). Pro Server können 64 Clients gehandelt werden (jeder Punkt ist 1 Client)
______KK______K_________________________________________________ K______C_____________________________________________________KK_ K_K___K________________________________________________________K _______W_K__K_________________________________W_________________ KK__________K_______________________________________________K___ _______________________________________________________________C ________K______K________________________________________K_____K_ _____K____K_____________________________________________________ __K_______K____________________________________________________C _K_________________________________________________K____________ ................................................................ ................................................................ ................................................................ ................................................................ ................................................................ ................................................................
ThreadsPerChild
Die Direktive legt die Anzahl der Threads fest, die mit jedem Kindprozess gestartet werden. Der Kindprozess erstellt diese Threads beim Start und erstellt später keine weiteren mehr. Wenn man ein MPM wie worker verwendet, wo mehrere Kindprozesse existieren, dann sollte die Gesamtzahl der Thread gross genug sein, die übliche Last auf dem Server zu bewältigen.
Die Voreinstellung für ThreadsPerChild ist 25 bei der Verwendung des worker MPMs.
Hier kann man etwas rumspielen und testen. Ich bin bei mir auf folgendes Ergebnis gekommen:
- Bei ThreadsPerChild 25 braucht jeder Apache Prozess ca. 100MB
- Bei ThreadsPerChild 64 kann ein Apache Prozess bis zu 200MB benötigen
ThreadsPerChild 64
MaxClients
MaxClients machen wir 10×64 (ServerLimit x ThreadsPerChild) also
MaxClients 640
MinSpareThreads
Minimale Anzahl unbeschäftigter Threads, die zur Bedienung von Anfragespitzen zur Verfügung stehen. Worker verwendet eine Voreinstellung von MinSpareThreads 75 und behandelt unbeschäftigte Threads auf serverweiter Basis. Wenn nicht genügend unbeschäftigte Threads im Server vorhanden sind, dann werden solange Kindprozesse erzeugt, bis die Anzahl unbeschäftigter Threads grösser als der angegebene Wert ist.
Das ist die Total Anzahl bei server-status. Also
MinSpareThreads ist im Besten Fall
ThreadsPerChild * 3
Also 64 x 3 = 192
So dass immer genügend Child Prozesse vorhanden sind (ein neuer Prozess zu starten bedeutet auch immer mehr Ressource)
MinSpareThreads 192
MaxSpareThreads
Maximale Anzahl unbeschäftigter Threads
Die Voreinstellung für worker ist MaxSpareThreads 75. Wenn zu viele unbeschäftigte Threads im Server existieren, dann werden solange Kindprozesse beendet, bis die Anzahl der unbeschäftigten Threads kleiner als der angegebene Wert ist.
Der Wertebereich von MaxSpareThreads ist eingeschränkt. Apache korrigiert den angegebenen Wert automatisch gemäss den folgenden Regeln:
Bei worker muss der Wert grösser oder gleich der Summe aus MinSpareThreads und ThreadsPerChild sein.
MaxSpareThreads 256
Beispiel Config
Diese Config kann 640 gleichzeitige Zugriffe handeln:
<IfModule mpm_worker_module>
ServerLimit 10
StartServers 3
MaxClients 640
MinSpareThreads 192
MaxSpareThreads 256
ThreadsPerChild 64
MaxRequestsPerChild 0
</IfModule>
Benchmark Tests
- http://www.petefreitag.com/item/689.cfm
- http://www.cyberciti.biz/tips/howto-performance-benchmarks-a-web-server.html