Copia de archivo multiproceso


8

Tenemos una utilidad que se usa para cargar archivos (y realizar otras operaciones en el archivo) a una ubicación compartida de la red.
El tamaño del archivo tiende a variar de unos pocos mb a 500 mb.
Ha surgido una sugerencia de que tal vez deberíamos admitir subprocesos múltiples al cargar los archivos en la ubicación compartida, no es necesario que lo haga en fragmentos de bytes, cada subproceso debe elegir un archivo e intentar cargarlo.

No estoy tan seguro de si el subprocesamiento múltiple puede acelerar operaciones de E / S como esta. ¿Es válida mi corazonada?

Si de hecho estamos obligados a construir esta funcionalidad, me preguntaba cuál sería un buen enfoque de diseño para el motor de copia de archivos.
¿Tendría sentido usar una herramienta como robocopy (leí que las versiones más nuevas admiten subprocesos múltiples)?

Editar: Disculpas por el retraso y la falta de información vital.
Esta utilidad está construida con C # (.Net 2.0) y cualquier actualización futura también debe estar usando .Net (la versión de marco no es una restricción). La utilidad se instala en las máquinas de los usuarios (alrededor de 20 en WinXP). El recurso compartido de destino está en el servidor Win2k3.

Edición 2: he decidido ejecutar algunas pruebas con una aplicación simple que implementa la carga del archivo a través de TPL. Publicar este análisis decidiremos si seguir adelante o no. Gracias a todos por la ayuda extendida.


1
¿Qué lenguaje de programación? En C, un enfoque más idiomático podría ser usar E / S asíncrona, usando un selectbucle en lugar de hilos. Aunque hacerlo requiere que "cambie el código al revés" (el código para copiar un archivo ya no es una secuencia directa de comandos), no tendrá que preocuparse por la sincronización de subprocesos.
Joey Adams

Probablemente la solución razonable más fácil es dejar que el sistema operativo manejar todo: SHFileOperation(FO_COPY). Eso le brinda todas las optimizaciones que la gente de Microsoft considera razonables.
MSalters

Tos tos robocopy ... podría automatizarlo con algo como robomojo
James Snell

Respuestas:


19

Esto depende de cuál es el factor limitante, ¿no? Si el cuello de botella es el programa de utilidad, entonces seguro, ejecutar más de una copia o usar más hilos acelerará las cosas. Si la red es el factor limitante, entonces agregar múltiples instancias de la utilidad no va a ayudar, ya que aún estará atascado moviéndose a la mayoría de los X bytes por segundo. De hecho, podría doler porque tiene la sobrecarga adicional de una segunda copia de la aplicación. Lo mismo con disk-IO. Solo puede copiar tan rápido como cualquiera de las máquinas puede leer y escribir en el disco. Si eso ya está al máximo, agregar copias no va a ayudar.

Lo que debe hacer es probar para ver cuál es el cuello de botella y comenzar desde allí.


11

Cómo no ayudará el subprocesamiento múltiple:

Múltiples hilos que leen simultáneamente desde el disco del cliente o que envían simultáneamente cosas a través de la red no ayudarán en absoluto, ya que lo más probable es que solo exista una ruta de comunicación entre el cliente y el servidor, lo más probable es que el cliente lea archivos desde un solo disco duro -drive, y los archivos probablemente se escriben en un solo disco duro en el servidor. (Incluso si el servidor tiene RAID, hará alguna diferencia, pero no mucha). Por el contrario, como ya se ha señalado, el rendimiento probablemente se degradará, porque habrá una búsqueda constante entre los archivos que se están leyendo en paralelo en el cliente y búsqueda constante entre los archivos que se escriben en paralelo en el servidor. Además, los archivos pueden terminar siendo almacenados mal fragmentados en el servidor.

Cómo ayudará el subprocesamiento múltiple:

