Verbraucht Pitchfork zu viel Speicher?

Sieht das noch jemand anderes? Es ist ein ziemlich kleines Forum, was Größe und Traffic angeht. Es gibt vier Pitchfork-Worker-Prozesse, und es scheint, als würde einer von ihnen den Großteil der eingehenden Anfragen verarbeiten und dabei mehr Speicher als die anderen verbrauchen. Es wird viel Swap-Speicher genutzt, und wenn man Pitchfork absichtlich neu startet, sinkt der Verbrauch erheblich. Daraus schließe ich, dass die Pitchfork-Prozesse derzeit viele kalte Seiten haben, die in den Swap ausgelagert wurden.

Dies ist nach 20 Tagen Laufzeit auf einem System mit 4 GB RAM und 4 GB Swap.

Es wäre schlecht, wenn der Swap-Speicher aufgebraucht wäre. Es wäre auch schlecht, wenn all dieser Swap-Speicher wieder in den Arbeitsspeicher geladen würde, was möglicherweise geschehen könnte, wenn Pitchfork irgendwann eine Garbage Collection durchführt.

Sieht jemand Ähnliches? Bitte teilt eure Systemkonfiguration mit!

# ps aux | sort -n -k 4 | egrep pitchf\|MEM |tail
root     2167652  0.0  0.0   5912  1792 pts/0    S+   20:07   0:00 grep -E --color=auto pitchf|MEM
USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
1000       15094  0.0  0.2 497544 10988 ?        Sl   Jul28   0:17 pitchfork monitor - 
1000       15704  0.0  2.5 6799124 97836 ?       Sl   Jul28   1:00 pitchfork (gen:0) service - ready
1000       15097  0.0  4.8 6791252 189724 ?      Sl   Jul28   5:26 pitchfork (gen:0) mold - ready
1000       15959  0.0  8.1 6815508 319708 ?      Sl   Jul28  12:05 pitchfork (gen:0) worker[3] - requests: 6684, waiting
1000       15900  0.0  9.2 6864596 360696 ?      Sl   Jul28  17:43 pitchfork (gen:0) worker[2] - requests: 14756, waiting
1000       15795  0.1 10.3 6884756 405420 ?      Sl   Jul28  48:36 pitchfork (gen:0) worker[1] - requests: 97007, waiting
1000       15734  2.1 12.8 11299708 500120 ?     Sl   Jul28 637:50 pitchfork (gen:0) worker[0] - requests: 2229848, waiting

# free
               total        used        free      shared  buff/cache   available
Mem:         3904968     1874636       98840      678812     1931492     1160916
Swap:        4194288     1226600     2967688


# vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0 1226600 115820  65288 1866284    1    1    20    38    0    3  3  1 97  0  0
 0  0 1226600 113208  65296 1866296    0    0     0    14  411  478  1  1 98  0  0
 0  0 1226600 112956  65304 1866336    0    0     1    23  438  528  2  1 97  0  0
 0  0 1226600 112704  65308 1866360    0    0     1    31  518  603  5  1 94  0  0
 0  0 1226600 112704  65308 1866364    0    0     0    11  347  387  1  1 98  0  0

Die vmstat-Ausgabe zeigt, dass derzeit kein Speicherdruck herrscht – keine Paging-Aktivität. Meine Sorge ist, dass eine Gefahr besteht, nicht dass meine Installation derzeit schlecht funktioniert.

cpu0

In einem ernsteren Ton: Der Worker, der die gesamte Arbeit erledigt, hat nur 100 MB RSS über dem Durchschnitt? Das sieht für mich normal aus, oder übersehe ich etwas?

Ich wäre daran interessiert, die Statistiken von einem aktiveren Forum zu sehen. Es scheint, dass die kumulative Anzahl der Anfragen wichtig ist, und meines ist keineswegs besonders aktiv.

Ja, die RSS-Unterschiede sind relativ gering, aber der Bereich von 300 M bis 500 M bedeutet proportional schon einen deutlichen Unterschied.

Auffälliger ist der Swap-Verbrauch. Bevor ich mit den Gabeln schwingen beginne, sehe ich:

# free
               total        used        free      shared  buff/cache   available
