GNU/Linux >> Tutoriales Linux >  >> Linux

¿Realmente no hay E/S de bloque asíncrono en Linux?

(2020) Si está utilizando un kernel de Linux 5.1 o superior, puede usar el io_uring interfaz para E/S similar a un archivo y obtenga una excelente operación asíncrona.

En comparación con los libaio existentes /Interfaz KAIO, io_uring tiene las siguientes ventajas:

  • Mantiene el comportamiento asíncrono cuando se realiza E/S en búfer (y no solo cuando se realiza E/S directa)
  • Más fácil de usar (especialmente cuando se usa el liburing biblioteca auxiliar)
  • Opcionalmente, puede funcionar de manera encuestada (pero necesitará mayores privilegios para habilitar este modo)
  • Menos gastos generales de espacio de contabilidad por I/O
  • Reducción de la sobrecarga de la CPU debido a la menor cantidad de cambios de modo de llamada al sistema del núcleo/espacio de usuario (un gran problema en estos días debido al impacto de las mitigaciones de espectro/fusión)
  • Los descriptores de archivos y los búferes se pueden registrar previamente para ahorrar tiempo de mapeo/desmapeo
  • Más rápido (puede lograr un mayor rendimiento agregado, las E/S tienen una latencia más baja)
  • El "modo vinculado" puede expresar dependencias entre E/S (>=kernel 5.3)
  • Puede funcionar con E/S basadas en socket (recvmsg() /sendmsg() son compatibles desde>=5.3, vea los mensajes que mencionan la palabra soporte en el historial de git de io_uring.c)
  • Admite intentos de cancelación de E/S en cola (>=5.5)
  • Puede solicitar que I/O siempre realizarse desde un contexto asíncrono en lugar del valor predeterminado de recurrir únicamente a punting I/O a un contexto asíncrono cuando la ruta de envío en línea activa el bloqueo (>=kernel 5.6)
  • Creciente soporte para realizar operaciones asincrónicas más allá de read /write (por ejemplo, fsync (>=5.1), fallocate (>=5.6), splice (>=5.7) y más)
  • Mayor impulso de desarrollo
  • No se bloquea cada vez que las estrellas no están perfectamente alineadas

En comparación con POSIX AIO de glibc, io_uring tiene las siguientes ventajas:

  • Mucho más rápido y más eficiente (los beneficios de gastos generales más bajos de arriba se aplican aún más aquí)
  • La interfaz está respaldada por kernel y NO utiliza un grupo de subprocesos de espacio de usuario
  • Se realizan menos copias de los datos cuando se realiza E/S en búfer
  • No luchar con las señales
  • El POSIX AIO de Glibc no puede tener más de una E/S activa en un solo descriptor de archivo, mientras que io_uring ¡Ciertamente puede!

El documento Efficient IO with io_uring entra en más detalles en cuanto a io_uring Beneficios y uso de . El documento Novedades de io_uring describe las nuevas funciones añadidas a io_uring entre los kernels 5.2 - 5.5, mientras que el artículo El rápido crecimiento de io_uringLWN describe qué características estaban disponibles en cada uno de los kernels 5.1 - 5.5 con una mirada al futuro de lo que iba a haber en 5.6 (consulte también la lista de artículos de io_uring de LWN). También hay una presentación en video de Faster IO a través de io_uring Kernel Recipes (diapositivas) de finales de 2019 y What's new with io_uring Kernel Recipes presentación en video (diapositivas) de mediados de 2022 por io_uring autor Jens Axboe. Finalmente, el tutorial de Lord of the io_uring ofrece una introducción a io_uring uso.

El io_uring Se puede contactar a la comunidad a través de la lista de correo io_uring y los archivos de la lista de correo io_uring muestran el tráfico diario a principios de 2021.

Re "admite E/S parcial en el sentido de recv() contra read() ":se introdujo un parche en el kernel 5.3 que volverá a intentar automáticamente io_uring lecturas cortas y una confirmación adicional entró en el kernel 5.4 que modifica el comportamiento para que solo se ocupe automáticamente de las lecturas cortas cuando se trabaja con archivos "normales" en solicitudes que no han establecido el REQ_F_NOWAIT bandera (parece que puede solicitar REQ_F_NOWAIT vía IOCB_NOWAIT o abriendo el archivo con O_NONBLOCK ). Por lo tanto, puede obtener recv() estilo:comportamiento de E/S "corto" de io_uring también.

Software/proyectos usando io_uring