Sin embargo, el subprocesamiento múltiple puede ayudar de una manera diferente: con solo dos subprocesos en el cliente, la E / S de archivo se puede desincronizar desde la E / S de red. Esto significa que el cliente puede transmitir simultáneamente un fragmento de un archivo mientras lee el siguiente fragmento de su disco. (El servidor ya es capaz de escribir al mismo tiempo una parte de un archivo en el disco, al recibir el siguiente fragmento de la red.) Esto sería enormementeacelerar el proceso de transferencia, porque el cliente tenderá a mantener saturado el canal de red o el canal de disco (el que sea más lento), en lugar de acceder a cada uno de forma intermitente. Supongo que todas las utilidades especializadas de copia de archivos deberían ser lo suficientemente inteligentes como para hacer eso, pero puedo estar equivocado, por lo que si "Robocopy" anuncia que hacen copias multiproceso, está bien, vaya con eso.

EDITAR: corrigí el bit que había escrito sobre RAID.

EDITAR: corrigí el bit sobre la necesidad de dos subprocesos en el servidor.

Supongo que lo más importante aquí (como está en casi todas partes) es la medición . No tiene ningún control sobre cómo funcionan estas utilidades, por lo que solo sabrá si lo está haciendo de la manera más rápida posible si mide el rendimiento para ver si está cerca del rendimiento anunciado de su disco o red (lo que sea menor) .)


Esto parece una gran idea, pero no entiendo cómo la utilidad de transferencia de archivos puede hacer esto a menos que tenga privilegios de ejecución remota (o el protocolo de transferencia de alguna manera lo soporta de manera inherente). Estoy tratando de escribir una utilidad para realizar transferencias regulares de una cantidad gigantesca de archivos desde un NAS, y realmente necesito encontrar formas de reducir el tiempo.
Asad Saeeduddin

Su pregunta es muy perceptiva y apunta a una inexactitud en mi respuesta. El servidor ya debería estar desincronizando las E / S de red desde el acceso al disco, en virtud de cómo funcionan los servidores: tienden a realizar E / S asíncronas en lugar de generar un hilo separado para cada cliente, que solo puede hacer una cosa a la vez. Por lo tanto, no debería preocuparse por el servidor, solo por el cliente. Reformularé mi respuesta.
Mike Nakis

@Asad Además, tenga en cuenta que por "servidor" en este caso me refiero a cualquier máquina que se encuentre en el extremo receptor de la transferencia. No necesita ser una máquina con un rol de servidor designado.
Mike Nakis

9

Al copiar una gran cantidad de archivos más pequeños, el subprocesamiento múltiple puede ayudar porque tiende a haber brechas en la transferencia de datos mientras el programa busca directorios para el siguiente archivo, lo abre y obtiene los datos.

El subprocesamiento múltiple también ayudará cuando el cliente y el servidor tengan almacenamiento de datos en paralelo, como RAID o SSD: cualquier cosa que funcione mejor con números de mayor profundidad de cola.

Aparte de eso, a menudo ralentizará las cosas. Por ejemplo, hacer que un solo disco duro lea o escriba dos archivos al mismo tiempo lo obligará a buscar repetidamente del archivo 1 al archivo 2.


2

Trabajo para Data Expedition, Inc. que, como mencionó Emmad, produce software comercial para este tipo de escenario. La transferencia de archivos multiproceso puede tener beneficios, pero debe comprender cuidadosamente cuáles son sus cuellos de botella de rendimiento.

Cualquier ruta de red tendrá al menos docenas de componentes de hardware y software por los que deben pasar los datos. El más lento de todos determinará tu velocidad. Pero la forma en que mueve los datos cambiará el comportamiento de esos componentes.

Muchos antecedentes sobre eso aquí: http://www.DataExpedition.com/support/notes/tn0009.html

La ejecución de TCP paralelos puede ayudar cuando las velocidades de TCP individuales están muy por debajo de las capacidades de la red, el disco y la CPU.

