Limitazione del numero di unicorns, utilizzo della memoria e swapping

Sto gestendo un piccolo server (1G di RAM) e anche un piccolo sito (installazione ufficiale di Discourse in esecuzione da quasi 8 anni). C’è più swapping su disco di quanto vorrei, quindi ho iniziato a esaminare l’utilizzo della memoria.

Ho notato che tempo fa avevo impostato il numero di unicorni a soli 2 per limitare l’utilizzo della memoria (e ridurre lo swapping). Sto eseguendo la versione di Discourse 3.1.0

Tuttavia, quando eseguo htop vedo 20 unicorni in esecuzione (10 per worker 0 e 10 per worker 1).

Cosa mi sfugge? Perché ho 20 unicorni in esecuzione mentre app.yml ne indica 2?

Ci sono altri modi per ridurre l’utilizzo della memoria (ad esempio, se riduco db_shared_buffers a 128 MB, ci sono effetti collaterali?) Posso ridurre l’utilizzo della memoria di sidekiq?

Questo è vmstat 5 5
image

free -h
image

1 Mi Piace

Sospetto che htop stia mostrando i thread anziché i processi - comunque, vedo la stessa cosa su htop come te, ma solo due unicorn secondo

ps uaxf|egrep unicorn.?worker

Anche il mio free è come il tuo:

# free -h
              total        used        free      shared  buff/cache   available
Mem:           985M        782M         61M         60M        141M         32M
Swap:          2.0G        992M        1.0G

A proposito, vedere dello swap in uso non è di per sé un problema. È lo swapping effettivo (paging) che conta. Prova vmstat 5 5 e guarda le colonne si e so.

# 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 1041832  63176   5716 127408  367  325   601   393    8   10  2  1 95  2  0
 0  0 1041576  60976   5724 127408  399    0   399    21  212  653  1  1 96  2  0
 0  0 1043544  77036   2296 120688  807  803   807   837  404 1144  1  2 94  3  0
 0  0 1043288  65040   3704 129476  254    0  2292     5  255  780  1  1 96  2  0
 0  0 1048736  81936   2916 119016  762 1499   919  1565  470 1171  3  2 90  5  0

Preferirei non vedere nulla sopra 1000 ma non sono troppo preoccupato. Una seconda esecuzione ha mostrato un quadro molto più calmo:

# 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 1048452  82712   2532 120848  367  325   601   393    8   10  2  1 95  2  0
 0  0 1047684  74552   2548 124816  285    0  1049    10  230  655  2  1 95  2  0
 0  0 1046660  66556   3692 129008  196    0  1261    16  219  672  1  1 96  2  0
 1  0 1046404  65812   3700 129284   54    0    97    13  137  364  1  0 98  0  0
 0  0 1046148  65280   3700 129288   50    0    50     3  132  344  1  0 98  0  0

Modifica: il tasto H in htop passerà dai thread ai processi:

  CPU[                                                       0.0%]   Tasks: 66; 1 running
  Mem[||||||||||||||||||||||||||||||||||||||||||||||||||824M/985M]   Load average: 0.19 0.12 0.05
  Swp[||||||||||||||||||||||||||||||                  1015M/2.00G]   Uptime: 52 days, 00:50:42

  PID USER      PRI  NI  VIRT   RES   SHR S CPU% MEM%   TIME+  Command
13246 1000       20   0  966M  362M  6448 S  0.0 36.8 51:01.52 unicorn worker[0] -E production -c config/unicorn.conf.rb
13237 1000       25   5 1004M  194M  3780 S  0.0 19.8 22:38.19 sidekiq 6.5.9 discourse [0 of 5 busy]
13258 1000       20   0  919M 70176  3632 S  0.0  7.0  5:02.87 unicorn worker[1] -E production -c config/unicorn.conf.rb
12412 systemd-r  20   0  212M 60928 56916 S  0.0  6.0  0:00.23 postgres: 13/main: discourse discourse [local] idle
12818 systemd-r  20   0  212M 39228 34868 S  0.0  3.9  0:00.07 postgres: 13/main: discourse discourse [local] idle
12719 systemd-r  20   0  211M 28400 25336 S  0.0  2.8  0:00.03 postgres: 13/main: discourse discourse [local] idle
13117 1000       20   0  541M 13768  2048 S  0.0  1.4  1:08.11 unicorn master -E production -c config/unicorn.conf.rb

Modifica: ho impostato db_shared_buffers: "128MB" molto presto e non ho riscontrato problemi.

1 Mi Piace

Grazie, molto utile. Qual è lo svantaggio di passare a un solo worker unicorn? Migliorerebbe o peggiorerebbe il tempo di risposta (un solo worker unicorn è limitato a una connessione in entrata, ovvero 2 worker renderebbero una singola connessione in entrata più veloce da elaborare?), supponendo che abbia solo poche connessioni al minuto?

Quando navigo sul sito web, ecco come appare vmstat 5 5, qualche suggerimento su come ridurre lo swapping (ho impostato la swappiness a 10)?

EDIT: C’è un modo per ridurre l’utilizzo della memoria di sidekiq senza influire sulle prestazioni?

Sembra certamente che il tuo sito sarebbe più veloce se avessi più RAM. Ma se il tempo di risposta non è un problema, non c’è problema. Guarda solo la tua equazione personale di costo/beneficio.

Potresti essere interessato a leggere MKJ’s Opinionated Discourse Deployment Configuration. Ci sono un paio di modifiche al kernel a livello di sistema che sono una buona idea. Non so se faranno la differenza o meno.

Non lo so, ma penso che ogni unicorn possa gestire una richiesta. Quindi, se hai solo un unicorn e traffico sufficiente per una seconda richiesta prima che la prima sia completata, quella seconda richiesta dovrà aspettare. Puoi vedere dall’output del mio htop che un unicorn ha accumulato 10 volte il tempo CPU dell’altro. Lo interpreterei come il fatto che il mio forum ha bisogno di un solo unicorn per il 90% del tempo, e il secondo unicorn è utile per il 10% del tempo. Non sento il bisogno di aggiungerne un terzo, e potrebbe non essere un grosso problema per i membri del mio forum se ne avessi solo uno. Ma non vedo motivo per farlo: potrebbe usare memoria, ma se è inattivo verrà scambiato. Nessun grosso problema: lascia che il sistema di memoria virtuale se ne occupi.

Modifica: non ho mai modificato swappiness. Sembra essere al 60. Uno swapping più aggressivo potrebbe essere utile se libera più RAM per i buffer di I/O. Non lo so.

2 Mi Piace

Se modifico db_shared_buffers e UNICORN_WORKERS è possibile riavviare senza ricostruire tramite ./launcher rebuild app?