Restringir el tamaño de la memoria caché del búfer en Linux

25

¿Hay alguna forma de decirle al kernel de Linux que solo use un cierto porcentaje de memoria para la memoria caché del búfer? Sé que /proc/sys/vm/drop_cachesse puede usar para borrar el caché temporalmente, pero ¿hay alguna configuración permanente que evite que crezca a más del 50% de la memoria principal?

La razón por la que quiero hacer esto es que tengo un servidor que ejecuta un OSD Ceph que constantemente sirve datos del disco y logra usar toda la memoria física como caché de búfer en unas pocas horas. Al mismo tiempo, necesito ejecutar aplicaciones que asignarán una gran cantidad (varios 10s de GB) de memoria física. Contrariamente a la creencia popular (vea el consejo dado en casi todas las preguntas relacionadas con el caché del búfer), la liberación automática de la memoria al descartar las entradas de caché limpias no es instantánea: iniciar mi aplicación puede tomar hasta un minuto cuando el caché del búfer está lleno ( *), mientras que después de borrar el caché (usando echo 3 > /proc/sys/vm/drop_caches), la misma aplicación se inicia casi instantáneamente.

(*) Durante este minuto de tiempo de inicio, la aplicación falla en la nueva memoria pero pasa el 100% de su tiempo en el núcleo, según Vtune en una función llamada pageblock_pfn_to_page. Esta función parece estar relacionada con la compactación de memoria necesaria para encontrar páginas enormes, lo que me lleva a creer que en realidad la fragmentación es el problema.

Wim
fuente
1
Hay algo llamado niveles de caché. ceph osd pool set {cachepool} hit_set_count 1 ceph osd pool set {cachepool} hit_set_period 3600 ceph osd pool set {cachepool} target_max_bytes 1000000000000 como ejemplo, ver. docs.ceph.com/docs/master/rados/operations/cache-tiering
Michael D.
2
Dado que este problema aparentemente solo afecta el inicio de las aplicaciones de uso intensivo de memoria, tal vez podría iniciar aplicaciones a través de un script que borra el caché antes de iniciarlas realmente. Tal vez esto los inicie más rápido mientras deja la administración de caché al kernel mientras se están ejecutando.
Thawn

Respuestas:

14

Si no desea un límite absoluto, pero simplemente presiona el núcleo para que elimine los búferes más rápido, debe mirar vm.vfs_cache_pressure

Esta variable controla la tendencia del núcleo a recuperar la memoria que se utiliza para el almacenamiento en caché de cachés VFS, en comparación con el almacenamiento en caché y el intercambio de páginas. Aumentar este valor aumenta la velocidad a la que se recuperan las memorias caché VFS.

El rango va de 0 a 200. Muévelo hacia 200 para una mayor presión. El valor predeterminado se establece en 100. También puede analizar el uso de su memoria con el slabtopcomando. En su caso, los valores dentryy *_inode_cachedeben ser altos.

Si desea un límite absoluto, debe buscarlo cgroups. Coloque el servidor Ceph OSD dentro de un cgroup y limite la memoria máxima que puede usar configurando el memory.limit_in_bytesparámetro para el cgroup.

memory.memsw.limit_in_bytesestablece la cantidad máxima para la suma de memoria y uso de intercambio. Si no se especifican unidades, el valor se interpreta como bytes. Sin embargo, es posible usar sufijos para representar unidades más grandes: k o K para kilobytes, m o M para Megabytes y g o G para Gigabytes.

Referencias

[1] - GlusterFS Linux Kernel Tuning

[2] - Guía de gestión de recursos RHEL 6

NOLFXceptMe
fuente
1
Un cgroup con limit_in_bytesset parece hacerlo. ¡Gracias!
Wim
44
Creo que vfs_cache_pressuresolo borra cachés de dentry e inodo, y no tiene nada que ver con el caché de búfer.
kawing-chiu
Aumentar vfs_cache_pressurearriba 100puede ayudar en caso de que no tenga suficiente RAM para su carga de trabajo. Reducirá el uso de RAM, pero en general provocará un rendimiento de E / S más pobre.
Mikko Rantalainen
3

No sé acerca de A%, pero puede establecer un límite de tiempo para que caiga después de x cantidad de minutos.

Primero en una terminal

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

Para borrar cachés actuales.

Haga que cron-job presione Alt-F2, escriba gksudo gedit /etc/crontab, luego agregue esta línea cerca de la parte inferior.

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

Esto limpia cada 15 minutos. Puede configurarlo en 1 o 5 minutos si realmente lo desea cambiando el primer parámetro a * o * / 5 en lugar de * / 15

Para ver su RAM libre, excepto el caché:

