¿Puedo configurar mi sistema Linux para un almacenamiento en caché más agresivo del sistema de archivos?

119

No estoy preocupado por el uso de RAM (ya que tengo suficiente) ni por la pérdida de datos en caso de un apagado accidental (ya que mi energía está respaldada, el sistema es confiable y los datos no son críticos). Pero hago mucho procesamiento de archivos y podría usar un aumento de rendimiento.

Es por eso que me gustaría configurar el sistema para que use más RAM para el almacenamiento en caché de lectura y escritura del sistema de archivos, para captar archivos agresivamente (por ejemplo, leer todo el archivo al que accede una aplicación en caso de que el archivo sea de un tamaño razonable o al menos leer de antemano una gran parte de lo contrario) y eliminar los buffers de escritura con menos frecuencia. ¿Cómo lograr esto (puede ser posible)?

Uso los sistemas de archivos ext3 y ntfs (¡uso mucho ntfs!) Con XUbuntu 11.10 x86.

Ivan
fuente
66
Si tiene mucha RAM, le importa mucho el rendimiento y no se preocupa por la pérdida de datos, simplemente copie todos sus datos en un disco RAM y sirva desde allí, descartando todas las actualizaciones en caso de bloqueo / apagado. Si eso no funciona para usted, es posible que necesite calificar "suficiente" para RAM o cuán críticos no son los datos.
James Youngman
1
@Nils, la computadora es una computadora portátil, así que, creo, el controlador es bastante común.
Ivan
1
Una forma de mejorar mucho el rendimiento es omitir la durabilidad de los datos. Simplemente deshabilite la sincronización en el disco, incluso si algunas aplicaciones solicitan sincronización. Esto provocará la pérdida de datos si su dispositivo de almacenamiento sufre una pérdida de electricidad. Si quiere hacerlo de todos modos, simplemente ejecute sudo mount -o ro,nobarrier /path/to/mountpointo ajuste /etc/fstabpara incluir nobarriercualquier sistema de archivos que esté dispuesto a sacrificar para mejorar el rendimiento. Sin embargo, si su dispositivo de almacenamiento tiene una batería interna como la serie Intel 320 SSD, el uso nobarrierno causa pérdida de datos.
Mikko Rantalainen
1
El uso de nobarrier ya no se recomienda en Red Hat Enterprise Linux 6 ya que el impacto negativo en el rendimiento de las barreras de escritura es insignificante (aproximadamente el 3%). Los beneficios de las barreras de escritura generalmente superan los beneficios de rendimiento de deshabilitarlos. Además, la opción nobarrier nunca debe usarse en el almacenamiento configurado en máquinas virtuales. access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Linux/…
Ivailo Bardarov
1
Dos puntos: 1) Hay distribuciones de Linux basadas en Debian o Ubuntu, como Puppy Linux y AntiX Linux, y muchas otras que ponen todo el sistema operativo en particiones ramdisk en capas (es decir, AUFS o overlayfs) y lo administran de manera transparente. ¡Muy rapido! - 2) Descubrimos en el diseño del mundo real de un sistema muy grande que arrojarle más caché puede REDUCIR EL RENDIMIENTO. A medida que aumenta la velocidad de almacenamiento (es decir, SSD), disminuye el tamaño óptimo de caché necesario. Sin embargo, no hay forma de saber cuál es ese tamaño sin experimentar en su sistema particular. Si el aumento no funciona, intente reducirlo.
DocSalvager

Respuestas:

107

Mejorar el rendimiento de la memoria caché del disco en general es más que solo aumentar el tamaño de la memoria caché del sistema de archivos a menos que todo el sistema se ajuste a la RAM, en cuyo caso debe usar la unidad de RAM ( tmpfses bueno porque permite volver al disco si necesita la RAM en algún caso) para el almacenamiento en tiempo de ejecución (y quizás una secuencia de comandos initrd para copiar el sistema desde el almacenamiento a la unidad RAM al inicio).

No dijiste si tu dispositivo de almacenamiento es SSD o HDD. Esto es lo que he encontrado que funciona para mí (en mi caso sdaes un HDD montado en /homey sdbSSD montado en /).

Primero optimice la parte load-stuff-from-storage-to-cache:

Aquí está mi configuración para HDD (asegúrese de que AHCI + NCQ esté habilitado en BIOS si tiene conmutadores):

