¿Existe una alternativa más rápida a cp para copiar archivos grandes (~ 20 GB)?

40

Soy un estudiante graduado, y el grupo en el que trabajo mantiene un clúster de Linux. Cada nodo del clúster tiene su propio disco local, pero estos discos locales son relativamente pequeños y no están equipados con copia de seguridad automática. Por lo tanto, el grupo posee un servidor de archivos con muchas TB de espacio de almacenamiento. Soy un novato relativo de Linux, por lo que no estoy seguro de cuáles son las especificaciones del servidor de archivos en términos de velocidad, capacidad de red, etc. Sé por experiencia que los discos locales son significativamente más rápidos que el servidor de archivos en términos de E / S . Alrededor de una docena de personas usan el servidor de archivos.

El uso cppara copiar un archivo de ~ 20 GB del servidor de archivos a uno de los discos locales demora aproximadamente 11.5 minutos en tiempo real en promedio (según time). Sé que esta cpoperación no es muy eficiente porque (1) timeme dice que el tiempo del sistema para tal copia es de solo ~ 45 segundos; y porque (2) cuando examino topdurante la copia, % CPU es bastante bajo (por inspección, aproximadamente 0-10% en promedio).

Usar cppara copiar el mismo archivo de ~ 20 GB de una carpeta en el disco local a otra carpeta en el mismo disco local toma menos tiempo, aproximadamente 9 minutos en tiempo real (~ 51 segundos en tiempo del sistema, según time). Entonces, aparentemente el servidor de archivos es algo más lento que el disco local, como se esperaba, pero quizás no significativamente más lento. Me sorprende que copiar de local a mismo local no sea más rápido que 9 minutos.

Necesito copiar ~ 200 archivos grandes, cada ~ 20 GB, del servidor de archivos a uno de los discos locales. Entonces, mi pregunta es: ¿Existe una alternativa más rápida cppara copiar archivos grandes en Linux? (¿O hay algún indicador dentro de cpeso que podría usar que aceleraría la copia?) Incluso si de alguna manera pudiera reducir un minuto este tiempo de copia, eso sería de gran ayuda.

Estoy seguro de que comprar discos de hardware nuevos y más rápidos, pero no tengo acceso a dichos recursos. Tampoco soy administrador del sistema, solo soy un usuario (novato), por lo que no tengo acceso a información más detallada sobre la carga que hay en los discos. Sé que, si bien alrededor de una docena de personas usan el servidor de archivos a diario, soy la única persona que usa este nodo particular / disco local.

Andrés
fuente
29
Eso hace alrededor de 29 MB / s, que es bastante rápido si me preguntas. No creo que haya ningún comando que acelere esto, lo más probable es que el "cuello de botella" sea a) la red ob) el servidor de archivos.
tink
55
tink es 100% correcto. Nunca he visto nada que pueda mejorar esto. Lo único que he hecho en el pasado es comprimir los datos antes de enviarlos, pero eso significa que está agregando tiempo con los pasos de compresión y descompresión, pero a veces vale la pena si los datos son un buen candidato para ser ¡comprimido!
slm
3
También puede intentar ddy rsynccomparar cuál funciona más rápido en su entorno
Raza
@Salton Gracias. Todavía no lo he intentado dd, pero solo lo intenté rsync. El tiempo real fue de aproximadamente 11.5 minutos y el tiempo del sistema fue de aproximadamente 1.5 minutos, según time.
Andrew
2
Me sorprende que nadie haya señalado que la copia de disco local a disco local podría hacerse más eficiente si se montan varios discos. Copiar de /dev/sda1a /dev/sdb1va a ser más rápido que copiar de una ubicación /dev/sda1a otra ubicación /dev/sda1u otra partición /dev/sdaporque el disco duro no tendrá que hacer búsquedas adicionales entre lecturas y escrituras (suponiendo que los discos duros tradicionales con discos giratorios y cabezas móviles; SSD es obviamente diferente).
tripleee

Respuestas:

53

El% de CPU debe estar bajo durante una copia. La CPU le dice al controlador de disco que "tome datos de los sectores X – Y en el búfer de memoria en Z". Luego se va y hace otra cosa (o duerme, si no hay nada más). El hardware desencadena una interrupción cuando los datos están en la memoria. Luego, la CPU tiene que copiarlo varias veces y le dice a la tarjeta de red que "transmita paquetes en las ubicaciones de memoria A, B y C". Luego vuelve a hacer otra cosa.

Estás empujando ~ 240mbps. En una LAN de gigabits, debe poder hacer al menos 800 mbps, pero:

  1. Eso es compartido entre todos los que usan el servidor de archivos (y posiblemente una conexión entre conmutadores, etc.)
  2. Eso está limitado por la velocidad que el servidor de archivos puede manejar la escritura, teniendo en cuenta que el ancho de banda de E / S del disco es compartido por todos los que lo usan.
  3. No especificó cómo está accediendo al servidor de archivos (NFS, CIFS (Samba), AFS, etc.). Es posible que deba ajustar su montaje de red, pero en cualquier cosa que haya sido la mitad de las veces, los valores predeterminados suelen ser bastante sensatos.

