¿Cuándo debo utilizar /dev/shm/ y cuándo /tmp/?
¿Cuándo debo usar /dev/shm/
y cuándo debo usar /tmp/
? ¿Puedo confiar siempre en que ambos estén presentes en Unices?
¿Cuándo debo usar /dev/shm/
y cuándo debo usar /tmp/
? ¿Puedo confiar siempre en que ambos estén presentes en Unices?
En orden descendente de probabilidad tmpfs
:
┌───────────┬──────────────┬────────────────┐
│ /dev/shm │ always tmpfs │ Linux specific │
├───────────┼──────────────┼────────────────┤
│ /tmp │ can be tmpfs │ FHS 1.0 │
├───────────┼──────────────┼────────────────┤
│ /var/tmp │ never tmpfs │ FHS 1.0 │
└───────────┴──────────────┴────────────────┘
Dado que está preguntando por un punto de montaje tmpfs específico de Linux frente a un directorio definido de forma portátil que puede ser tmpfs (dependiendo de su administrador de sistemas y de lo que esté por defecto en su distro), su pregunta tiene dos aspectos, que otras respuestas han enfatizado de forma diferente:
Edición conservadora (mezcla de convenciones de FHS y uso común):
/tmp
. /var/tmp
para datos grandes que no caben fácilmente en la ram. /var/tmp
para datos que es beneficioso mantener a través de los reinicios (como un caché). /dev/shm
como efecto secundario de la llamada a shm_open()
. El público objetivo son los buffers limitados que se sobreescriben infinitamente. Así que esto es para archivos de larga duración cuyo contenido es volátil y no es terriblemente grande. mktemp
respeta la variable de entorno TMPDIR
. Edición pragmática:
Use /dev/shm
cuando sea importante usar tmpfs, /var/tmp
cuando sea importante no hacerlo, si no, /tmp
.
fsync
es un no-op en tmpfs. Esta llamada al sistema es el enemigo número uno del rendimiento (IO) (y de la longevidad de la memoria flash, si se preocupa por eso), aunque si se encuentra usando tmpfs (o eatmydata ) sólo para vencer a fsync, entonces usted (o algún otro desarrollador en la cadena) está haciendo algo mal. Significa que las transacciones hacia el dispositivo de almacenamiento son innecesariamente finas para su propósito - usted está claramente dispuesto a saltarse algunos puntos de guardado para el rendimiento, ya que ahora ha llegado al extremo de sabotearlos todos - raramente el mejor compromiso. Además, es aquí, en el terreno del rendimiento de las transacciones, donde se encuentran algunos de los mayores beneficios de tener un SSD: cualquier SSD decente va a tener un rendimiento fuera de este mundo en comparación con lo que puede soportar un disco giratorio (7200 rpm = 120 Hz, si no hay nada más que acceda a él), por no hablar de las tarjetas de memoria flash, que varían mucho en esta métrica (sobre todo porque es un compromiso con el rendimiento secuencial, que es por lo que se clasifican, por ejemplo, la clasificación de clase de la tarjeta SD). Así que tened cuidado, desarrolladores con SSDs rapidísimas, de no forzar a vuestros usuarios en este caso de uso.
¿Quieres oír una historia ridícula? Mi primera lección de fsync
: Tenía un trabajo que implicaba la “actualización” rutinaria de un montón de bases de datos Sqlite (mantenidas como casos de prueba) a un formato actual siempre cambiante. El marco de “actualización” ejecutaba un montón de scripts, haciendo al menos una transacción cada uno, para actualizar una base de datos. Por supuesto, actualicé mis bases de datos en paralelo (8 en paralelo, ya que fui bendecido con una poderosa CPU de 8 núcleos). Pero, como descubrí, no hubo ningún aumento de velocidad de paralelización en absoluto (más bien un ligero hit) porque el proceso estaba completamente ligado a la IO. Curiosamente, envolviendo el marco de actualización en un script que copiaba cada base de datos a /dev/shm
, la actualizaba allí, y la copiaba de nuevo al disco era como 100 veces más rápido (aún con 8 en paralelo). Como extra, el PC era usable también, mientras se actualizaban las bases de datos.
El uso apropiado de tmpfs es para evitar la escritura innecesaria de datos volátiles. Efectivamente deshabilitando el writeback, como poner /proc/sys/vm/dirty_writeback_centisecs
a infinito en un sistema de archivos regular.
Esto tiene muy poco que ver con el rendimiento, y fallar esto es una preocupación mucho menor que abusar de fsync: El tiempo de espera de escritura determina la pereza con la que se actualiza el contenido del disco después del contenido de la pagecache, y el valor por defecto de 5 segundos es mucho tiempo para un ordenador - una aplicación puede sobrescribir un archivo con la frecuencia que quiera, en la pagecache, pero el contenido en el disco sólo se actualiza aproximadamente una vez cada 5 segundos. A menos que la aplicación lo fuerce con fsync, es decir. Piensa en cuántas veces puede salir un archivo pequeño en este tiempo, y verás por qué fsync cada uno sería un problema mucho mayor.
fsync
por supuesto. Guardando datos fríos. Podría estar tentado a pensar que servir archivos fuera de swap es tan eficiente como un sistema de archivos normal, pero hay un par de razones por las que no lo es:
Bien, esta es la realidad.
Tanto el tmpfs como un sistema de archivos normal son una memoria caché sobre el disco.
El tmpfs utiliza memoria y swapspace como almacén de respaldo un sistema de archivos utiliza un área específica del disco, ninguno de los dos está limitado en el tamaño que puede tener el sistema de archivos, es muy posible tener un tmpfs de 200GB en una máquina con menos de un GB de ram si tienes suficiente swapspace.
La diferencia está en cuándo se escriben los datos en el disco. En el caso de un tmpfs los datos se escriben SOLO cuando la memoria se llena demasiado o cuando es poco probable que los datos se utilicen pronto. Por otro lado, la mayoría de los sistemas de archivos normales de Linux están diseñados para tener siempre un conjunto de datos más o menos consistente en el disco, de modo que si el usuario se desconecta no lo pierda todo.
Personalmente, estoy acostumbrado a tener sistemas operativos que no se cuelgan y sistemas UPS (por ejemplo: baterías de portátiles) por lo que creo que los sistemas de archivos ext2/3 son demasiado paranoicos con su intervalo de checkpoint de 5-10 segundos. El sistema de archivos ext4 es mejor con un checkpoint de 10 minutos, excepto que trata los datos del usuario como de segunda clase y no los protege. (ext3 es lo mismo pero no lo notas debido al checkpoint de 5 segundos)
Este checkpointing frecuente significa que los datos innecesarios se escriben continuamente en el disco, incluso para /tmp.
Así que el resultado es que necesitas crear un espacio de intercambio tan grande como necesites que sea tu /tmp (incluso si tienes que crear un archivo de intercambio) y usar ese espacio para montar un tmpfs del tamaño requerido en /tmp.
NUNCA use /dev/shm.
A no ser que lo uses para archivos IPC muy pequeños (probablemente mmap’d) y estés seguro de que existe (no es un estándar) y la máquina tenga más que suficiente memoria + swap disponible.
Utilice /tmp/ para los archivos temporales. Usa /dev/shm/ cuando quieras memoria compartida (es decir, comunicación entre procesos a través de ficheros).
Puedes confiar en que /tmp/ está ahí, pero /dev/shm/ es algo relativamente reciente y exclusivo de Linux.
Otro momento en el que deberías usar /dev/shm (para Linux 2.6 y superior) es cuando necesitas un sistema de archivos tmpfs garantizado porque no sabes si puedes escribir en el disco.
Un sistema de monitorización con el que estoy familiarizado necesita escribir archivos temporales mientras construye su informe para enviarlo a un servidor central. Es mucho más probable en la práctica que algo impida las escrituras en un sistema de archivos (ya sea por falta de espacio en el disco o porque un fallo del RAID subyacente haya empujado al sistema a un modo de sólo lectura por hardware), pero que aún así se pueda seguir cojeando para alertar sobre ello, que si algo se lleva toda la memoria disponible en espiral de tal manera que tmpfs sea inutilizable (y la caja no esté muerta). En casos como este, un sistema de monitorización preferirá escribir en la RAM para poder enviar una alerta sobre un disco lleno o un hardware muerto/muerto.
/dev/shm se utiliza para programas y controladores de dispositivos específicos del sistema de memoria virtual compartida.
Si usted está creando un programa que requiere un montón de memoria virtual que debe ser asignado a la memoria virtual. Esto va doblemente si necesitas que múltiples procesos o hilos puedan acceder de forma segura a esa memoria.
El hecho de que el controlador utilice una versión especial de tmpfs para ello, no significa que debas utilizarlo como una partición tmpfs genérica. En lugar de eso, deberías simplemente crear otra partición tmpfs si quieres una para tu directorio temporal.
En PERL, teniendo 8GB mínimo en cualquier máquina (todas corriendo Linux Mint), soy de lo que creo que es una buena costumbre de hacer algoritmos complejos basados en DB_File (estructura de datos en un archivo) con millones de lecturas y escrituras usando /dev/shm
En otros lenguajes, no teniendo gigether en todas partes, para evitar los arranques y paradas en la transferencia de red (trabajando localmente en un archivo que se encuentra en un servidor en un ambiente cliente-servidor), usando un archivo por lotes de algún tipo, copiaré todo el archivo (300-900MB) de una vez a /dev/shm, ejecutaré el programa con salida a /dev/shm, escribiré los resultados de vuelta al servidor, y borraré de /dev/shm
Naturalmente, si tuviera menos RAM, no haría esto. Ordinariamente, el sistema de archivos en memoria de /dev/shm se lee como un tamaño que es la mitad de su RAM disponible. Sin embargo, el uso ordinario de la RAM es constante. Así que realmente no podrías hacer esto en un dispositivo con 2GB o menos. Parafraseando a la hipérbole, a menudo hay cosas en la RAM que incluso el sistema no informa bien.