Moviendo 2 TB (10 mil archivos + directorios), ¿cuál es mi cuello de botella?

21

Fondo

Me quedé sin espacio en /home/datay necesidad de la transferencia /home/data/repoa /home/data2.

/home/data/repocontiene 1M de directorios, cada uno de los cuales contiene 11 directorios y 10 archivos. Totaliza 2 TB.

/home/dataestá en ext3 con dir_index habilitado. /home/data2está en ext4. Ejecutando CentOS 6.4.

Supongo que estos enfoques son lentos debido al hecho de que repo/tiene 1 millón de directorios directamente debajo.


Intento 1: mves rápido pero se interrumpe

Podría haber terminado si esto hubiera terminado:

/home/data> mv repo ../data2

Pero se interrumpió después de que se transfirieron 1,5 TB. Estaba escribiendo a aproximadamente 1 GB / min.

Intento 2: se rsyncarrastra después de 8 horas de creación de la lista de archivos

/home/data> rsync --ignore-existing -rv repo ../data2

Se tardó varias horas en crear la 'lista de archivos incremental' y luego se transfiere a 100 MB / min.

Lo cancelo para intentar un enfoque más rápido.

Intento 3a: se mvqueja

Probándolo en un subdirectorio:

/home/data/repo> mv -f foobar ../../data2/repo/
mv: inter-device move failed: '(foobar)' to '../../data2/repo/foobar'; unable to remove target: Is a directory

No estoy seguro de qué se trata este error, pero quizás cppueda rescatarme ...

Intento 3b: cpno llega a ninguna parte después de 8 horas

/home/data> cp -nr repo ../data2

Lee el disco durante 8 horas y decido cancelarlo y volver a rsync.

Intento 4: se rsyncarrastra después de 8 horas de creación de la lista de archivos

/home/data> rsync --ignore-existing --remove-source-files -rv repo ../data2

Solía --remove-source-filespensar que podría hacerlo más rápido si empiezo la limpieza ahora.

Se tarda al menos 6 horas en crear la lista de archivos y luego se transfiere a 100-200 MB / min.

Pero el servidor estuvo cargado durante la noche y mi conexión se cerró.

Intento 5: SOLO 300GB DEJARON DE MOVERSE POR QUÉ ES TAN DOLOROSO

/home/data> rsync --ignore-existing --remove-source-files -rvW repo ../data2

Interrumpido de nuevo. La -Wcasi parecía tener "el envío de la lista de archivos incremental" más rápido, lo que a mi entender no debe tener sentido. De todos modos, la transferencia es terriblemente lenta y me doy por vencida con esta.

Intento 6: tar

/home/data> nohup tar cf - . |(cd ../data2; tar xvfk -)

Básicamente, intenta volver a copiar todo pero ignorando los archivos existentes. Tiene que vadear hasta 1.7TB de archivos existentes, pero al menos está leyendo a 1.2GB / min.

Hasta ahora, este es el único comando que brinda gratificación instantánea.

Actualización: interrumpido de nuevo, de alguna manera, incluso con nohup ..

Intento 7: harakiri

Todavía debatiendo este

Intento 8: guión de 'fusión' con mv

El directorio de destino tenía aproximadamente 120k directorios vacíos, así que corrí

/home/data2/repo> find . -type d -empty -exec rmdir {} \;

Guión Ruby:

SRC  = "/home/data/repo"
DEST = "/home/data2/repo"

`ls #{SRC}  --color=never > lst1.tmp`
`ls #{DEST} --color=never > lst2.tmp`
`diff lst1.tmp lst2.tmp | grep '<' > /home/data/missing.tmp`

t = `cat /home/data/missing.tmp | wc -l`.to_i
puts "Todo: #{t}"

# Manually `mv` each missing directory
File.open('missing.tmp').each do |line|
  dir = line.strip.gsub('< ', '')
  puts `mv #{SRC}/#{dir} #{DEST}/`
end

HECHO.