Para rastrear el cuello de botella, iostat -kx 10será un comando útil. Le mostrará la utilización en sus discos duros locales. Si puede ejecutar eso en el servidor de archivos, le dirá qué tan ocupado está el servidor de archivos.

La solución general será acelerar ese cuello de botella, que por supuesto no tiene el presupuesto. Pero, hay un par de casos especiales en los que puede encontrar un enfoque más rápido:

  • Si los archivos son comprimibles y tienes una CPU rápida, hacer una compresión mínima sobre la marcha podría ser más rápido. Algo así lzopo tal vez gzip --fastest.
  • Si solo cambia algunos bits aquí y allá, y luego envía el archivo de regreso, solo el envío de deltas será mucho más rápido. Desafortunadamente, rsyncrealmente no ayudará aquí, ya que necesitará leer el archivo en ambos lados para encontrar el delta. En cambio, necesita algo que haga un seguimiento del delta a medida que cambia el archivo ... La mayoría de los enfoques aquí son específicos de la aplicación. Pero es posible que pueda armar algo con, por ejemplo, el mapeador de dispositivos (vea el nuevo objetivo de la era dm ) o btrfs.
  • Si está copiando los mismos datos en varias máquinas, puede usar algo como udpcast para enviarlo a todas las máquinas a la vez.

Y, como notas que no eres el administrador del sistema, supongo que eso significa que tienes un administrador del sistema. O al menos alguien responsable del servidor de archivos y la red. Probablemente debería preguntarle a él / ella / ellos, deberían estar mucho más familiarizados con los detalles de su configuración. Sus administradores de sistemas deberían al menos poder decirle qué tasa de transferencia puede esperar razonablemente.

derobert
fuente
+1 para iostat -kx 10 :-)
n611x007
16

Posiblemente, esto podría ser una alternativa más rápida, y no obstruirá la red durante dos días: tome uno o dos discos USB grandes (USB 3 si lo tiene) o discos FireWire, conéctelos al servidor y copie los archivos a el disco. Lleve el disco a su máquina local. Copie los archivos a la máquina.

Thomas Padron-McCarthy
fuente
23
Sneakernet ( en.wikipedia.org/wiki/Sneakernet ) puede ser muy rápido: nunca subestimes el ancho de banda de una camioneta llena de cintas que se precipitan por la carretera.
SplinterReality
10

Su definición de eficiente es al revés. Una implementación más eficiente desperdicia menos tiempo de CPU. En la copia local, está promediando unos 74 MB / s de rendimiento (lectura + escritura), que es casi tan bueno como un disco duro.

psusi
fuente
1
Ups Cuando dije "eficiente", quise decir "rápido".
Andrew
10

Si tiene acceso directo SSH (o SFTP) (pregunte a su administrador de sistemas), puede usar scpcon compresión ( -C):

scp -C you@server:/path/to/yourfile .

Por supuesto, eso solo es útil si el archivo es compresible, y esto usará más tiempo de CPU, ya que usará cifrado (porque está sobre SSH) y compresión.

Reinstalar a Mónica
fuente
En este caso, sería útil deshabilitar el cifrado. Recuerde que estamos tratando de hacer la copia más rápido .
lgeorget
3
@lgeorget Sospecho que la sobrecarga del cifrado no será significativa, considerando lo lentos que son los discos duros. Pensé en agregar algo al respecto -c none, pero eso parece no ser estándar .
Vuelva a instalar Mónica
1
Estamos tratando con archivos ~ 20G, por lo que es bastante ineficiente usar cifrado si no es necesario.
lgeorget
1
@lgeorget Encryption se puede hacer mucho más rápido que el rendimiento que está obteniendo, por lo que no ralentizará nada. Pero parece innecesario pasar por SSH aquí. Si solo necesita compresión, seguramente hay otras herramientas.
Thomas
@Thomas La ventaja de SSH es que si se supone que debes tener acceso al servidor remoto, es casi seguro que esté ejecutando SSH. Otra opción sería comprimir el archivo localmente, copiarlo en el servidor, luego sshdescomprimirlo ..
Vuelva a instalar Monica el
8

Lo cpmás probable es que la implementación no sea un cuello de botella. Intente observar el uso de IO a través iotopdel servidor y el nodo del clúster. Esto le dará una idea de dónde puede mejorar el rendimiento.

Otro consejo es evitar copiar los mismos datos del mismo host. Por ejemplo, si tiene un archivo 20G idéntico para distribuir desde el servidor de archivos a través de la red a todos los nodos del clúster, funcionará mucho más rápido si copia los archivos de manera punto a punto en lugar de un servidor a todos los clientes. Es un poco más complicado de implementar, pero incluso puedes intentar usar alguna línea de comando p2p como el hub de conexión directa.

Si dentro de esos archivos 20G, alguna parte es común y otras son específicas del nodo del clúster, considere dividirlo en partes comunes y específicas, y luego distribuya la parte común en forma p2p.

Michał Šrajer
fuente
1
Si está en una LAN, debería poder hacer multidifusión en lugar de punto a punto. Que debería ser más rápido y menos carga en la red.
derobert
8