free -m | sed -n -e '3p' | grep -Po "\d+$
DnrDevil
fuente
Siento aquí un poco de redundancia. Hasta donde yo sé, 3 > drop_cachesincluye el comportamiento desync
andras.tim
1
@ andras.tim no - sync escribe páginas sucias en el disco, 3 en drop_caches solo reclama / libera memoria utilizada por páginas limpias y otras memorias caché. no tiene que ejecutar la sincronización, pero si lo hace, más memoria estará limpia en lugar de sucia y se liberará más memoria al soltar cachés
Daniel S. Sterling
2

Creo que su presentimiento al final de su pregunta está en el camino correcto. Sospecho que A, la asignación de memoria compatible con NUMA migra páginas entre CPU o B, más probablemente, el código de desfragmentación de páginas enormes transparentes que intentan encontrar regiones contiguas y alineadas.

Se han identificado páginas enormes y páginas enormes transparentes para ambas mejoras de rendimiento marcadas en ciertas cargas de trabajo y responsables de consumir enormes cantidades de tiempo de CPU sin proporcionar muchos beneficios.

Sería útil saber qué kernel está ejecutando, el contenido de / proc / meminfo (o al menos los valores HugePages_ *) y, si es posible, más del callgraph de vtune profiler haciendo referencia a pageblock_pfn_to_page ().

Además, si puede darse el gusto, intente deshabilitar la desfragmentación de página enorme con:

echo 'nunca'> / sys / kernel / mm / transparent_hugepage / defrag

(puede ser esto en su lugar, dependiendo de su núcleo :)

echo 'nunca'> / sys / kernel / mm / redhat_transparent_hugepage / defrag

Por último, ¿esta aplicación está usando muchas decenas de gigas de ram algo que escribiste? ¿Que lenguaje?

Como usó el término "falla en las páginas de memoria", supongo que está familiarizado con el diseño operativo y la memoria virtual. Me cuesta imaginar una situación / aplicación que estaría fallando de manera tan agresiva que no se lee en muchas E / S, casi siempre desde el caché del búfer que estás tratando de limitar.

(Si tiene curiosidad, consulte los indicadores mmap (2) como MAP_ANONYMOUS y MAP_POPULATE y mincore (2) que se pueden usar para ver qué páginas virtuales tienen una página física asignada).

¡Buena suerte!

Etherfish
fuente
2

Si Ceph OSD es un proceso separado, puede usar cgroups para controlar los recursos utilizados por el proceso:

Cree un cgroup llamado como group1 con un límite de memoria (de 50 GB, por ejemplo, se admiten otros límites como CPU, por ejemplo, también se menciona CPU):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

Luego, si su aplicación ya se está ejecutando, traiga la aplicación a este cgroup:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

O ejecute su aplicación dentro de este cgroup:

cgexec -g memory,cpu:group1 your_app_name
Alexei Martianov
fuente
0

tuned es un demonio de ajuste dinámico del sistema adaptativo que ajusta la configuración del sistema dinámicamente según el uso.

 $ man tuned

Consulte la documentación relacionada y los archivos de configuración.

 /etc/tuned
 /etc/tuned/*.conf
 /usr/share/doc/tuned-2.4.1
 /usr/share/doc/tuned-2.4.1/TIPS.txt

This parameter may be useful for you.

** Set flushing to once per 5 minutes
** echo "3000" > /proc/sys/vm/dirty_writeback_centisecs

Información adicional

El comando de sincronización vacía el búfer, es decir, obliga a que todos los datos no escritos se escriban en el disco, y se puede usar cuando se quiere estar seguro de que todo está escrito de forma segura. En los sistemas UNIX tradicionales, hay un programa llamado actualización que se ejecuta en segundo plano que hace una sincronización cada 30 segundos, por lo que generalmente no es necesario usar la sincronización. Linux tiene un demonio adicional, bdflush , que realiza una sincronización más imperfecta con mayor frecuencia para evitar la congelación repentina debido a la E / S de disco pesado que a veces causa la sincronización .

En Linux, bdflush se inicia por actualización. Por lo general, no hay razón para preocuparse por eso, pero si bdflush muere por alguna razón, el núcleo lo advertirá y debe comenzarlo a mano ( / sbin / update ).

Ijaz Ahmad Khan
fuente
1
¿No es esto solo para entradas sucias? No creo que ese sea el problema en mi sistema, ya que todos están limpios: la demora no está en escribir páginas sucias sino en desfragmentar el espacio que queda al eliminar las limpias.
Wim
Sí, esto es para páginas sucias, creo que también puede solucionar otros problemas de rendimiento configurando sintonizado en modo dinámico.
Ijaz Ahmad Khan
"Desde Linux 2.6, la llamada al sistema [bdflush] está en desuso y no hace nada. Es probable que desaparezca por completo en una versión futura del kernel. Hoy en día, la tarea realizada por bdflush () es manejada por el hilo pdflush del kernel". man7.org/linux/man-pages/man2/bdflush.2.html
sourcejedi