Pero si está buscando velocidades de red de más de decenas de megabits por segundo, las transferencias de datos paralelas reducirán exponencialmente la E / S de su disco debido a la agitación del disco duro. Puede caer rápidamente hasta el punto en que el acceso al disco se vuelve mucho más lento que la capacidad de la red. Elegir el tamaño correcto de bloque de lectura / escritura puede ayudar, pero eso dependerá del hardware en particular. También tenga en cuenta que Windows XP / 2003 tiene una memoria paginada muy limitada, lo que puede hacer que sea inestable si las velocidades superan los 200 megabits por segundo.

Por otro lado, si la red es más lenta que unas pocas decenas de megabits por segundo, la ejecución de muchos TCP paralelos puede llevar la latencia hasta el punto en que las sesiones individuales comienzan a ralentizarse o incluso caen sus conexiones. Nuevamente, es una cuestión de experimentación para encontrar qué nivel de paralelismo funcionará para cualquier camino y condiciones.

Por lo tanto, la copia de archivos multiproceso puede ayudar si tiene una ruta de datos conocida y puede tomarse el tiempo para ajustar la cantidad de sesiones paralelas y la E / S de su disco. Pero requiere que vuelva a sintonizar cada vez que cambian las condiciones, y puede ser perjudicial si se excede. Es por eso que hemos optado por evitar transferencias paralelas en nuestro propio software, así como evitamos el TCP.


1

Además de lo que se ha dicho, considere: - Debe haber una tarea en el cliente para crear los fragmentos y otra en el servidor para volver a unirlos como 1 archivo. Esto requiere algo de trabajo.

  • Lo bueno de los fragmentos pequeños es que puede volver a enviar partes de un archivo si el proceso falla en lugar de enviar el archivo grande por todas partes.

  • Considere solicitar una 'tubería más grande' entre su cliente y el servidor.

  • Considere comprimir el archivo grande antes de enviarlo (no estoy seguro de si esto ayudaría en el caso de archivos multimedia, ya que a veces ya están comprimidos).

  • Considere usar una utilidad comercial de transferencia de archivos como:

DataExp


0

Si está hablando de un archivo grande, el subprocesamiento múltiple realmente no ayudará. Va a estar vinculado a E / S, por lo que usar un solo hilo no ralentizará ESA carga.

Sin embargo, de lo que debe preocuparse es de la contención de recursos (suponiendo que también esté escribiendo el servidor). Si está manejando la carga en el hilo que también acepta y procesa nuevas solicitudes, otras solicitudes estarán esperando. Sin embargo, siempre que vuelva a la cola del selector después de leer un fragmento del socket y escribirlo en el disco, debería estar bien.


0

Hacer lo que sugieres de una manera ingenua matará tu rendimiento, el punto de estrangulamiento es la E / S de disco y no preparar los archivos.

Sugeriré usar un hilo que reciba archivos para trabajar y los ponga en cola para la copia y luego mantenga una copia secuencial en cualquier cosa en la cola; su hilo de proveedor es responsable de hacer que los archivos se lean para hacer cola. De esta manera, no está agotando el sistema de archivos en las unidades compartidas y no está haciendo archivos uno por uno con espacios para preparar el siguiente, está preparando y enviando simultáneamente.

La ventaja es que solo hay un punto de sincronización en la cola para preocuparse.


0

En lugar de implementar la carga paralela usted mismo, puede considerar los protocolos y herramientas existentes. Por ejemplo, el protocolo ftp y la herramienta lftp (lftp puede transferir varios archivos en paralelo).

Por lo tanto, probablemente sea mucho más fácil y más robusto usar scripts lftp o controlar lftp desde su aplicación en lugar de implementar todo desde cero.


0

Todo depende de dónde esté el factor limitante.

Multithreading podría ayudar si hay retrasos de ida y vuelta u otros espacios en la transmisión, y los hilos ayudan a llenar los espacios.

El subprocesamiento múltiple podría dañar si tiene el efecto de hacer que su disco vibre de un lado a otro, tratando de mantener todos los hilos suministrados con datos.

etc.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.