Параллельное копирование файлов


9

У меня есть список файлов, которые мне нужно скопировать в системе Linux - каждый файл имеет размер от 10 до 100 ГБ.

Я только хочу скопировать в локальную файловую систему. Есть ли способ сделать это параллельно - с несколькими процессами, каждый из которых отвечает за копирование файла - простым способом?

Я могу легко написать многопоточную программу для этого, но мне интересно узнать, существует ли для этого низкоуровневый метод Linux.


1
Параллельное копирование файлов не принесет существенного ускорения. (По крайней мере, в теории это не должно быть.)
Тарнай Кальман


1
@ TarnayKálmán, если у вас нет кластерной, оверлейной, RAID-системы или файловой системы в стиле «без боязни» или любого из перечисленного выше в относительно высокой задержке или загруженной сети; или рабочая нагрузка, в которой задержка для файла составляет значительную часть времени копирования для этого файла (1e5 + очень маленькие файлы, серверные части с адресацией содержимого и т. д.). Параллельная обработка была бы чрезвычайно полезной в таких ситуациях.
Rvalue

Ответы:


11

Если ваша система не перегружена им (например, возможно, файлы находятся в кеше), тогда GNU Parallel http://www.gnu.org/software/parallel/ может работать для вас:

find . -print0 | parallel -0 -j10 cp {} destdir

Это будет работать 10 одновременных cpсекунд.

Pro: это просто читать.

Против: GNU Parallel не является стандартным на большинстве систем - поэтому вам, вероятно, придется установить его.

Посмотрите вступительное видео для получения дополнительной информации: http://www.youtube.com/watch?v=OpaiGYxkSuQ

См. Также https://oletange.wordpress.com/2015/07/04/parallel-disk-io-is-it-faster/ для обсуждения параллельного дискового ввода-вывода.


3

Для этого нет механизма низкого уровня по очень простой причине: это приведет к снижению производительности вашей системы. При использовании дисков с дисками каждая запись будет бороться за размещение головки, что приводит к массовому ожиданию ввода-вывода. При использовании твердотельных накопителей это приведет к насыщению одной или нескольких системных шин, что вызовет другие проблемы.


Ошибка, которая, кажется, не имеет место с одним cp в настоящее время, я уверен, что есть удачная среда для нескольких параллельных "cp's", при которых ваш канал ввода / вывода не становится полностью насыщенным ...
Джон

1
Насыщенный автобус - это счастливый автобус. Пропускная способность в режиме ожидания - это потеря пропускной способности.
Rvalue

3

Как уже упоминалось, это ужасная идея. Но я считаю, что каждый должен иметь возможность реализовать свои собственные ужасные планы, ооочень ...

for FILE in *;do cp $FILE <destination> &;done

Звездочку можно заменить регулярным выражением ваших файлов или, $(cat <listfile>)если они есть в текстовом документе. Амперсанд запускает команду в фоновом режиме, поэтому цикл будет продолжаться, порождая больше копий.

Как уже упоминалось, это полностью уничтожит ваш ввод-вывод. Так что ... я бы не советовал это делать.

- Кристофер Карел


3

Единственный ответ, который не повлияет на скорость отклика вашей машины, - это не просто «копия», а очень быстрый. Если вы не будете редактировать файлы в новом или старом месте, то жесткая ссылка по сути похожа на копию, и (только), если вы находитесь в одной файловой системе, они создаются очень и очень быстро.

Проверьте cp -lи посмотрите, будет ли это работать на вас.


2

Вот инструмент распределенного / параллельного и децентрализованного копирования файлов, который разбивает файл на части и копирует все куски параллельно. Вероятно, это поможет вам, только если у вас есть SSD, который поддерживает несколько потоков, или какая-то установка с несколькими головками дисков.

https://github.com/hpc/dcp


1

Для людей, которые думают, что это не очень хорошая идея, я бы сказал, что это зависит. У вас может быть большая рейдовая система или параллельная файловая система, которая обеспечит действительно лучшую производительность, чем один процесс cp. Тогда да, вам нужно использовать «параллельный инструмент».

Давайте возьмем этот пример:

timeout 10 strace -e write -c cp /dev/zero /dev/null
strace: Process 24187 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
100.00    0.655188           4    166222           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.655188                166222           total

тогда это

timeout 0.01 strace -e write  cp /dev/zero /dev/null
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
write(4, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 65536) = 65536
strace: Process 24567 detached

поэтому каждая запись системного вызова, созданная "cp", в этом случае составляет 64 КБ, и в течение 10 секунд в моей системе я могу предоставить эту пропускную способность: 65536 * 166222/10 = 1089352499 = ~ 1,08 ГБ / с.

Теперь давайте запустим эту рабочую нагрузку с 2 процессами (у меня 4 ядра, но мой рабочий стол используется для других вещей, и здесь это только пример):

timeout 10 strace -e write -c cp /dev/zero /dev/null & timeout 10 strace -e write -c cp /dev/zero /dev/null &  wait
[1] 26106
[2] 26107
strace: Process 26113 detached
strace: Process 26112 detached
% time     seconds  usecs/call     calls    errors syscall
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
------ ----------- ----------- --------- --------- ----------------
100.00    0.624108           4    162616           write
100.00    0.638468           4    162451           write
------ ----------- ----------- --------- --------- ----------------
100.00    0.624108                162616           total
100.00    0.638468                162451           total
------ ----------- ----------- --------- --------- ----------------
[1]-  Exit 124                timeout 10 strace -e write -c cp /dev/zero /dev/null

Итак, мы видим, что мы можем почти удвоить производительность, используя 2 ядра для запуска этого.

Так что если мы находимся в контексте, отличном от диска 1xHard от диска 1xHard, но с массивом raid (или несколькими NVMe, так что я не согласен с этим, но я работаю над этим каждый день), это определенно показывает лучшую производительность при использовании нескольких общих в параллельно.


-1

Вы должны попробовать это:

    $ seq 3 | параллельный cp -v / etc / passwd passwd {}

Это скопирует файл passwd 3 раза из каталога / etc / в ваш $ HOME

Или, если ваш файл находится в вашем домашнем каталоге

    $ seq 3 | параллельный cp -v passwd {, {}}

Это скопирует файл passwd 3 раза в ваш $ HOME

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.