La naturaleza / contenido de esos archivos puede hacer alguna diferencia. Comprendí que necesita copiar 200 archivos, ~ 20 GB cada uno, de una computadora a otra, ¿es eso?

Si esos archivos son comprimibles o tienen piezas similares / idénticas, tiene dos enfoques:

  • comprímalos antes de copiarlos o cree un túnel entre las computadoras con la habilitación zip habilitada. Entonces, si la red es el cuello de botella, será un poco más rápido

  • si los archivos son muy similares o comparten algunos elementos de contenido común entre ellos, intente usar rsync . Pasará algún tiempo buscando lo que es común entre los archivos, y no necesitará copiarlo literalmente , porque lo reconstruirá en función de lo que es común.

editar

¿Necesitarás copiar esos archivos muchas veces? (como una copia -> use esos archivos -> cambie algo en los archivos de la computadora A -> copie los archivos nuevamente a la computadora B)

Si es así, rsync será útil, porque intentará detectar lo que es igual entre las versiones y no copiará lo que no ha cambiado.

Y un tercer método: si lo anterior es correcto (cambios en el archivo, luego copie todos los archivos nuevamente en la segunda computadora), puede intentar binary diffcambiar en la segunda computadora lo que se cambió en la primera computadora.

woliveirajr
fuente
6

Veo lo siguiente aquí, el cifrado no es una buena idea, ya que podría AUMENTAR la cantidad de datos que se transferirán.

Si está copiando entre dos sistemas, entonces el cuello de botella es, por supuesto, la conexión entre los servidores.

Si está copiando localmente, observe cómo va el proceso, es de UN SOLO subproceso, por lo tanto, las utilidades estándar de Linux usan:

- for all blocks in a file
      read a block
      write a block

NO hay concurrencia a esta operación.

Para acelerar las cosas, puede usar algo como esto:

  buffer -i infile -o outfile -m size-of-shared-memory-default-1MByte

Consulte la página del comando man buffer (1) para obtener más información.

El comando buffer configura dos procesos para ejecutar el proceso de copia simultáneamente: uno para leer y el otro para escribir, y utiliza un buffer de memoria compartida para comunicar los datos entre los dos procesos. El búfer de memoria compartida es su búfer circular clásico que evita la sobrescritura de datos no escritos y la escritura de datos ya escritos. He usado este programa para cortar alrededor del 10-20% del tiempo de copia en transferencias del disco a la cinta.

mdpc
fuente
En realidad, hay concurrencia en "leer un bloque / escribir un bloque" porque "escribir un bloque" en realidad solo lo coloca en el búfer del núcleo, y el núcleo maneja la escritura del bloque real en segundo plano (al menos, hasta que empiece a agotarse de RAM). O si está utilizando O_DSYNC / O_SYNC por alguna razón.
derobert
3

¿Por qué no probar un algoritmo de propagación P2P si necesita actualizar todo su clúster al mismo tiempo?

https://github.com/lg/murder es lo que usa Twitter

Hay BTSync que puedes probar también.

Gui13
fuente
1

Si está copiando los mismos conjuntos de archivos con frecuencia desde su computadora local al servidor con pequeños cambios aquí y allá. Puede acelerar la transferencia utilizando rsync o un DVCS (por ejemplo, hg o git).

git o hg pueden realizar un seguimiento y detectar deltas y solo transferir esos deltas. En caso de usar un git, ya que ambos lados tienen un historial completo del repositorio, descubrir el delta es muy barato.

rsync utiliza una forma de algoritmo de suma de comprobación continua para detectar deltas sin conocimiento previo de lo que hay al otro lado. Si bien rsync requiere más trabajo para calcular los deltas, no necesita almacenar todo el historial del archivo.

Lie Ryan
fuente
1

Es posible que desee intentar empaquetar todos los archivos en un solo archivo (no es necesario comprimirlo). En mi experiencia, copiar ese archivo es más rápido que copiar una gran cantidad de archivos individuales

Munim
fuente
3
Buena observación genérica, pero como la pregunta dice "~ 200 archivos grandes - cada ~ 20 GB", no creo que esto pueda considerarse una respuesta real a este problema.
manatwork
@manatwork ah .. no leí claramente. Pensé que tenía 200 archivos por un total de 20 gb
Munim
0

Prueba bbcp . Las pruebas en nuestro entorno revelaron que cp tenía algún tipo de gobernador incorporado. Solo tenga cuidado porque cuando despega el gobernador, puede marcar su servidor y causar una interrupción. En nuestro caso, estábamos desconectando el servidor para hacer la copia, así que más rápido era mejor. Esto mejoró el tiempo de transferencia varias horas.

James Shewey
fuente
0

Asegúrese de que los archivos de destino no existan antes de copiar.

A veces es sorprendente la cantidad de tiempo que se gasta incluso copiando en el mismo host (sin red involucrada).

Vea mi respuesta a otra pregunta de CP aquí . En pocas palabras, sobrescribir un archivo existente es mucho más lento que truncarlo o desvincularlo primero, y luego copiarlo. Este último es 8 veces más rápido para un archivo de 1.2GB.

Pierre D
fuente