Ich kapier jetzt nicht was besser ist:
1 Prozess mit 400 maxClients oder
4 Prozesse mit 100 max Clients.
http://httpd.apache.org/docs/2.2/de/mod/worker.html said:
Die maximale Anzahl Clients, die gleichzeitig bedient werden kann (d.h. die maximale Gesamtzahl der Threads in allen Prozessen), wird mit der Direktive MaxClients festgelegt.
In beiden Fällen wäre also
MaxClients 400 die entsprechende Direktive. 400 Threads in einem Prozess halte ich aber nicht für wirklich sinnvoll.
Zur Begründung muss man sich anschauen, wie Threads sich von Prozessen unterscheiden. Threads sind immer Bestandteil eines Prozesses. Während unterschiedliche Prozesse auch unterschiedliche Prozessräume (DATA, TEXT, etc. Speichersegmente) haben, teilen sich alle Threads innerhalb eines Prozesses diese Ressourcen.
Daher bedeutet es zunächst mehr Overhead, wenn mehr Prozesse existieren - für jeden muss ja ein eigener Prozessraum erzeugt werden; bei einem Kontext-Wechsel auf der CPU müssen auch die zugehörigen Speichersegmente de-/aktiviert werden. Ein Thread-Kontextwechsel innerhalb eines Prozesses unterliegt dieser Einschränkung nicht, hier wird (in der Theorie) nur der Instruction Pointer neu gesetzt, und weiter geht's.
In der Praxis gibt es aber deutliche Einschränkungen. Da Threads innerhalb eines Prozesses dieselben Speicherbereiche benutzen, müssen kritische Operationen wie z. B. das Reservieren von Speicherblöcken auf diesem gemeinsam genutzten Speicherbereich durch geeignete Mechanismen geschützt werden (bei Threads geschieht dies i. d. R. durch einen Mutex). Im Klartext: während ein Thread eines Prozesses eine kritische Operation durchführt, darf kein anderer Thread desselben Prozesses (der ev. auf einem anderen CPU-Kern läuft) dieselbe kritische Operation ausführen.
Je mehr Threads es innerhalb eines Prozesses gibt, desto höher ist also die Wahrscheinlichkeit, dass ein Thread einen anderen in der Ausführung behindert. Es kommt zwar dadurch bei sauberer Programmierung nicht zu einem Deadlock, aber es bildet sich ein Stau.
Eine genaue Grenze lässt sich da nicht ziehen, da diese stark von der Nutzung gemeinsamer Ressourcen abhängt. Ein häufig genannter Daumenwert für Linux-Systeme lautet 32: Bei dieser Anzahl Threads innerhalb eines Prozesses kommt es noch nicht zu so gravierenden Behinderungen, dass die Leistung der Threads in Summe wieder abnimmt.
Ich würde daher empfehlen, MaxClients insgesamt erst mal deutlich zu limitieren - 400 Threads können auf handelsüblichen Systemen sowieso nicht parallel laufen. Wenn so viele Threads im Status Wait hängen, dauert es ohnehin ziemlich lange, bis ein bestimmter Thread wieder vom Scheduler drangenommen wird. Irgendwo ist der Punkt dann erreicht, wo der anfragende Client besser in der Queue gehalten wird (steuerbar über
ListenBackLog), bis ein Thread "frei" ist und sich des Clients annehmen kann.
Ich würde mit den Standard-Werten oder sogar leicht darunter starten (MaxClients <= 100) und dann dem Server ordentlich Feuer machen (ab, Siege & Co.). Dann langsam in den Bereich reinsteigern, wo Du tatsächlich Deine Spitzen-Hitrate erwartest. Dabei würde ich darauf achten, dass pro Child nicht mehr als 24 Threads gestartet werden (25 ist bei mpm_worker default und auch sinnvoll).
Bei den Versuchen dann immer die durchschnittliche Antwortzeit und den Ressourcenverbrauch (Anzahl Prozesse und Threads) im Auge behalten - so kann man sich mal schnell eine Load im 3stelligen Bereich erzeugen und/oder sogar den OOM-Killer auf den Plan rufen. Genau das ist ja aber die Situation, die man beim Tuning vermeiden will - es muss also immer Luft im System sein. Wenn damit die Antwortzeiten bei den erwarteten Hitrates immer noch in einem unbefriedigenden Bereich liegen, hilft eigentlich nur noch horizontale Skalierung.
Ich habe die Doku jetzt so verstanden:
Beim Start des Apache wird ein Eltern Prozess gestartet.
Dieser Startet dann Kindprozesse. (StartServers).
Soweit korrekt.
Jeder dieser Prozesse kann z.b. 100 MaxClients bedienen.
Passt das soweit?
Nein. Alle Kind-Prozesse zusammen können 100
MaxClients bedienen. Jeder einzelne Kindprozess bedient maximal
ThreadsPerChild Clients. Wenn jetzt die maximale Anzahl an Kindprozessen durch
ServerLimit ebenfalls limitiert ist, muss man sehr genau darauf achten, dass sich die gesetzten Limits nicht gegenseitig widersprechen.
Beispiel:
Code:
MaxClients 600
ServerLimit 10
ServerThreads 10
ist natürlich Blödsinn - 10 Prozesse mit je 10 Threads können eben maximal 100 Clients gleichzeitig verarzten, und nicht 600.
Sorry, ist ein bisschen länger geworden - hoffe, es ist trotzdem noch einigermaßen verständlich. Wenn nicht, einfach weiterbohren