echo cfq > /sys/block/sda/queue/scheduler
echo 10000 > /sys/block/sda/queue/iosched/fifo_expire_async
echo 250 > /sys/block/sda/queue/iosched/fifo_expire_sync
echo 80 > /sys/block/sda/queue/iosched/slice_async
echo 1 > /sys/block/sda/queue/iosched/low_latency
echo 6 > /sys/block/sda/queue/iosched/quantum
echo 5 > /sys/block/sda/queue/iosched/slice_async_rq
echo 3 > /sys/block/sda/queue/iosched/slice_idle
echo 100 > /sys/block/sda/queue/iosched/slice_sync
hdparm -q -M 254 /dev/sda

Vale la pena señalar que el caso de HDD es alto fifo_expire_async(generalmente de escritura) y largo slice_syncpara permitir que un solo proceso obtenga un alto rendimiento (configurado slice_syncen un número más bajo si encuentra situaciones en las que varios procesos esperan algunos datos del disco en paralelo). El slice_idlesiempre es un compromiso para establecer unidades de disco duro, pero en algún lugar en el rango de 3-20 debería estar bien en función del uso del disco y firmware del disco. Prefiero apuntar a valores bajos, pero establecerlo demasiado bajo destruirá su rendimiento. La quantumconfiguración parece afectar mucho el rendimiento, pero trate de mantenerlo lo más bajo posible para mantener la latencia en un nivel razonable. Establecer quantumdemasiado bajo destruirá el rendimiento. Los valores en el rango 3-8 parecen funcionar bien con discos duros. La peor latencia de caso para una lectura es ( quantum* slice_sync) + ( slice_async_rq*slice_async) ms si he entendido el comportamiento del núcleo correctamente. El asíncrono es utilizado principalmente por las escrituras y, dado que está dispuesto a retrasar la escritura en el disco, configure ambas slice_async_rqy slice_asyncnúmeros muy bajos. Sin embargo, establecer slice_async_rqun valor demasiado bajo puede detener las lecturas porque las escrituras ya no se pueden retrasar después de las lecturas. Mi configuración intentará escribir datos en el disco como máximo después de 10 segundos después de que los datos se han pasado al núcleo, pero ya que se puede tolerar la pérdida de datos sobre la pérdida de potencia también fijados fifo_expire_asynca 3600000decir que 1 hora está bien por el retraso en el disco. Sin slice_asyncembargo, solo mantenga el nivel bajo, porque de lo contrario puede obtener una latencia de lectura alta.

El hdparmcomando es necesario para evitar que AAM elimine gran parte del rendimiento que permite AHCI + NCQ. Si su disco hace demasiado ruido, omita esto.

Aquí está mi configuración para SSD (serie Intel 320):

echo cfq > /sys/block/sdb/queue/scheduler
echo 1 > /sys/block/sdb/queue/iosched/back_seek_penalty
echo 10000 > /sys/block/sdb/queue/iosched/fifo_expire_async
echo 20 > /sys/block/sdb/queue/iosched/fifo_expire_sync
echo 1 > /sys/block/sdb/queue/iosched/low_latency
echo 6 > /sys/block/sdb/queue/iosched/quantum
echo 2 > /sys/block/sdb/queue/iosched/slice_async
echo 10 > /sys/block/sdb/queue/iosched/slice_async_rq
echo 1 > /sys/block/sdb/queue/iosched/slice_idle
echo 20 > /sys/block/sdb/queue/iosched/slice_sync

Aquí vale la pena señalar los valores bajos para diferentes configuraciones de corte. La configuración más importante para un SSD es la slice_idleque debe establecerse en 0-1. Establecerlo en cero mueve todas las decisiones de pedido a NCQ nativo, mientras que establecerlo en 1 permite que el núcleo ordene solicitudes (pero si el NCQ está activo, el hardware puede anular parcialmente el pedido del núcleo). Pruebe ambos valores para ver si puede ver la diferencia. Para la serie Intel 320, parece que el establecimiento slide_idlede 0da el mejor rendimiento, pero poniéndolo a 1da mejor latencia global (la más baja).

Para obtener más información sobre estos ajustables, consulte http://www.linux-mag.com/id/7572/ .

Ahora que hemos configurado el kernel para cargar cosas desde el disco a la memoria caché con un rendimiento razonable, es hora de ajustar el comportamiento de la memoria caché:

Según los puntos de referencia que he hecho, no me molestaría en configurar la lectura anticipada blockdeven absoluto. La configuración predeterminada del kernel está bien.

