J'ai 1000000 fichiers de 4-20 ko dans un répertoire. J'ai besoin de copier ce répertoire. Mais il semble que je doive faire une recherche pour chaque fichier, donc cela prend un certain temps.
Existe-t-il un moyen d’accélérer cela?
Je pense actuellement que si je pouvais obtenir les blocs de disque que ces fichiers occupent, je pourrais les trier, fusionner les blocs qui étaient proches (étant donné que la lecture séquentielle est souvent plus rapide que la recherche) et lire ces blocs, afin qu'ils soient en RAM cache (j'ai 32 Go de RAM) avant de faire la copie.
Mais pour que cela fonctionne, j'ai besoin d'un moyen d'identifier les blocs sur lesquels se trouvent les fichiers.
J'utilise EXT4 sur un appareil magnétique (c'est-à-dire pas SSD).
Éditer:
Cela devrait fonctionner mais cela ne:
ls |
parallel -IOO --pipe "sudo parallel -j100 hdparm --fibmap {}'|tail -n +5'" |
sort -nk 2 |
perl -ane 'if($u+10000 < $F[1]) { print "$l ",($u-$l),"\n"; $l=$F[1] } $u=$F[2]' |
sudo parallel --colsep ' ' dd if=/dev/sda1 skip={1} bs=512 count={2} '| cat >/dev/null'
Lorsque vous le testez sur un gros fichier, il ne met pas le fichier en cache.
Edit2:
Voici quelques repères. Le cache a été vidé ( echo 3 >/proc/sys/vm/drop_caches
) entre chaque exécution. Mesures effectuées avec iostats -dkx 5
.
rsync -Hav foo/ bar/: 1800 KB/s
cp -a foo/ bar/: 3600 KB/s
cat sort-by-inode | parallel -j1 -X cp foo/{} bar/: 5000 KB/s
cat sort-by-inode | shuf | parallel -j1 -X cp foo/{} bar/: 3000 KB/s
cat sort-by-inode | shuf | parallel -j10 -X cp foo/{} bar/: 7000 KB/s
cat sort-by-inode | parallel -j10 -X cp foo/{} bar/: 8000 KB/s
cat sort-by-inode | parallel -j100 -X cp foo/{} bar/: 9000 KB/s
cat sort-by-inode | parallel -j500 -X cp foo/{} bar/: 10000 KB/s
Que pouvons-nous en tirer?
Il semble que le tri par inode soit une bonne idée. Mais il semble que la parallélisation de plusieurs cp
boosts de performances soit encore plus poussée. Il convient de souligner que la source foo/
est un disque magnétique, donc cela attaque le mythe selon lequel la parallélisation des E / S à une seule broche n'accélérera pas les E / S: la parallélisation accélère clairement et systématiquement la copie ici.
la source
cp -r /mnt/dir1 /mnt/dirdest
ou quelque chose commecp /mnt/dir1/* /mnt/dirdest
?Réponses:
En admettant que
readdir
ne sont pas triées par numéro d'inodevous pouvez essayer d'accélérer la copie en copiant les fichiers dans l'ordre des inodes.
Cela signifie utiliser quelque chose comme ça:
la source
ls -U
n'est pas suffisant car il ne trie pas par numéro d'inode ... et pourquoi devrais-je le vouloir-1
?-1
répertorie simplement «un fichier par ligne» - cela n'aide pas avec les retours à la ligne dans les noms de fichiers. Pour cela, vous pouvez utiliserfind -print0/xargs -O
.mkdir tmp; cd tmp; touch foo"<RETURN>"bar; ls
imprime 'foo? Bar'. Als -1
imprime également 'foo? Bar'. Als -1 | wc -l
imprime «2». Afind -ls
imprime le nom de fichier sous la forme './foo\nbar'. Uncp -i
ls -1` x` échoue avec 'cp: la cible' x 'n'est pas un répertoire'.-q
fait ce que je pensais-1
! Encore une fois, mes excuses - sans parler des remerciements.GNU
tar
- dans lapax
tradition - gère seul les liens physiques.De cette façon, vous n'avez que les deux
tar
processus et vous n'avez pas besoin de continuer à invoquercp
encore et encore.la source
Dans la même veine que la réponse de @ maxschlepzig , vous pouvez analyser la sortie de
filefrag
pour trier les fichiers dans l'ordre dans lequel leurs premiers fragments apparaissent sur le disque:MMV avec le
sed
script ci-dessus , alors assurez-vous de tester soigneusement.Sinon, quoi que vous fassiez,
filefrag
(une partie dee2fsprogs
) sera beaucoup plus rapide à utiliserhdparm
qu'il ne peut prendre plusieurs arguments de fichier. Le simple fait de courirhdparm
1 000 000 fois va ajouter beaucoup de frais généraux.De plus, il ne serait probablement pas si difficile d'écrire un
perl
script (ou un programme C) dans unFIEMAP
ioctl
fichier pour chaque fichier, de créer un tableau trié des blocs qui devraient être copiés et des fichiers auxquels ils appartiennent, puis de tout copier dans l'ordre en lire la taille de chaque bloc à partir du fichier correspondant (attention cependant à ne pas manquer de descripteurs de fichiers).la source
tar
pour leurs fichiers.qtar
en open source; c'est maintenant sur github.com/chlunde/qtar