Mem:         3904968     1888140       77308      679004     1939520     1147220
Swap:        4194288     1226344     2967944

und danach:

# free
               total        used        free      shared  buff/cache   available
Mem:         3904968     1486412     1422380      640744      996176     1587908
Swap:        4194288      309892     3884396

Meiner Meinung nach wurden durch das Recycling 1300 M freigegeben (Differenz aus used + swap).

Ich glaube nicht, dass ich bei der Verwendung von Unicorn je so viel Swap benötigt habe: Daher der Titel.

Wie gesagt, ich bin daran interessiert, Zahlen von anderen Instanzen zu sehen.

Es ist normal, dass ein einzelner Pitchfork-Prozess den Großteil der Last bearbeitet – andere Prozesse werden nur dann herangezogen, wenn der erste beschäftigt ist. Es ist ebenfalls normal, dass der Speicherverbrauch im Laufe der Zeit zunimmt. Er sollte jedoch nach einer Weile einen stabilen Zustand erreichen, sobald alles, wie z. B. Caches und Ruby-JIT, hochgefahren ist.

Hier ist ein Graph aus einem unserer Produktivcluster über einen Zeitraum von 7 Tagen. Er zeigt den einzelnen Prozess mit dem höchsten Speicherverbrauch. Die grünen gepunkteten Linien kennzeichnen Deploys (d. h. Neustarts von Pitchfork):

Man sieht also, dass der Verbrauch nach dem ersten Start zunimmt, dann aber bei knapp unter 1,4 GB stabil bleibt. Dieser Cluster bedient Hunderte von Websites, daher ist er in Bezug auf die nackten Zahlen vielleicht nicht der beste Vergleichsmaßstab… aber die Visualisierung des Wachstums sollte hoffentlich hilfreich sein.

Die RSS-Werte pro Prozess erzählen nicht die ganze Geschichte. Pitchfork ist ein „forking web server“. Er startet also den „Mold“-Prozess, und alle Worker werden daraus mittels eines Copy-on-Write-Speichermusters abgeleitet. Während der RSS-Wert für worker[0] beispielsweise 500 MB anzeigen mag, sind etwa 200 MB davon mit dem Mold und allen anderen Workern geteilt.

In nicht allzu ferner Zukunft hoffen wir, die „Reforking“-Funktion von Pitchfork aktivieren zu können. Sie tötet regelmäßig Worker und leitet sie von einem bereits hochgefahrenen Worker neu ab, sodass sie im Laufe der Zeit so viel Speicher wie möglich teilen. Dafür müssen wir jedoch noch sicherstellen, dass unser gesamter Code mit diesem Muster kompatibel ist :crossed_fingers:

Nützliche Visualisierung, danke. Ich würde nicht behaupten, dass sich das bereits stabilisiert hat, aber das Wachstum ist nicht mehr so hoch wie zuvor.

Das regelmäßige Reforken klingt wie eine großartige Sache, die man einführen könnte – wenn du kannst, bitte hier einen Hinweis setzen, sobald das umgesetzt ist.

Kannst du etwas zu den grünen Linien sagen? Mich interessiert, wann (wenn überhaupt) die Pitchforks eine Müllsammlung durchführen, was sie auslöst und welche Auswirkungen das währenddessen hat.

Die grünen Linien zeigen an, wann wir Updates ausrollen. Im Wesentlichen: ./launcher rebuild app.

Ruby (und JS, das wir über MiniRacer/v8 innerhalb der Ruby-Prozesse ausführen) führt während der Laufzeit und als Reaktion auf Signale des Betriebssystems kontinuierlich eine Garbage Collection durch. Ich denke daher nicht, dass sich durch manuelle Eingriffe ein großer Vorteil ergeben würde.

Danke. Ich wäre interessiert zu sehen, wie sich die Dinge langfristig entwickeln – was auf einem Server, der relativ häufig aktualisiert wird, nicht offensichtlich sein wird. In meinem Fall hatte ich 20 Tage, bevor ich mich entschied, mit einer Gabel neu zu starten. Das hat mir zwar etwas verraten, aber auch den Taktgeber zurückgesetzt.