Прискорити копіювання 1000000 невеликих файлів


11

У мене є 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?
maxschlepzig

Лише файли, але не однакова файлова система: cp -r / mnt / dir1 / mnt2 / dirdest
Ole Tange

btw, я не думаю, що це допомагає, якщо паралельно виконувати доступ до жорсткого диска, коли ви хочете мінімізувати прагнення до диска.
maxschlepzig

Я написав програму, яка впорядковує файли за їх кількістю (швидше за все, це є появою на диску) тут: github.com/nh2/diskorder
nh2

Відповіді:


9

Якщо припустити, що

  • Повернені записи readdirне сортуються за номером inode
  • читання файлів у порядку inode зменшує кількість операцій пошуку
  • вміст більшості файлів знаходиться в початковому виділенні 8k (оптимізація ext4), що також повинно дати менше операцій пошуку

ви можете спробувати прискорити копіювання за допомогою копіювання файлів у порядку inode.

Це означає використовувати щось подібне:

$ cd /mnt/src
$ ls -U -i | sort -k1,1 -n | cut -d' ' -f2- > ~/clist
$ xargs cp -t /mnt2/dst < ~/clist

@mikeserv, що ти маєш на увазі? ls -Uнедостатньо, тому що він не сортується за номерами inode ... і чому я хочу це робити -1?
maxschlepzig

@mikeserv, "в порядку каталогу" не є таким, як порядок inode! У такому випадку вам не доведеться використовувати для цього інше слово. Те, що вам здається дивним, не має значення. Я навіть тестував це на файловій системі ext4. І там порядок каталогів дійсно відрізняється від порядку inode. -1просто перелічується "один файл на рядок" - це не допомагає з новими рядками у назви файлів. Для цього можна скористатися find -print0/xargs -O.
maxschlepzig

@mikeserv, про що ти говориш? Приклад лічильника: mkdir tmp; cd tmp; touch foo"<RETURN>"bar; lsдрукує "foo? Bar". ls -1Також «Foo? Бар» друкує. А ls -1 | wc -lвідбитки "2". A find -lsдрукує ім'я файлу як "./foo\nbar". cp -i Ls -1` x` зазнає невдачі з "ф: мішень" х "не є каталогом.
maxschlepzig

Чорт - ти навчаєш мене ліворуч і праворуч! -qробить те, що я думав, що -1буде! Знову мої вибачення - не кажучи вже про подяку.
mikeserv

4

GNU tar- за paxтрадицією - самостійно обробляє жорсткі посилання.

cd "$srcdir" ; tar --hard-dereference -cf - ./* |
    tar -C"${tgtdir}" -vxf -

Таким чином, у вас є лише два tarпроцеси, і вам не потрібно продовжувати викликати cpзнову і знову.


2

У аналогічній відповіді на відповідь @ maxschlepzig ви можете проаналізувати вихід filefragдля сортування файлів у порядку, коли їх перші фрагменти з'являються на диску:

find . -maxdepth 1 -type f |
  xargs -d'\n' filefrag -v |
  sed -n '
    /^   0:        0../ {
      s/^.\{28\}\([0-9][0-9]*\).*/\1/
      h
      }
    / found$/ {
      s/:[^:]*$//
      H
      g
      s/\n/ /p
      }' |
    sort -nk 1,1 |
    cut -d' ' -f 2- |
    cpio -p dest_dir

MMV з вищевказаним sedсценарієм, тому не забудьте ретельно перевірити.

В іншому випадку все, що ви робите, filefrag(частина e2fsprogs) буде набагато швидшим у використанні, ніж hdparmце може зайняти кілька аргументів файлів. Просто накладні витрати в hdparm1 000 000 разів додадуть багато накладних витрат.

Також, мабуть, було б не так складно написати perlскрипт (або програму на C), FIEMAP ioctlдля кожного файлу створити відсортований масив блоків, які слід скопіювати, а файли належать, а потім скопіювати все в порядку зчитування розміру кожного блоку з відповідного файлу (будьте обережні, щоб не вичерпалися дескриптори файлів).


Це добре, див. Також home.ifi.uio.no/paalh/publications/files/ipccc09.pdf для документа, який описує підхід та показує ~ 4-кратне прискорення tarдля їх файлів.
nh2

1
Я надіслав електронною поштою авторам цього документа, запитуючи, чи можна випустити їх qtarяк відкритий код; зараз це за адресою github.com/chlunde/qtar
nh2
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.