Haga que Linux escriba en el sistema de archivos de red simultáneamente con lecturas de disco local

17

Resumen

¿Cómo puede configurar Linux tanto para leer desde un disco / sistema de archivos local como para escribir en un recurso compartido de red al mismo tiempo, en lugar de leer mientras no hay datos en la red, y luego enviar esos datos a través de la red mientras el disco local está ¿ocioso?

Es mucho más rápido leer y escribir al mismo tiempo en lugar de solo realizar una operación y luego la otra de manera alterna.

Detalles

Estoy transfiriendo una gran cantidad de datos de discos locales en una máquina Linux a un dispositivo NAS.

Estoy usando rsyncpara copiar, básicamente, /srv/dataen /mnt/nasque es un soporte de CIFS.

Comenzó bien, leyendo a 100 MB / seg y escribiendo en el NAS a 100 MB / seg (límite de la red de gigabits), con lectura y escritura simultáneamente.

Sin embargo, ahora, unas horas más tarde, descubro que está leyendo desde el disco local, luego detengo la lectura mientras escribe en el NAS, luego, cuando no hay más datos para escribir en el NAS, reanuda la lectura desde el disco de nuevo. La red está inactiva mientras se lee el disco, y el disco está inactivo mientras la red está en uso.

No hace falta decir que leer 200 MB y luego escribir 200 MB lleva mucho más tiempo que leer y escribir esos 200 MB al mismo tiempo.

¿Cómo puedo configurar el núcleo de modo que se adhiera al comportamiento anterior de leer y escribir al mismo tiempo, en lugar de alternar entre leer y escribir, realizando solo una operación a la vez?

Algunas observaciones: cuando el disco local lee a más de 100 MB / seg, todo parece suceder en paralelo muy bien, pero una vez que el disco se ralentiza (parece que ahora solo va a 20 MB / seg por alguna razón) es cuando esta lectura / escritura El cambio parece suceder.

También puedo ejecutar syncmanualmente cada pocos segundos para que las escrituras sucedan en paralelo con las lecturas (aunque obviamente a velocidades reducidas), sin embargo, poner syncun whilebucle para que se ejecute cada cinco segundos no parece ser la solución correcta ...

El núcleo parece almacenar en caché aproximadamente 1 GB de datos y luego escribirlo en la red lo más rápido posible, lo cual está bien, pero no entiendo por qué el disco lento debe dejar de leerse mientras los datos se envían a través de la red. red.

Malvinoso
fuente
1
La mayoría de las herramientas de Unix no están absolutamente optimizadas para el ancho de banda en este sentido, ni rsync, ni siquiera un simple cp. Son aplicaciones de subproceso único que usan IO de bloqueo.
peterh - Restablece a Mónica el
1
En algún lugar, alrededor de 100 MB / s también es lo que puede esperar ver en los discos duros rotativos comunes modernos de 7200 rpm en cargas de trabajo puramente secuenciales. Se reduce una vez que comienza a buscar, por ejemplo, para actualizar metadatos o si el sistema de archivos está fragmentado, porque luego se une a IOPS.
un CVn
¿Puedes instalar rsync en el NAS?
Jasen

Respuestas:

27

Después de más investigación, parece que este problema está menos relacionado con el kernel y más sobre cómo rsyncinteractúan CIFS.

Por lo que puedo entender, lo que está sucediendo es que cuando rsynccierra el archivo de destino, CIFS (y probablemente cualquier sistema de archivos de red) asegura que el archivo esté completamente enjuagado y escrito en el disco remoto antes de que closeregrese la llamada al sistema. Esto es para asegurar a cualquier aplicación que una vez que la operación de cierre se complete con éxito, el archivo se haya guardado por completo y no exista riesgo de errores adicionales que puedan causar la pérdida de datos.

Si esto no se hiciera, entonces sería posible que una aplicación cierre un archivo, salga pensando que la operación de guardar fue exitosa, y luego (tal vez debido a un problema de red) los datos no pudieron escribirse, pero para entonces es demasiado tarde para que la aplicación haga algo al respecto, como preguntarle al usuario si desea guardar el archivo en otro lugar.

