Déplacement de 2 To (fichiers 10 mil + dirs), quel est mon goulot d'étranglement?

21

Contexte

Je suis sorti de l' espace sur /home/dataet nécessité de transférer /home/data/repoà /home/data2.

/home/data/repocontient 1 million de répertoires, chacun contenant 11 répertoires et 10 fichiers. Il totalise 2 To.

/home/dataest sur ext3 avec dir_index activé. /home/data2est sur ext4. Exécution de CentOS 6.4.

Je suppose que ces approches sont lentes en raison du fait qu'il y repo/a 1 million de dirhams directement en dessous.


Tentative 1: mvrapide mais interrompue

Je pourrais faire si cela avait fini:

/home/data> mv repo ../data2

Mais il a été interrompu après le transfert de 1,5 To. Il écrivait à environ 1 Go / min.

Tentative 2: rsyncanalyse après 8 heures de création de la liste des fichiers

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

Il a fallu plusieurs heures pour créer la «liste de fichiers incrémentielle», puis elle transfère à 100 Mo / min.

Je l'annule pour essayer une approche plus rapide.

Tentative 3a: se mvplaint

Le tester sur un sous-répertoire:

/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

Je ne sais pas de quoi il s'agit, mais cpje peux peut- être me renflouer.

Tentative 3b: cpn'aboutit à rien après 8 heures

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

Il lit le disque pendant 8 heures et je décide de l'annuler et de revenir à rsync.

Tentative 4: rsyncanalyse après 8 heures de création de la liste des fichiers

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

J'avais l'habitude de --remove-source-filespenser que cela pourrait être plus rapide si je commence le nettoyage maintenant.

Il faut au moins 6 heures pour créer la liste des fichiers, puis il transfère à 100-200 Mo / min.

Mais le serveur a été surchargé du jour au lendemain et ma connexion a été fermée.

Tentative 5: IL N'Y A PLUS QUE 300 Go À DÉPLACER POURQUOI EST-CE SI DOULEUR

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

A nouveau interrompu. Le -Wsemblait presque faire « envoyer la liste des fichiers supplémentaires » plus rapide, ce qui à mon sens ne devrait pas donner un sens. Quoi qu'il en soit, le transfert est horriblement lent et j'abandonne celui-ci.

Tentative 6: tar

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

Essayant essentiellement de tout recopier mais en ignorant les fichiers existants. Il doit parcourir 1,7 To de fichiers existants, mais au moins, il lit à 1,2 Go / min.

Jusqu'à présent, c'est la seule commande qui donne une gratification instantanée.

Mise à jour: interrompu à nouveau, en quelque sorte, même avec nohup ..

Tentative 7: harakiri

Débat toujours sur celui-ci

Tentative 8: script de «fusion» avec mv

Le répertoire de destination contenait environ 120 000 répertoires vides, j'ai donc couru

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

Script 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

TERMINÉ.

Tim
la source
Vous avez raison, il faut trouver et énumérer chaque répertoire et 1 million de dirs va être pénible.
cybernard
2
Regardez le bon côté ... si c'était Windows, vous ne pourriez même pas avoir un million de sous-répertoires et toujours avoir un système d'exploitation qui fonctionne. :)
Jack
1
@Tim, pourquoi ne reviens-tu mvpas? En théorie, mvle fichier source ne sera supprimé que si le fichier de destination a été entièrement copié, il devrait donc fonctionner correctement. De plus, avez-vous un accès physique à la machine ou cela se fait-il via une sshconnexion?
terdon
5
Non ça ne peut pas. mvne pardonne pas, si vous continuez à être déconnecté, vous pourriez perdre des données et même ne pas le savoir. Comme vous l'avez dit, vous sshrecommencez, je recommande fortement d'utiliser screenet de détacher. Activez la journalisation et gardez une trace de cette façon. Si vous utilisez verbeux, cela prendra juste plus de temps. Essayez égalementiotop
justbrowsing
2
@justbrowsing - Bon appel screen. Je me posais des questions sur verbeux mais je suppose qu'il est trop tard pour redémarrer tarmaintenant. Et iotopa été mon utilitaire préféré ces derniers jours :)
Tim

Réponses:

6

Avez-vous déjà entendu parler de la division de grandes tâches en petites tâches?

/ home / data / repo contient 1 million de répertoires, chacun contenant 11 répertoires et 10 fichiers. Il totalise 2 To.

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/

(...)

Temps de pause café.

Ярослав Рахматуллин
la source
1
L'avantage sur lequel je souligne vaguement est que vous suivez manuellement la progression des petites pièces afin que la reprise de la tâche prenne moins de temps si une partie est abandonnée (car vous savez quelles étapes ont été effectuées avec succès).
Ярослав Рахматуллин
C'est essentiellement ce que j'ai fini par faire, sauf avec mv. Malheureusement, il n'y a pas de réunion d'outils mvet à rsyncmi - chemin.
Tim
4

Voici ce qui se passe:

  • Initialement, rsync construira la liste des fichiers.
  • La construction de cette liste est vraiment lente, en raison d'un tri initial de la liste des fichiers.
  • Cela peut être évité en utilisant ls -f -1 et en le combinant avec xargs pour construire l'ensemble de fichiers que rsync utilisera, ou en redirigeant la sortie vers un fichier avec la liste de fichiers.
  • Si vous passez cette liste à rsync au lieu du dossier, rsync commencera à fonctionner immédiatement.
  • Cette astuce de ls -f -1 sur des dossiers contenant des millions de fichiers est parfaitement décrite dans cet article: http://unixetc.co.uk/2012/05/20/large-directory-causes-ls-to-hang/
maki
la source
1
Pouvez-vous donner un exemple d'utilisation de ls avec rsync? J'ai une situation similaire mais pas identique. Sur la machine AI, rsyncd est en cours d'exécution et une grande arborescence de répertoires que je souhaite transférer sur la machine B (en fait, 90% du répertoire est déjà sur B). Le problème est que je dois le faire en utilisant une connexion mobile instable qui tombe fréquemment. Passer une heure à construire la liste des fichiers à chaque redémarrage est assez inefficace. De plus, B est derrière NAT que je ne contrôle pas, il est donc difficile de connecter A -> B, tandis que B -> A est facile.
db
D'accord avec @db. Si un exemple pouvait être donné, cela rendrait cette réponse beaucoup plus utile.
redfox05
1

Même si rsync est lent (pourquoi est-il lent? Peut-être que -z vous aidera), il semble que vous en ayez beaucoup déplacé, vous pouvez donc continuer à essayer:

Si vous avez utilisé --remove-source-files, vous pouvez ensuite effectuer un suivi en supprimant les répertoires vides. --remove-source-files supprimera tous les fichiers, mais y laissera les répertoires.

Assurez-vous simplement de NE PAS utiliser --remove-source-files avec --delete pour effectuer plusieurs passes.

Aussi pour une vitesse accrue, vous pouvez utiliser - en place

Si vous êtes expulsé parce que vous essayez de le faire à distance sur un serveur, allez-y et exécutez-le dans une session «écran». Au moins de cette façon, vous pouvez le laisser fonctionner.

Angelo
la source