У мене є 1000000 файлів 4-20 кб в режимі. Мені потрібно скопіювати цей реж. Але здається, що я повинен шукати кожен файл, тому це займає досить багато часу.
Чи є спосіб, яким я можу пришвидшити це?
На даний момент я думаю, що якщо мені вдасться отримати блоки дисків, які займають ці файли, я міг би сортувати їх, об'єднати ті блоки, які були близькими (враховуючи, що послідовне зчитування часто швидше, ніж шукати), і прочитати ці блоки, щоб вони були в оперативній пам'яті кеш (у мене є 32 Гб оперативної пам’яті) перед тим, як зробити копію.
Але для цього мені потрібен спосіб визначити, на яких блоках файли.
Я використовую EXT4 на магнітному пристрої (тобто не на SSD).
Редагувати:
Це повинно працювати, але це не так:
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'
При тестуванні його на великому файлі він не кешує файл.
Edit2:
Ось кілька орієнтирів. Кеш промивався ( echo 3 >/proc/sys/vm/drop_caches
) між кожним прогоном. Вимірювання, проведені за допомогою 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
То що ми можемо навчитися з цього?
Здається, сортування за inode - хороша ідея. Але, мабуть, паралелізація декількох cp
підвищує продуктивність ще більше. Варто підкреслити, що джерелом foo/
є магнітний диск, тому це атакує міф про те, що паралелізація вводу / виводу на одне шпиндель не прискорить введення / виведення: Паралельне чітке та послідовне прискорення копіювання тут.
cp -r /mnt/dir1 /mnt/dirdest
чи щось подібне cp /mnt/dir1/* /mnt/dirdest
?