Uso de O_DIRECT en Linux

23

Si esta pregunta está demasiado orientada al programador, avíseme. Me pregunto si hay personas familiarizadas con el indicador O_DIRECT para la llamada al sistema open () en Linux 2.6. Linus menosprecia su uso, sin embargo, la escritura de archivos de alto rendimiento parece indicar su uso. Me gustaría saber de cualquier experiencia y recomendaciones del mundo real.

Más información: La aplicación que estoy usando no mantener su propia caché, y al hacerlo, alcanza un promedio de 5 veces o más velocidad. Al escribir en un archivo, el contenido de la memoria caché debe escribirse en la memoria caché del sistema de archivos, lo que parece redundante y una preocupación de rendimiento.

casualunixer
fuente

Respuestas:

17

Ok, pides experiencias, esto hace que la pregunta sea un poco subjetiva y argumentativa, pero aceptable.

Linus dijo que refiriéndose a los usos que las personas generalmente atribuyen a O_DIRECT, y para esos usos, IMO Linus es en su mayoría correcto. Incluso si realiza una E / S directa, no puede transferir datos a / desde dispositivos directamente a las declaraciones de su programa, necesita un búfer que se llena (por el programa o el dispositivo) y se transfiere mediante una llamada del sistema al otro extremo. Además, para que sea eficiente, no querrá volver a leer algo que acaba de leer, en caso de que lo necesite nuevamente. Por lo tanto, necesita algún tipo de caché ... ¡y es exactamente eso lo que el núcleo proporciona sin O_DIRECT, un caché de página! ¿Por qué no usar eso? También viene con beneficios si más procesos desean acceder al mismo archivo al mismo tiempo, sería un desastre con O_DIRECT.

Dicho esto, O_DIRECT tiene sus usos: si por alguna razón necesita obtener datos directamente del dispositivo de bloque. No tiene nada que ver con el rendimiento.

Las personas que usan O_DIRECT para el rendimiento generalmente provienen de sistemas con algoritmos de caché de página defectuosos, o sin mecanismos de asesoramiento POSIX, o incluso personas que repiten sin pensar lo que otras personas han dicho. Para evitar estos problemas, O_DIRECT fue una solución. Linux, OTOH, tiene la filosofía de que debe solucionar el problema subyacente real, y el problema subyacente fueron los sistemas operativos que hicieron un mal trabajo con el almacenamiento en caché de la página.

Usé O_DIRECT para una implementación simple de cat para encontrar un error de memoria en mi máquina. Este es un uso válido para O_DIRECT. Eso no tenía nada que ver con el rendimiento.

Juliano
fuente
Gracias por la información, se agradece. He actualizado mi pregunta con las condiciones específicas de la aplicación que provocó esta pregunta. Si tiene más detalles sobre los mecanismos de asesoramiento POSIX para escribir archivos, eso también sería apreciado.
casualunixer
44
o_direct también podría ser útil en un sistema donde el desarrollador quiere proporcionar un mecanismo de almacenamiento en caché en la capa de aplicación (piense en bases de datos).
Jmoney38
No tiene nada que ver con el rendimiento. Eso no siempre es cierto, especialmente para acceder a un dispositivo de alta velocidad donde el IO califica el ancho de banda de memoria rival, o incluso solo un porcentaje significativo del ancho de banda de memoria. En ese caso, omitir la copia adicional a / desde la memoria caché de la página puede tener importantes beneficios de rendimiento.
Andrew Henle
13

En realidad, O_DIRECT es necesario para evitar cualquiera de

  • contaminación de caché : a veces sabes que no tiene sentido la sobrecarga con el almacenamiento en caché, por ejemplo, cuando se trata de archivos realmente grandes, digamos 64 GiB cuando solo hay 2 GiB de RAM. El archivo torrent de 32 GiB que un usuario decidió verificar no parece ser un buen candidato para el almacenamiento en caché. Es solo una actividad extra con sus propios gastos generales. Y puede hacer que algunos datos realmente útiles se eliminen del caché.
  • caché doble : por ejemplo, algunos RDBMS (MySQL para mencionar) permiten definir su propio caché. Las bases de datos supuestamente saben mejor cómo almacenar en caché y qué, que la memoria virtual del núcleo, que no sabe nada sobre la planificación de SQL, etc.