Aunque la interfaz es joven (su primera encarnación llegó en mayo de 2019), algunos programas de código abierto usan io_uring "en la naturaleza":

  • fio (que también fue escrito por Jens Axboe) tiene un backend io_uring ioengine (de hecho, ¡se introdujo en fio-3.13 a partir de febrero de 2019!). La presentación "Mejora del rendimiento de almacenamiento con la nueva interfaz SNIA de E/S del kernel de Linux" (diapositivas) de dos ingenieros de Intel afirma que pudieron obtener el doble de IOPS en una carga de trabajo y menos de la mitad de la latencia promedio con una profundidad de cola de 1 en otra carga de trabajo al comparar el io_uring ioengine al libaio ioengine en un dispositivo Optane.
  • El proyecto SPDK agregó soporte para usar io_uring (!) para bloquear el acceso a dispositivos en su versión v19.04 (pero obviamente este no es el backend para el que normalmente usaría SPDK aparte de la evaluación comparativa). Más recientemente, también parecen haber agregado soporte para usarlo con sockets en v20.04...
  • Ceph comprometió un backend io_uring en diciembre de 2019, que formaba parte de su versión 15.1.0. El autor de la confirmación publicó un comentario de github que muestra que el backend de io_uring tiene algunas ganancias y pérdidas en comparación con el backend de libaio (en términos de IOPS, ancho de banda y latencia) según la carga de trabajo.
  • RocksDB cometió un io_uring backend para MultiRead en diciembre de 2019 y fue parte de su versión 6.7.3. Jens declara io_uring ayudó a reducir drásticamente la latencia.
  • libev lanzó 4.31 con un io_uring inicial backend en diciembre de 2019. Si bien algunos de los puntos originales del autor se abordaron en kernels más nuevos, en el momento de escribir este artículo (mediados de 2021), el autor de libev tiene algunas palabras selectas sobre io_uring y está adoptando un enfoque de esperar y ver antes de implementar mejoras adicionales.
  • QEMU comprometió un backend io_uring en enero de 2020 y fue parte del lanzamiento de QEMU 5.0. En la presentación en PDF "io_uring en QEMU:E/S de disco de alto rendimiento para Linux", Julia Suvorova muestra el io_uring backend superando al threads y aio backends en una carga de trabajo de bloques aleatorios de 16K.
  • Samba fusionó un io_uring Backend de VFS en febrero de 2020 y fue parte del lanzamiento de Samba 4.12. En el backend "Linux io_uring VFS". Hilo de la lista de correo de Samba, Stefan Metzmacher (el autor de la confirmación) dice el io_uring El módulo pudo impulsar aproximadamente un 19 % más de rendimiento (en comparación con algún backend no especificado) en una prueba sintética. También puede leer la presentación en PDF "Async VFS Future" de Stefan para conocer algunas de las motivaciones detrás de los cambios.
  • El C++ experimental libunifex de Facebook lo usa (pero también necesitará un kernel 5.6+)
  • La gente del óxido ha estado escribiendo envoltorios para hacer io_uring más accesible al óxido puro. rio es una biblioteca de la que se habló un poco y el autor dice que lograron un mayor rendimiento en comparación con el uso de llamadas de sincronización envueltas en subprocesos. El autor hizo una presentación sobre su base de datos y biblioteca en FOSDEM 2020 que incluyó una sección ensalzando las virtudes de io_uring .
  • La biblioteca de óxido Glommio usa exclusivamente io_uring . El autor (Glauber Costa) publicó un documento llamado El almacenamiento moderno es bastante rápido. Son las API las que son malas y muestran que, con un ajuste cuidadoso, Glommio podría obtener un rendimiento 2,5 veces superior al normal (no io_uring). ) llamadas al sistema al realizar E/S secuenciales en un dispositivo Optane.
  • Gluster fusionó un posix xlator de io_uring en octubre de 2020 y formó parte del lanzamiento de Gluster 9.0. El autor de la confirmación menciona que el rendimiento "no fue peor que las llamadas al sistema pwrite/pread normales".

