Який найкращий спосіб виконати паралельну копію на Unix?


18

Мені звичайно доводиться копіювати вміст папки в мережевій файловій системі на свій локальний комп'ютер. У віддаленій папці є багато файлів (1000), але всі вони відносно невеликі, але через мережеві накладні витрати звичайна копія cp remote_folder/* ~/local_folder/займає дуже багато часу (10 хвилин).

Я вважаю, що файли копіюються послідовно - кожен файл чекає, поки попередній завершиться, перш ніж розпочнеться копія.

Який найпростіший спосіб збільшити швидкість цієї копії? (Я припускаю, що копію потрібно виконати паралельно.)

Збирання файлів перед копіюванням не обов'язково прискорить роботу, оскільки вони можуть бути збережені на різних дисках на різних серверах.


Перетягування файлів перед копіюванням значно прискорить роботу, тому що більше не потрібно буде "ти отримав цей файл", "так, я зробив", "ось наступний", "добре", ... Це ті "повороти", які сповільнюють вас.
Девід Шварц

Це, мабуть, швидкість диска, а не швидкість мережі, що є вашим обмежуючим фактором, і якщо це так, то виконання цього файлу паралельно зробить операцію повільнішою , а не швидшою, тому що ви змусите диск постійно шукати вперед і назад між файлами.
Joel Coehoorn

Хоча блискавка може бути не дуже хорошою ідеєю (запуск алгоритму стиснення понад 1000 тисяч файлів може зайняти трохи часу), тар може бути життєздатним.
Роб

@JoelCoehoorn все-таки є випадки, коли це не так: наприклад, кілька шпинделів + невеликі файли (або просто випадкові читання). У цьому сценарії допоможе "паралельний cp".
CAFxX

Відповіді:


8

Поки ви обмежуєте запущені команди для копіювання, ви, ймовірно, можете використовувати такий сценарій, як той, який опублікував Scrutinizer

SOURCEDIR="$1"
TARGETDIR="$2"
MAX_PARALLEL=4
nroffiles=$(ls "$SOURCEDIR" | wc -w)
setsize=$(( nroffiles/MAX_PARALLEL + 1 ))
ls -1 "$SOURCEDIR"/* | xargs -n "$setsize" | while read workset; do
  cp -p "$workset" "$TARGETDIR" &
done
wait

1
Зауваження про попередження, однак: Цей скрипт розбивається на назви файлів, що містять пробіли або символи глобусу.
slhck

@OldWolf - Чи можете ви пояснити, як працює цей сценарій? Наприклад, яка частина проводить паралелізацію?
dsg

3
@dsg: &наприкінці cpкоманди дозволяє whileциклу продовжувати та запускати наступну команду cp, не чекаючи. xargsКоманда передає імена файлів в групах (4) MAX_PARALLEL до whileпетлі.
RedGrittyBrick

Не працює для мене. Я не впевнений, що можна пришвидшити cp. Ви зобов’язано можете прискорити обчислення через багатопотоковість. Але я не думаю, що те ж саме стосується вирішення даних на жорсткому диску.
Adobe

9

Якщо у вас встановлений GNU Parallel http://www.gnu.org/software/parallel/, ви можете це зробити:

parallel -j10 cp {} destdir/ ::: *

Ви можете встановити GNU Parallel просто:

$ (wget -O - pi.dk/3 || lynx -source pi.dk/3 || curl pi.dk/3/ || \
   fetch -o - http://pi.dk/3 ) > install.sh
$ sha1sum install.sh | grep 3374ec53bacb199b245af2dda86df6c9
12345678 3374ec53 bacb199b 245af2dd a86df6c9
$ md5sum install.sh | grep 029a9ac06e8b5bc6052eac57b2c3c9ca
029a9ac0 6e8b5bc6 052eac57 b2c3c9ca
$ sha512sum install.sh | grep f517006d9897747bed8a4694b1acba1b
40f53af6 9e20dae5 713ba06c f517006d 9897747b ed8a4694 b1acba1b 1464beb4
60055629 3f2356f3 3e9c4e3c 76e3f3af a9db4b32 bd33322b 975696fc e6b23cfb
$ bash install.sh

Перегляньте вступні відео для паралельних GNU, щоб дізнатися більше: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1


3

Одним із способів було б використання rsync, який буде копіювати лише зміни - нові файли та змінені частини інших файлів.

http://linux.die.net/man/1/rsync

Запуск будь-якої форми паралельної операції копіювання, ймовірно, заповнить вашу мережу, і операція копіювання просто перемелить або зупиниться на вузьких місцях у вихідного чи призначеного диска.


2

Чесно кажучи, найкращим інструментом є gsutil Google. Він обробляє паралельні копії з рекурсією каталогу. Більшість інших методів, які я бачив, не можуть впоратися з рекурсією каталогу. Вони спеціально не згадують локальну файлову систему до копій локальної файлової системи у своїх документах, але це працює як принадність.

Це інший бінарний файл для встановлення, але, ймовірно, той, який ви вже можете запустити, враховуючи все прийняття хмарних служб сьогодні.


2

Паралельна rsync за допомогою find:

export SOURCE_DIR=/a/path/to/nowhere
export DEST_DIR=/another/path/to/nowhere

# sync folder structure first
rsync -a -f'+ */' -f'- *' $SOURCE_DIR $DEST_DIR

# cwd
cd $SOURCE_DIR

# use find to help filter files etc. into list and pipe into gnu parallel to run 4 rsync jobs simultaneously
find . -type f | SHELL=/bin/sh parallel --linebuffer --jobs=4 'rsync -av {} $DEST_DIR/{//}/'

у корпоративній локальній мережі одиночний rsync працює близько 800 Мбіт / с; з 6-8 робочих місць я можу отримати понад 2,5 Гбіт / с (за рахунок великого навантаження). Обмежений дисками.


0

Є багато речей, які, можливо, доведеться врахувати в залежності від топології. Але перш ніж почати замислюватися над складними рішеннями, ви можете просто спробувати розділити завдання на дві роботи і перевірити, чи скоротиться час, який потрібно:

Наступного разу спробуйте:

  cp remote_folder/[a-l]* ~/local_folder/ &
  cp remote_folder/[!a-l]* ~/local_folder/ &
  wait
  wait

(ви можете замінити [al] * на щось інше, що відповідає приблизно половині файлів - можливо, [0-4] * - залежно від вмісту папки)

Якщо час різко покращується, може бути важливіше перевірити, чи потрібно копіювати всі файли (яке відношення змінених файлів до всіх файлів?)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.