Este requisito significa que cada vez que rsynctermine de copiar un archivo, todo el búfer de disco debe vaciarse en la red antes de rsyncpoder continuar leyendo el siguiente archivo.

Una solución alternativa es montar el recurso compartido CIFS con la opción cache=noneque deshabilita esta función y hace que todas las E / S vayan directamente al servidor. Esto elimina el problema y permite que las lecturas y escrituras se ejecuten en paralelo, sin embargo, un inconveniente de esta solución es que el rendimiento es algo menor. En mi caso, la velocidad de transferencia de red cae de 110 MB / seg a 80 MB / seg.

Esto puede significar que si está copiando archivos grandes, el rendimiento puede ser mejor con el comportamiento alternativo de lectura / escritura. Con muchos archivos más pequeños, deshabilitar el caché dará como resultado menos descargas de caché cada vez que se cierre un archivo, por lo que el rendimiento puede aumentar allí.

Parece que rsyncnecesita una opción para cerrar sus identificadores de archivo en otro subproceso, por lo que puede comenzar a leer el siguiente archivo mientras el último todavía está enjuagado.

EDITAR: He confirmado que cache=nonedefinitivamente ayuda cuando se transfieren muchos archivos pequeños (lo lleva de 10 MB / seg hasta 80 MB / seg) pero cuando se transfieren archivos grandes (1 GB +) se cache=nonereduce la transferencia de 110 MB / seg a los mismos 80 MB / seg. Esto sugiere que la transferencia lenta desde muchos archivos pequeños tiene menos que ver con la búsqueda del disco de origen, y más con tener tantas descargas de caché de todos los archivos pequeños.

Malvinoso
fuente
2
Que es un problema muy interesante, y gracias por publicar la explicación. rsyncno leer el archivo en un hilo diferente (en realidad, proceso diferente) porque está diseñado de modo que una copia de rsyncse ejecuta en cada lado de la red, a pesar de que en su caso ambas copias están en el mismo lado (y el sistema de archivos se esconde la hecho de que hay una red). Supongo que no ayuda, porque el proceso del lector llena muy rápidamente la tubería mientras el proceso del escritor se bloquea en unclose() . rsyncfuncionaría mejor si estuviera usando rsyncel cable, no CIFS.
Celada
1
Me imagino que otra solución es que no se puede ejecutar rsyncen el NAS sería usar a rsynctravés de la red (como rsync -a files localhost:/dest/path) mientras se introduce artificialmente un enorme búfer (como megabytes múltiples, al menos) en las conexiones de red. No estoy seguro de cuál sería el mejor truco para hacerlo.
Celada
@ Celada: ¡Gracias! Sí, me imagino que ejecutar rsyncen la caja NAS también solucionaría el problema. Sin embargo, es un poco más complejo (permisos NAS extraños, tengo que soltar enlaces simbólicos, etc.) pero creo que si tuviera un poco más de datos para copiar, valdría la pena invertir tiempo en hacerlo.
Malvineous
2
Posiblemente no relacionado con su caso: hace unos años tuve un problema similar al escribir la salida dump(8)en un NAS montado sobre NFS. En ese momento, diagnostiqué que el problema estaba maximizando la CPU en el NAS, debido al efecto combinado del servidor NFS y un firewall que se ejecutaba en el NAS (la caja no estaba rooteada y el firewall no podía desactivarse por completo desde La interfaz web). El problema desapareció cuando reemplazamos el NAS con una PC vieja. FWIW
Satō Katsura
@SatoKatsura: Definitivamente una posibilidad para dispositivos NAS más antiguos, aunque en ese caso me imagino que vería una transferencia general más lenta en lugar de una ráfaga como esta. Mi NAS es un Atom de doble núcleo (~ 2 GHz) que se encuentra a aproximadamente el 30% de uso de la CPU cuando se maximiza una NIC de gigabit sin tramas gigantes, por lo que debería estar bien allí.
Malvineous