- lo cual no es bueno, como parece. Y O_DIRECTno significa ser más rápido, a menudo no lo es .

poige
fuente
10
posix_fadvisepuede encargarse del problema de la contaminación del caché.
psusi
No creo que la memoria virtual tenga nada que ver con eso, simplemente asigna la dirección de memoria. Buffer Cache / Page Cache es lo que quieres decir.
ArekBulski
Caches / caching es parte del subsistema VM en UNIX, por lo que puedo decir, es por eso que usé este término. Gracias por editar :)
poige
6

Tenga en cuenta que usando O_DIRECT puede fallar en los núcleos más nuevos con los sistemas de archivos más nuevos. Vea este informe de error, por ejemplo. Por lo tanto, no solo el uso a menudo es dudoso, sino que probablemente no funcionará en absoluto en la próxima generación de distribuciones de Linux. Por lo tanto, no apostaría el rendimiento de mi código en él, incluso si puede demostrar que podría tener un beneficio.

Peter Eisentraut
fuente
1
El informe de error en realidad discute el uso de sistemas de archivos con la opción journal = data activada. Esta opción es directamente opuesta en efecto al indicador O_DIRECT. La mayoría de los sistemas de archivos ext3 y ext4 no tienen este indicador establecido y, si lo tienen, desactivarlo permitirá abrir el archivo con O_DIRECT.
casualunixer
3

Tiene mucho que ver con el rendimiento.

Un ejemplo interesante es en mongodb usando el motor mmap. O_DIRECT se usa mejor, como han dicho otros, donde es poco probable que los datos se lean durante algún tiempo. En mongodb, el diario de la base de datos se escribe usando O_DIRECT, mientras que las escrituras de datos e índices se manejan mediante el mecanismo de caché de página (pdflush) porque, aunque O_DIRECT ofrece menos ancho de banda, también significa menos latencia y, por lo tanto, reduce la pérdida de datos en caso de un corte inesperado (pánico del núcleo, falla del disco o de la alimentación). Tenga en cuenta que todavía hay almacenamiento en búfer antes de que una escritura O_DIRECT se confirme en un almacenamiento no volátil, esto solo reduce la pérdida de datos.

Otra característica importante de O_DIRECT es que proporciona más control sobre la secuencia. de escrituras. Una vez más, no garantiza el orden de las escrituras (a menos que tenga un controlador de disco de almacenamiento en caché no volátil y esté utilizando el planificador fifo, pero estos tienen sus propias complicaciones). Por lo tanto, aunque mysql usa O_DIRECT para sus datos / índices, así como para el diario, puede esperar que este último se confirme primero.

Pero es importante recordar que O_DIRECT rompe la imparcialidad en la asignación de recursos. Una de las razones por las que su aplicación se acelera es porque ralentiza otras cosas.

symcbean
fuente
Usted dice que tiene mucho que ver con el rendimiento, sin embargo, proporciona un ejemplo en el que se usa para disminuir la latencia o para ordenar escrituras. Pero sí estoy de acuerdo en que afecta el rendimiento. Punto justo sobre la equidad.
ArekBulski
¿Puede proporcionar más referencias que expliquen cuándo es injusto?
Acíclico
3

En relación con lo que @Juliano ya ha dicho.

Compruebe posix_fadvisesi el problema real es el mal comportamiento del algoritmo de caché del sistema de archivos subyacente, puede intentar darle consejos, ¿cómo va a utilizar el sistema de archivos? Para fs bien implementado, debería aumentar el rendimiento. (Aquí hay un enlace a otro tema que toca consideraciones similares /programming//a/3755818/544721 )

Grzegorz Wierzowiecki
fuente
1
Parece que posix_fadvise cambia los algoritmos de lectura leída utilizados por el núcleo. El factor crítico con el código en la pregunta es el rendimiento de escritura. El problema es que escribir el búfer llena primero los cachés de Linux, que el núcleo debe volcar cuando se queda sin memoria. Esto es una pérdida de esfuerzo, la salida en este caso debe ser mínimamente almacenada en el camino al disco.
casualunixer