Qualcuno vede lo stesso problema? È un forum piuttosto modesto per dimensioni e traffico. Ci sono quattro processi worker di pitchfork, e sembra che uno di essi gestisca la grande maggioranza delle richieste in ingresso e stia utilizzando più memoria rispetto agli altri. C’è un uso elevato della swap, e respawnando deliberatamente pitchfork questo si riduce considerevolmente. Quindi concludo che i processi pitchfork hanno molte pagine fredde attualmente scambiate (swapped out).
Questo è dopo 20 giorni di funzionamento, su una macchina con 4G di RAM e 4G di swap.
Non sarebbe buona cosa esaurire la swap. Non sarebbe buona cosa scoprire che tutta quella swap viene ripaginata in memoria, come potrebbe accadere quando pitchfork alla fine esegue una raccolta dei rifiuti (garbage collect).
Qualcuno vede qualcosa di simile? Condividete la configurazione della macchina, per favore!
L’output di vmstat mostra che al momento non c’è pressione sulla memoria: nessuna attività di paging. La mia preoccupazione è che esista un pericolo, non che la mia installazione stia funzionando male in questo momento.
Mi piacerebbe vedere le statistiche di un forum più attivo. Sembra che il numero cumulativo di richieste sia importante, e il mio non è per niente molto affollato.
Sì, le differenze di RSS sono relativamente modeste, ma passando da 300M a 500M la differenza è piuttosto significativa in termini proporzionali.
Ancora più evidente è l’utilizzo dello swap. Prima di riciclare, ecco cosa vedo:
# free
total used free shared buff/cache available
Mem: 3904968 1888140 77308 679004 1939520 1147220
Swap: 4194288 1226344 2967944
e dopo:
# free
total used free shared buff/cache available
Mem: 3904968 1486412 1422380 640744 996176 1587908
Swap: 4194288 309892 3884396
A mio avviso, il riciclo ha liberato circa 1300M (differenza tra used+swap).
Non credo di aver mai visto la necessità di così tanto swap quando usavo unicorn: da qui il titolo.
Come dicevo, sarei interessato a vedere i numeri di altre istanze.
È normale che un processo pitchfork gestisca la maggior parte del carico: gli altri processi vengono selezionati solo quando il primo è occupato. È anche normale che la memoria cresca nel tempo. Sebbene dovrebbe raggiungere uno stato stazionario una volta che tutto, come le cache e ruby-JIT, è stato “scaldato”.
Ecco un grafico da uno dei nostri cluster di produzione, relativo a un periodo di 7 giorni. Questo traccia il singolo processo con il maggiore utilizzo di memoria. Le linee verdi tratteggiate indicano i deploy (cioè gli avvi freschi di pitchfork):
Quindi si può vedere che la memoria cresce dopo l’avvio iniziale, ma poi si stabilizza a poco meno di 1,4 GB. Questo cluster serve centinaia di siti, quindi forse non è il miglior paragone in termini di numeri… ma si spera che la visualizzazione della crescita sia utile.
Guardare i numeri RSS per processo non racconta la storia completa. Pitchfork è un “forking web server”. Quindi avvia il processo “mold” (modello) e poi tutti i worker vengono forkati da questo con uno schema di memoria copy-on-write. Quindi, anche se l’RSS potrebbe mostrare 500 MB per worker[0], circa 200 MB di quella quantità sono condivisi con il mold e tutti gli altri worker.
In un futuro non troppo lontano, speriamo di abilitare la funzione “reforking” di Pitchfork. Elimina periodicamente i worker e li riforca da un worker già scaldato, in modo che condividano la massima quantità di memoria possibile nel tempo. Tuttavia, è necessario un po’ di lavoro per assicurarsi che tutto il nostro codice sia compatibile con quel tipo di schema
Visualizzazione utile, grazie. Non direi che si sia stabilizzato, ma il tasso di crescita non è più così elevato come prima.
Il riforking periodico sembra un’ottima cosa da implementare: se puoi, ti prego di segnalarlo qui quando verrà rilasciato.
Puoi dirmi qualcosa sulle linee verdi? Mi interessa sapere quando (se mai) i pitchfork eseguono una raccolta dei rifiuti, cosa la causa e qual è l’effetto mentre è in corso.
Le linee verdi indicano i momenti in cui effettuiamo il deploy degli aggiornamenti. In pratica: ./launcher rebuild app.
Ruby (e JS, che eseguiamo all’interno dei processi Ruby tramite MiniRacer/v8) esegue continuamente la garbage collection durante l’esecuzione e in risposta ai segnali del sistema operativo. Pertanto, non credo che ci siano grandi vantaggi nel farlo manualmente.
Grazie. Sarei interessato a vedere come si evolvono le cose a lungo termine, il che non sarà evidente su un server che viene aggiornato relativamente spesso. Nel mio caso, ho avuto 20 giorni, poi ho scelto di usare pitchfork per riavviare, il che mi ha dato un’informazione ma ha anche azzerato il timer.