Investigación de software usando io_uring

  • El desarrollador de PostgreSQL Andres Freund ha sido una de las fuerzas impulsoras detrás de io_uring mejoras (por ejemplo, la solución alternativa para reducir la contención de inodos del sistema de archivos). Hay una presentación "E/S asíncrona para PostgreSQL" (tenga en cuenta que el video está interrumpido hasta la marca de 5 minutos) (PDF) que motiva la necesidad de cambios en PostgreSQL y demuestra algunos resultados experimentales. Ha expresado su esperanza de obtener su io_uring opcional. compatibilidad con PostgreSQL 14 y parece muy consciente de lo que funciona y lo que no, incluso hasta el nivel del kernel. En diciembre de 2020, Andrés habla más sobre su PostgreSQL io_uring trabaja en el hilo de la lista de correo de pgsql-hackers "Blocking I/O, async I/O and io_uring" y menciona que el trabajo en progreso se puede ver en https://github.com/anarazel/postgres/tree/aio .
  • El proyecto Netty tiene un repositorio de incubadora trabajando en io_uring soporte que necesita un kernel 5.9
  • libuv tiene una solicitud de extracción en su contra agregando io_uring apoyo, pero su progreso en el proyecto ha sido lento
  • SwiftNIO agregó io_uring soporte para eventos (pero no syscalls) en abril de 2020 y el problema de E/S de Linux:io_uring completo describe los planes para integrarlo aún más
  • El proyecto Tokio Rust ha desarrollado una prueba de concepto tokio-uring

Compatibilidad con la distribución de Linux para io_uring

  • (Finales de 2020) El último kernel de habilitación HWE de Ubuntu 18.04 es 5.4, por lo que io_uring Se pueden usar llamadas al sistema. Esta distribución no empaqueta previamente el liburing biblioteca auxiliar, pero puede crearla usted mismo.
  • El núcleo inicial de Ubuntu 20.04 es 5.4, así que io_uring Se pueden usar llamadas al sistema. Como arriba, la distribución no empaqueta previamente liburing .
  • El núcleo inicial de Fedora 32 es 5.6 y tiene un liburing empaquetado entonces io_uring es utilizable.
  • SLES 15 SP2 tiene un kernel 5.3, por lo que io_uring Se pueden usar llamadas al sistema. Esta distribución no empaqueta previamente el liburing biblioteca auxiliar, pero puede crearla usted mismo.
  • (mediados de 2021) el kernel predeterminado de RHEL 8 no soporte io_uring (una versión anterior de esta respuesta dijo erróneamente que sí). Hay un artículo de la base de conocimiento de Red Hat Add io_uring support (el contenido está detrás de un muro de pago de suscriptor) que está "en progreso".
  • (mediados de 2022) el kernel predeterminado de RHEL 9 no soporte io_uring . El kernel es lo suficientemente nuevo (5.14) pero es compatible con io_uring está explícitamente deshabilitado.

Con suerte io_uring marcará el comienzo de una mejor historia de E/S asincrónica similar a un archivo para Linux.

(Para agregar una fina capa de credibilidad a esta respuesta, en algún momento en el pasado, Jens Axboe (mantenedor de la capa de bloques del kernel de Linux e inventor de io_uring ) pensó que valdría la pena votar esta respuesta :-)


La respuesta real, que fue señalada indirectamente por Peter Teoh, se basa en io_setup() y io_submit(). Específicamente, las funciones "aio_" indicadas por Peter son parte de la emulación a nivel de usuario de glibc basada en hilos, que no es una implementación eficiente. La verdadera respuesta está en:

io_submit(2)
io_setup(2)
io_cancel(2)
io_destroy(2)
io_getevents(2)

Tenga en cuenta que la página de manual, fechada en 2012-08, dice que esta implementación aún no ha madurado hasta el punto en que pueda reemplazar la emulación del espacio de usuario de glibc:

http://man7.org/linux/man-pages/man7/aio.7.html

esta implementación aún no ha madurado hasta el punto en que la implementación de POSIXAIO se puede volver a implementar por completo mediante las llamadas al sistema kernel.

Entonces, de acuerdo con la última documentación del kernel que pude encontrar, Linux aún no tiene un modelo de E/S asíncrono basado en el kernel maduro. Y, si asumo que el modelo documentado es realmente maduro, todavía no admite E/S parcial en el sentido de recv() frente a read().


Linux
  1. Linux:¿cómo monitorear la E/S del disco en un directorio en particular?

  2. ¿Cómo se realiza la E/S de la consola sin bloqueo en Linux en C?

  3. ¿Cómo detener el proceso 'ininterrumpible' en Linux?

  4. ¿Linux y puertos de finalización de E/S?

  5. Confusión sobre el mecanismo de E/S asíncrono interno de node.js

10 Comando iostat de Linux para informar estadísticas de CPU y E/S

N ¿Equivalente a Top pero para E/S de red?

10 ejemplos de iozone para la medición del rendimiento de E/S de disco en Linux

¿Hay STDCALL en Linux?

¿Cómo purgar cachés de E/S de disco en Linux?

Depuración de la latencia de E/S de Linux