Configure el sistema para que prefiera intercambiar datos de archivos sobre el código de la aplicación (esto no importa si tiene suficiente RAM para mantener todo el sistema de archivos y todo el código de la aplicación y toda la memoria virtual asignada por las aplicaciones en la RAM). Esto reduce la latencia para intercambiar entre diferentes aplicaciones sobre la latencia para acceder a archivos grandes desde una sola aplicación:

echo 15 > /proc/sys/vm/swappiness

Si prefiere mantener las aplicaciones casi siempre en la RAM, puede configurar esto en 1. Si configura esto en cero, el núcleo no se intercambiará a menos que sea absolutamente necesario para evitar OOM. Si tenía memoria limitada y trabajaba con archivos grandes (p. Ej., Edición de video HD), entonces podría tener sentido establecer esto cerca de 100.

Hoy en día (2017) prefiero no tener ningún intercambio si tienes suficiente RAM. Al no tener intercambio, generalmente perderá 200-1000 MB de RAM en una máquina de escritorio de larga ejecución. Estoy dispuesto a sacrificar eso para evitar la latencia del peor de los casos (intercambiando el código de la aplicación cuando la RAM está llena). En la práctica, esto significa que prefiero OOM Killer a intercambiar. Si permite / necesita intercambiar, es posible que desee aumentar /proc/sys/vm/watermark_scale_factortambién para evitar cierta latencia. Sugeriría valores entre 100 y 500. Puede considerar esta configuración como el uso de CPU comercial para una latencia de intercambio más baja. El valor predeterminado es 10 y el máximo posible es 1000. Un valor más alto debería (de acuerdo con la documentación del kernel ) dar como resultado un mayor uso de la CPU para los kswapdprocesos y una menor latencia de intercambio general.

Luego, dígale al kernel que prefiera mantener la jerarquía de directorios en la memoria sobre el contenido del archivo en caso de que se necesite liberar algo de RAM (nuevamente, si todo encaja en la RAM, esta configuración no hace nada):

echo 10 > /proc/sys/vm/vfs_cache_pressure

Ajuste vfs_cache_pressureun valor bajo tiene sentido porque en la mayoría de los casos, el núcleo necesita conocer la estructura del directorio antes de poder usar el contenido del archivo de la memoria caché y vaciar la memoria caché del directorio demasiado pronto hará que la memoria caché del archivo sea casi inútil. Considere ir a 1 con esta configuración si tiene muchos archivos pequeños (mi sistema tiene alrededor de 150,000 fotos de 10 megapíxeles y cuenta como un sistema de "muchos archivos pequeños"). Nunca lo ajuste a cero o la estructura del directorio siempre se mantiene en la memoria, incluso si el sistema se está quedando sin memoria. Establecer esto en gran valor es sensato solo si tiene solo unos pocos archivos grandes que se vuelven a leer constantemente (nuevamente, la edición de video HD sin suficiente RAM sería un ejemplo). La documentación oficial del kernel dice que "

Excepción: si tiene una cantidad realmente masiva de archivos y directorios y rara vez toca / lee / enumera todos los archivos con una configuración vfs_cache_pressuresuperior a 100, puede ser sabio. Esto solo se aplica si no tiene suficiente RAM y no puede mantener toda la estructura de directorios en RAM y aún tiene suficiente RAM para la caché de archivos y procesos normales (por ejemplo, servidor de archivos de toda la empresa con mucho contenido de archivo). Si siente que necesita aumentar por vfs_cache_pressureencima de 100, está ejecutando sin suficiente RAM. El aumento vfs_cache_pressurepuede ayudar, pero la única solución real es obtener más RAM. Habiendo vfs_cache_pressureestablecido en alto número sacrifica el rendimiento promedio para tener un rendimiento más estable en general (es decir, se puede evitar muy mal comportamiento peor caso, pero tener que lidiar con un peor rendimiento global).

Finalmente, dígale al núcleo que use hasta el 99% de la RAM como caché para las escrituras e indique al núcleo que use hasta el 50% de la RAM antes de ralentizar el proceso que está escribiendo (el valor predeterminado dirty_background_ratioes 10). Advertencia: Yo personalmente no haría esto, pero usted afirmó tener suficiente RAM y está dispuesto a perder los datos.

echo 99 > /proc/sys/vm/dirty_ratio
echo 50 > /proc/sys/vm/dirty_background_ratio

Y diga que 1h de retraso de escritura está bien incluso para comenzar a escribir cosas en el disco (de nuevo, no haría esto):

echo 360000 > /proc/sys/vm/dirty_expire_centisecs
echo 360000 > /proc/sys/vm/dirty_writeback_centisecs

