Limitación del número de unicorns, uso de memoria y swapping

Estoy ejecutando un servidor pequeño (1G de RAM) y también un sitio pequeño (instalación oficial de Discourse que ha estado funcionando durante casi 8 años). Hay más intercambio de disco del que me gustaría, así que comencé a analizar el uso de memoria.

Noté que hace un tiempo había establecido el número de unicornios en solo 2 para limitar el uso de memoria (y reducir el intercambio). Ejecutando la versión de Discourse 3.1.0

Sin embargo, cuando ejecuto htop, veo 20 unicornios en ejecución (10 para el trabajador 0 y 10 para el trabajador 1).

¿Qué me estoy perdiendo aquí? ¿Por qué tengo 20 unicornios en ejecución mientras que app.yml indica 2?

Además, ¿hay alguna otra forma de reducir el uso de memoria (por ejemplo, si reduzco db_shared_buffers a 128MB, ¿hay algún efecto secundario?) ¿Puedo reducir el uso de memoria de sidekiq?

Esto es vmstat 5 5
image

free -h
image

1 me gusta

Sospecho que htop está mostrando hilos en lugar de procesos. De todos modos, veo lo mismo en htop que tú, pero solo dos unicornios según

ps uaxf|egrep unicorn.?worker

Además, mi free es como el tuyo:

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

Por cierto, ver algo de swap en uso no es un problema en sí mismo. Es el swapping (paginación) real lo que importaría. Prueba vmstat 5 5 y mira las columnas si y 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

Preferiría no ver nada por encima de 1000, pero no estoy demasiado preocupado. Una segunda ejecución mostró una imagen mucho más tranquila:

# 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

Editar: la tecla H en htop cambiará de hilos a procesos:

  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

Editar: establecí db_shared_buffers: "128MB" muy temprano y no he visto ningún problema con eso.

1 me gusta

Gracias, muy útil. ¿Cuál es la desventaja de pasar a un solo trabajador unicorn? ¿Mejoraría o empeoraría el tiempo de respuesta (¿un solo trabajador unicorn está limitado a una conexión entrante, es decir, dos trabajadores harían que una sola conexión entrante se procesara más rápido?), asumiendo que tengo solo unas pocas conexiones por minuto?

Cuando navego por el sitio web, esto es lo que muestra vmstat 5 5, ¿alguna sugerencia sobre cómo reducir el intercambio (he establecido la tendencia de intercambio en 10)?

EDITAR: ¿Hay alguna manera de reducir el uso de memoria de sidekiq sin afectar el rendimiento?

Ciertamente parece que tu sitio sería más rápido si tuvieras más RAM. Pero si el tiempo de respuesta no es un problema, no hay problema. Simplemente mira tu ecuación personal de costo/beneficio.

Podría interesarte leer La configuración de despliegue de Discourse de MKJ. Hay un par de ajustes del kernel a nivel de sistema que son una buena idea. No sé si harán alguna diferencia.

No lo sé, pero creo que cada unicornio puede manejar una solicitud. Así que si solo tienes un unicornio y suficiente tráfico para que llegue una segunda solicitud antes de que la primera termine, esa segunda solicitud tendrá que esperar. Puedes ver en mi salida de htop que un unicornio ha acumulado 10 veces más tiempo de CPU que el otro. Yo interpretaría eso como que mi foro necesita solo un unicornio el 90% del tiempo, y el 10% del tiempo ese segundo unicornio es útil. No siento ninguna necesidad de añadir un tercero, y podría no ser gran cosa para los miembros de mi foro si me quedara con uno. Pero no veo ninguna razón para no hacerlo: puede usar memoria, pero si está inactivo, se intercambiará. No es gran cosa: deja que el sistema de memoria virtual se encargue de ello.

Editar: Nunca he ajustado la agresividad del intercambio (swappiness). Parece estar en 60. Un intercambio más agresivo podría ser útil si libera más RAM para los búferes de E/S. No lo sé.

2 Me gusta

Si cambio db_shared_buffers y UNICORN_WORKERS, ¿hay alguna forma de reiniciar sin reconstruir con ./launcher rebuild app?