Tim
fuente
Tienes razón, tiene que encontrar y enumerar cada directorio y 1 millón de directorios será doloroso.
cybernard
2
Mire el lado positivo ... si fuera Windows, ni siquiera podría tener un millón de subdirectorios y todavía tener un sistema operativo que funcione. :)
Jack
1
@Tim, ¿por qué no vuelves mv? En teoría mv, solo eliminará un archivo de origen si el archivo de destino se ha copiado por completo, por lo que debería funcionar correctamente. Además, ¿tiene acceso físico a la máquina o se hace a través de una sshconexión?
terdon
55
No, no puede. mvno es indulgente, si sigues desconectado podrías perder datos y ni siquiera saberlo. Como dijiste que estás haciendo esto de nuevo ssh, te recomiendo usar screeny desconectar. Habilite el registro y realice un seguimiento de esa manera. Si está utilizando detallado, solo llevará más tiempo. Intente tambiéniotop
simplemente el
2
@justbrowsing - Buena llamada screen. Me preguntaba acerca de detallado, pero supongo que es demasiado tarde para reiniciar tarahora. Y iotopha sido mi utilidad favorita durante los últimos días :)
Tim

Respuestas:

6

¿Has oído hablar de dividir tareas grandes en tareas más pequeñas?

/ home / data / repo contiene 1M de directorios, cada uno de los cuales contiene 11 directorios y 10 archivos. Totaliza 2 TB.

rsync -a /source/1/ /destination/1/
rsync -a /source/2/ /destination/2/
rsync -a /source/3/ /destination/3/
rsync -a /source/4/ /destination/4/
rsync -a /source/5/ /destination/5/
rsync -a /source/6/ /destination/6/
rsync -a /source/7/ /destination/7/
rsync -a /source/8/ /destination/8/
rsync -a /source/9/ /destination/9/
rsync -a /source/10/ /destination/10/
rsync -a /source/11/ /destination/11/

(...)

Tiempo de pausa para el café.

Ярослав Рахматуллин
fuente
1
El beneficio que enfatizo vagamente es que realiza un seguimiento manual del progreso en partes pequeñas, de modo que reanudar la tarea tomará menos tiempo si se cancela alguna parte (porque sabe qué pasos se completaron con éxito).
Ярослав Рахматуллин
Esto es básicamente lo que terminé haciendo al final, excepto con mv. Lamentablemente no hay reunión de herramientas mvy a rsyncmitad de camino.
Tim
4

Esto es lo que está sucediendo:

  • Inicialmente, rsync construirá la lista de archivos.
  • La creación de esta lista es realmente lenta, debido a una clasificación inicial de la lista de archivos.
  • Esto puede evitarse usando ls -f -1 y combinándolo con xargs para construir el conjunto de archivos que rsync usará, o bien redirigiendo la salida a un archivo con la lista de archivos.
  • Al pasar esta lista a rsync en lugar de a la carpeta, rsync comenzará a funcionar de inmediato.
  • Este truco de ls -f -1 sobre carpetas con millones de archivos se describe perfectamente en este artículo: http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to-hang/
maki
fuente
1
¿Puedes dar un ejemplo de cómo usar ls con rsync? Tengo una situación similar pero no idéntica. En la máquina AI tengo rsyncd ejecutándose y un gran árbol de directorios que quiero transferir a la máquina B (en realidad, el 90% del directorio ya está en B). El problema es que tengo que hacer esto usando una conexión móvil inestable que frecuentemente cae. Dedicar una hora a crear la lista de archivos cada vez que reinicio es bastante ineficiente. Además, B está detrás de NAT que no controlo, por lo que es difícil conectar A -> B, mientras que B -> A es fácil.
db
De acuerdo con @db. Si se pudiera dar un ejemplo, esta respuesta sería mucho más útil.
redfox05
1

Incluso si rsync es lento (¿por qué es lento? Tal vez -z ayudará) parece que se ha movido mucho, por lo que podría seguir intentando:

Si usó --remove-source-files, podría hacer un seguimiento eliminando directorios vacíos. --remove-source-files eliminará todos los archivos, pero dejará los directorios allí.

Solo asegúrese de NO usar --remove-source-files con --delete para hacer múltiples pases.

También para aumentar la velocidad puede usar --inplace

Si te echan porque intentas hacer esto de forma remota en un servidor, continúa y ejecuta esto dentro de una sesión de 'pantalla'. Al menos de esa manera puedes dejarlo correr.

Angelo
fuente