GNU/Linux >> Tutoriales Linux >  >> Linux

¿Por qué mi sistema Linux tartamudea a menos que descarte cachés continuamente?

Parece que ya ha probado muchas de las cosas que le habría sugerido al principio (ajustar la configuración de intercambio, cambiar los programadores de E/S, etc.).

Aparte de lo que ya ha intentado cambiar, le sugiero que busque cambiar los valores predeterminados algo inertes para el comportamiento de reescritura de VM. Esto es administrado por los siguientes seis valores sysctl:

  • vm.dirty_ratio :controla la cantidad de escrituras que deben estar pendientes para la reescritura antes de que se active. Maneja la reescritura en primer plano (por proceso) y se expresa como un porcentaje entero de RAM. El valor predeterminado es el 10 % de RAM
  • vm.dirty_background_ratio :controla la cantidad de escrituras que deben estar pendientes para la reescritura antes de que se active. Maneja la reescritura en segundo plano (en todo el sistema) y se expresa como un porcentaje entero de RAM. El valor predeterminado es el 20 % de RAM
  • vm.dirty_bytes :Igual que vm.dirty_ratio , excepto que se exprese como un número total de bytes. O esto o vm.dirty_ratio se utilizará, cualquiera que haya sido escrito para durar.
  • vm.dirty_background_bytes :Igual que vm.dirty_background_ratio , excepto que se exprese como un número total de bytes. O esto o vm.dirty_background_ratio se utilizará, cualquiera que haya sido escrito para durar.
  • vm.dirty_expire_centisecs :Cuántas centésimas de segundo deben pasar antes de que comience la reescritura pendiente cuando los cuatro valores de sysctl anteriores aún no la activarían. El valor predeterminado es 100 (un segundo).
  • vm.dirty_writeback_centisecs :Con qué frecuencia (en centésimas de segundo) el kernel evaluará las páginas sucias para reescritura. El valor predeterminado es 10 (una décima de segundo).

Entonces, con los valores predeterminados, cada décima de segundo, el núcleo hará lo siguiente:

  • Escriba las páginas modificadas en el almacenamiento persistente si se modificaron por última vez hace más de un segundo.
  • Escribe todas las páginas modificadas de un proceso si la cantidad total de memoria modificada que no se ha escrito supera el 10 % de la RAM.
  • Escribe todas las páginas modificadas del sistema si la cantidad total de memoria modificada que no se ha escrito supera el 20 % de la RAM.

Por lo tanto, debería ser bastante fácil ver por qué los valores predeterminados pueden causarle problemas, ya que su sistema podría estar intentando escribir hasta 4 gigabytes de datos al almacenamiento persistente cada décimo de un segundo.

El consenso general en estos días es ajustar vm.dirty_ratio para ser el 1% de RAM, y vm.dirty_background_ratio sea ​​del 2 %, lo que para sistemas con menos de 64 GB de RAM da como resultado un comportamiento equivalente al que se pretendía originalmente.

Algunas otras cosas para investigar:

  • Intenta aumentar el vm.vfs_cache_pressure sysctl un poco. Esto controla la agresividad con la que el kernel reclama memoria del caché del sistema de archivos cuando necesita RAM. El valor predeterminado es 100, no lo baje a menos de 50 (usted lo hará obtenga un comportamiento realmente malo si va por debajo de 50, incluidas las condiciones OOM), y no lo eleve mucho más de 200 (mucho más alto, y el kernel perderá el tiempo tratando de recuperar la memoria que realmente no puede). Descubrí que aumentarlo a 150 en realidad mejora visiblemente la capacidad de respuesta si tiene un almacenamiento razonablemente rápido.
  • Intente cambiar el modo de sobreasignación de memoria. Esto se puede hacer alterando el valor de vm.overcommit_memory sist. De forma predeterminada, el kernel utilizará un enfoque heurístico para intentar predecir cuánta RAM puede permitirse comprometer. Establecer esto en 1 desactiva la heurística y le dice al kernel que actúe como si tuviera memoria infinita. Establecer esto en 2 le dice al kernel que no comprometa más memoria que la cantidad total de espacio de intercambio en el sistema más un porcentaje de RAM real (controlado por vm.overcommit_ratio ).
  • Intenta ajustar el vm.page-cluster sist. Esto controla cuántas páginas se intercambian dentro o fuera a la vez (es un valor logarítmico de base 2, por lo que el valor predeterminado de 3 se traduce en 8 páginas). Si realmente está intercambiando, esto puede ayudar a mejorar el rendimiento del intercambio de páginas de entrada y salida.

¡Se ha encontrado el problema!

Resulta que es un problema de rendimiento en el recuperador de memoria de Linux cuando hay una gran cantidad de contenedores/grupos de memoria. (Descargo de responsabilidad:mi explicación puede ser defectuosa, no soy un desarrollador de kernel). El problema se solucionó en 4.19-rc1+ en este conjunto de parches:

Este conjunto de parches soluciona el problema de la lentitud de la reducción_slab() en las máquinas que tienen muchos reductores y grupos de memoria (es decir, con muchos contenedores). El problema es que la complejidad de shrink_slab() es O(n^2) y crece demasiado rápido con el crecimiento del número de contenedores.

Tengamos 200 contenedores, y cada contenedor tiene 10 montajes y 10cgroups. Todas las tareas de contenedor están aisladas y no tocan los montajes de contenedores extranjeros.

En caso de recuperación global, una tarea tiene que iterar en todos los memcgs y llamar a todos los reductores conscientes de memcg para todos ellos. Esto significa que la tarea tiene que visitar 200 * 10 =2000 reductores por cada memcg, y dado que hay 2000 memcg, el total de llamadas de do_shrink_slab() es 2000 * 2000 =4000000.

Mi sistema se vio particularmente afectado, ya que ejecuto una buena cantidad de contenedores, lo que probablemente fue lo que provocó que apareciera el problema.

Mis pasos de solución de problemas, en caso de que sean útiles para cualquier persona que enfrente problemas similares:

  1. Aviso kswapd0 usando una tonelada de CPU cuando mi computadora tartamudea
  2. Intente detener los contenedores de Docker y vuelva a llenar la memoria → ¡la computadora no tartamudea!
  3. Ejecutar ftrace (siguiendo la magnífica explicación del blog de Julia Evan) para obtener un seguimiento, ver que kswapd0 tiende a atascarse en shrink_slab , super_cache_count y list_lru_count_one .
  4. Google shrink_slab lru slow , encuentra el conjunto de parches!
  5. Cambie a Linux 4.19-rc3 y verifique que el problema esté solucionado.

Linux
  1. Linux:¿por qué se tarda tanto en detectar una memoria USB?

  2. 12 razones por las que todos los administradores de sistemas Linux deberían ser perezosos

  3. ¿Por qué el preprocesador de C interpreta la palabra linux como la constante 1?

  4. ¿Por qué Ctrl + V no se pega en Bash (shell de Linux)?

  5. ¿Por qué esta expresión regular no funciona en Linux?

Linux – ¿Por qué Locale Es_mx funciona pero no Es?

¿El problema del rebaño atronador existe más en Linux?

¿Por qué popen() invoca un shell para ejecutar un proceso?

¿Por qué Linux es similar a Unix si su núcleo es monolítico?

¿Linux suele registrar datos de temperatura del sistema?

¿Por qué un enrutador de hardware funciona mejor que un enrutador Linux con mejores especificaciones (RAM y CPU)?