Si coloca todo eso /etc/rc.locale incluye el siguiente al final, todo estará en caché lo antes posible después del arranque (solo haga esto si su sistema de archivos realmente cabe en la RAM):

(nice find / -type f -and -not -path '/sys/*' -and -not -path '/proc/*' -print0 2>/dev/null | nice ionice -c 3 wc -l --files0-from - > /dev/null)&

O una alternativa un poco más simple que podría funcionar mejor (solo caché /homey /usr, solo haga esto si su /homey /usrrealmente encaja en RAM):

(nice find /home /usr -type f -print0 | nice ionice -c 3 wc -l --files0-from - > /dev/null)&
Mikko Rantalainen
fuente
3
¡Una respuesta mejor informada y en general mucho mejor que la aceptada! Este está subestimado ... Creo que la mayoría de la gente solo quiere instrucciones simples sin molestarse en entender lo que realmente hacen ...
Vladimir Panteleev
2
@Phpdevpad: Además, la pregunta decía "No estoy preocupado por el uso de RAM" [...] - No creo que ningún dispositivo Maemo califique.
Mikko Rantalainen
1
¿No es un noop o una fecha límite un mejor programador para SSD?
rep_movsd
1
@rep_movsd He estado usando solo unidades SSD de Intel, pero al menos estas unidades siguen siendo lo suficientemente lentas como para tener un mejor rendimiento general con programadores más inteligentes como CFQ. Supongo que si su unidad SSD puede manejar más de 100K IOPS aleatorios, usar noop o fecha límite tendría sentido incluso con una CPU rápida. Con "CPU rápida" me refiero a algo que tiene al menos múltiples núcleos de 3GHz disponibles solo para IO.
Mikko Rantalainen
1
También puede leer sobre estos sintonizables vm en los documentos del kernel vm .
joeytwiddle
16

En primer lugar, NO le recomiendo que continúe usando NTFS, ya que la implementación de NTFS en Linux sería un problema de rendimiento y seguridad en cualquier momento.

Hay varias cosas que puedes hacer:

  • use algunos fs más nuevos como ext4obtrfs
  • intenta cambiar tu planificador io, por ejemplo bfq
  • apagar el intercambio
  • usar algún precargador automático como preload
  • usar algo como systemdprecargar mientras arranca
  • ... y algo más

Quizás quieras probarlo :-)

Felix Yan
fuente
1
Ya me he alejado por completo de NTFS a ext4 una vez, dejando que la única partición NTFS sea la partición del sistema de Windows. Pero me causó muchos inconvenientes y volví a NTFS como la partición de datos principal (donde almaceno todos mis documentos, descargas, proyectos, código fuente, etc.). No dejo de repensar mi estructura de particiones y mi flujo de trabajo (para usar menos Windows), pero en este momento renunciar a NTFS no parece una opción realista.
Ivan
Si también tiene que usar sus datos dentro de Windows, NTFS puede ser la única opción. (muchas otras opciones disponibles si puede usar su Windows solo como una VM dentro de Linux)
Felix Yan
1
Un resumen de cuáles son estos supuestos problemas de NTFS habría sido útil.
underscore_d
2
NTFS en Linux es bastante aceptable, excepto por el rendimiento. Teniendo en cuenta que la pregunta se refería específicamente a mejorar el rendimiento del sistema de archivos, NTFS debería ser lo primero.
Mikko Rantalainen
Aunque btrfses un sistema de archivos recientemente diseñado, lo evitaría si se necesita rendimiento. Hemos estado ejecutando sistemas btrfsy ext4sistemas de archivos idénticos y ext4ganamos en el mundo real con un gran margen ( btrfsparece requerir aproximadamente 4 veces más tiempo de CPU que las ext4necesidades para el mismo nivel de rendimiento y provoca más operaciones de disco para un solo comando lógico). Dependiendo de la carga de trabajo, sugeriría ext4, jfso xfspara cualquier trabajo que requiera rendimiento.
Mikko Rantalainen
8

Leer por adelantado:

En sistemas de 32 bits:

blockdev --setra 8388607 /dev/sda

En sistemas de 64 bits:

blockdev --setra 4294967295 /dev/sda

Escribe detrás del caché:

echo 100 > /proc/sys/vm/dirty_ratio

Esto usará hasta el 100% de su memoria libre como caché de escritura.

O puede salir y usar tmpfs. Esto solo es relevante si tiene suficiente RAM. Pon esto en /etc/fstab. Reemplace 100G con la cantidad de RAM física.

tmpfs /mnt/tmpfs tmpfs size=100G,rw,nosuid,nodev 0 0

Entonces:

mkdir /mnt/tmpfs; mount -a

Luego use / mnt / tmpfs.

Ole Tange
fuente
55
¿Lectura de 3GB o 2TB? ¿De Verdad? ¿Sabes lo que hacen estas opciones?
Cobra_Fast
1
@Cobra_Fast ¿Sabes lo que significa? Realmente no tengo idea y ahora estoy interesado.
syss
3
@syss, la configuración de readahead se guarda como número de "bloques" de memoria, no bytes o bits. El tamaño de un bloque se determina en el momento de compilación del núcleo (dado que los bloques de lectura son bloques de memoria) o el tiempo de creación del sistema de archivos en algunos casos. Sin embargo, normalmente 1 bloque contiene 512 o 4096 bytes. Ver linux.die.net/man/8/blockdev
Cobra_Fast
6

Puede establecer el tamaño de lectura anticipada con blockdev --setra sectors /dev/sda1, donde sectores es el tamaño que desea en sectores de 512 bytes.

psusi
fuente
2

Mi configuración asesina es muy simple y muy efectiva:

echo "2000" > /proc/sys/vm/vfs_cache_pressure

La explicación de la documentación del kernel :

vfs_cache_pressure

Controla la tendencia del kernel a recuperar la memoria que se utiliza para almacenar en caché los objetos de directorio e inodo.

Con el valor predeterminado de vfs_cache_pressure = 100, el núcleo intentará reclamar dentries e inodes a una tasa "justa" con respecto a pagecache y swapcache reclaman. La disminución de vfs_cache_pressure hace que el kernel prefiera retener caché de dentry e inode. Cuando vfs_cache_pressure = 0, el núcleo nunca reclamará dentries e inodos debido a la presión de la memoria y esto puede conducir fácilmente a condiciones de falta de memoria. El aumento de vfs_cache_pressure más allá de 100 hace que el núcleo prefiera reclamar dentries e inodes.

vfs_cache_pressure en 2000 hace que la mayor parte de la computación ocurra en la RAM y las escrituras de disco muy tardías.

slm
fuente
44
Establecer vfs_cache_pressuredemasiado alto (lo consideraría 2000demasiado alto) provocará un acceso innecesario al disco, incluso para cosas simples como listas de directorios que deberían caber fácilmente en la memoria caché. ¿Cuánta RAM tiene y qué está haciendo con el sistema? Como escribí en mi respuesta, usar un valor alto para esta configuración tiene sentido, por ejemplo, para la edición de video HD con RAM limitada.
Mikko Rantalainen
2
Tenga en cuenta que la documentación a la que se hace referencia continúa: "El aumento de vfs_cache_pressure significativamente más allá de 100 puede tener un impacto negativo en el rendimiento. El código de recuperación necesita tomar varios bloqueos para encontrar directorios y objetos de inodo liberables. Con vfs_cache_pressure = 1000, buscará diez veces más objetos liberables que allí son."
Mikko Rantalainen
1

No está relacionado con el almacenamiento en caché de escritura, pero está relacionado con las escrituras:

  • Para un sistema ext4, puede deshabilitar el diario por completo

    Esto reducirá el número de escrituras de disco para cualquier actualización en particular, pero puede dejar que el sistema de archivos tenga un estado inconsistente después de un apagado inesperado, que requiera un fsck o algo peor.

Para evitar que las lecturas de disco activen escrituras de disco:

  • Montar con el relatime o la noatime opción

    Cuando lee un archivo, los metadatos del "último tiempo de acceso" para ese archivo generalmente se actualizan. La noatimeopción deshabilitará ese comportamiento. Esto reduce las escrituras de disco innecesarias, pero ya no tendrá esos metadatos. Algunas distribuciones (por ejemplo, Manjaro) han adoptado esto como el valor predeterminado en todas las particiones (probablemente para aumentar la vida útil de los SSD de modelos anteriores).

    relatimeactualiza el tiempo de acceso con menos frecuencia, de acuerdo con las heurísticas que ayudan a admitir aplicaciones que utilizan el atime. Este es el valor predeterminado en Red Hat Enterprise Linux.

Otras opciones:

  • En los comentarios anteriores, Mikko compartió la posibilidad de montar con la opción de nobarrier . Pero Ivailo citó a RedHat que advierte contra eso. ¿Qué tanto quieres ese 3% extra?
joeytwiddle
fuente