it-swarm-ru.tech

Как я могу лучше всего скопировать большое количество маленьких файлов по scp?

У меня есть каталог с несколькими гигабайтами и несколькими тысячами маленьких файлов. Я хочу скопировать его по сети с помощью scp более одного раза. Процессорное время на компьютерах источника и назначения дешевое, но накладные расходы сети, добавленные путем копирования каждого файла по отдельности, огромны. Я хотел бы распаковать и отправить его, но исходному компьютеру недостаточно места на диске.

Есть ли способ для меня, чтобы передать вывод tar -czf <output> <directory> для scp? Если нет, есть ли другое простое решение? Моя исходная машина старая (SunOS), поэтому я бы не стал устанавливать на нее какие-либо вещи.

63
nmichaels

Вы можете передать tar через сеанс ssh:

$ tar czf - <files> | ssh [email protected] "cd /wherever && tar xvzf -"
110
pdo

Tar со сжатием bzip2 должен брать на себя как большую нагрузку на сеть, так и на процессор.

$ tar -C /path/to/src/dir -jcf - ./ | ssh [email protected] 'tar -C /path/to/dest/dir -jxf -'

Не используя -v потому что вывод на экран может замедлить процесс. Но если вы хотите подробный вывод, используйте его на локальной стороне tar (-jcvf), а не в удаленной части.

Если вы неоднократно копируете один и тот же путь назначения, например, обновляете резервную копию, ваш лучший выбор - rsync со сжатием.

$ rsync -az -e ssh /path/to/src/dir/ [email protected]:/path/to/dest/dir/

Обратите внимание, что пути src и dest заканчиваются символом /. Опять же, не используя -v а также -P Флаги специально, добавьте их, если вам нужен подробный вывод.

23
forcefsck

используйте rsync , он использует SSH.

Применение:

rsync -aPz /source/path destination.server:remote/path

Коммутаторы rsync заботятся о сжатии и информации I-узла. -P отображает прогресс каждого файла.

Ты можешь использовать scp -C, который включает сжатие, но, если возможно, используйте rsync.

16
polemon

Вы можете запустить tar на обоих концах, используя ssh. scp является частью семейства добродетелей ssh, так что вы, вероятно, имеете его с обеих сторон.

 8:03AM 12 % tar cf - some_directory | ssh dest_Host "tar xf -"

Может также быть способ использовать gzip или bzip2 в конвейере, чтобы уменьшить сетевой трафик.

3
Bruce Ediger

Ответ @ pdo хорош, но можно увеличить скорость с помощью буфера и хорошего сжатия и добавить индикатор выполнения.

Часто узким местом является сеть, и скорость меняется со временем. Следовательно, это помогает буферизовать данные перед их отправкой по сети. Это можно сделать с помощью pv.

Кроме того, обычно можно увеличить скорость с надлежащим алгоритмом сжатия. Gzip (как использовалось выше) - это алгоритм быстрого сжатия, но в целом zstandard (zstd) (и для высоких коэффициентов сжатия LZMA/LZMA2 (xz) будет сжиматься лучше и быстрее одновременно . Новые xz и zstd уже имеют многоядерную поддержку. Для использования gzip с несколькими ядрами можно использовать pigz.

Вот пример отправки данных с индикатором выполнения, буферизацией и zstandard сжатием по сети:

tar cf - . | pv -perabs $(du -sk . | cut -f 1)K | zstd -14 --long=31 -T0 | pv -qCB 512M | ssh [email protected] "cd /wherever && pv -qCB 512M | zstd -cd -T0 --long=31 | tar xf -"

Первый pv должен показать прогресс ( p ), расчетное время ( e ), скорость передачи ( r ), средняя скорость ( a ), общее количество переданных байтов ( b ). Общий размер оценивается с помощью du и ​​добавляется к параметру размера ( s ). Прогресс измеряется до сжатия и буферизации, поэтому он не очень точен, но все же полезен.

zstd используется с настройкой сжатия 14 . Это число может быть уменьшено или увеличено в зависимости от скорости сети и процессора, поэтому zstd немного быстрее скорости сети. С четырьмя ядрами на процессоре Haswell 3,2 ГГц 14 дает скорость около 120 МБ/с. В этом примере используется длинный режим 31 (используется окно размером 2 ГБ, требуется много оперативной памяти, но очень хорошо, например, для сжатия дампов базы данных) , Опции T0 устанавливают количество потоков равным количеству ядер. Следует помнить, что вместе с длинным режимом эти настройки используют много памяти.

Проблема с zstd заключается в том, что большинство операционных систем не поставляются с версией> = 1.3.4. Эта версия необходима для правильной многоядерности и длительной поддержки. Если он недоступен, его можно скомпилировать и установить с https://github.com/facebook/zstd всего лишь с помощью make -j4 && Sudo make install. Вместо zstd можно также использовать xz или pigz. xz медленный, но сжимается очень хорошо (хорошо по сравнению с медленными соединениями), pigz/gzip быстр, но сжимается не очень хорошо. pv затем используется снова, но для буферизации (q для тихого режима, C для режима без сращивания [всегда необходим для буферизации] и B для установки) размер буфера).

В этом примере буфер также используется на стороне получателя. Это часто не нужно (поскольку скорость распаковки и записи на жесткий диск в большинстве случаев выше, чем скорость сети), но обычно также не наносит вреда.

3
Fabian Heller

Если у вас есть gzip на обоих концах: sourcehost$ cd sourcedir && tar cf - . | gzip -c - | ssh [email protected] "cd destinationdir && gzip -c -d | tar xf -"

Если у вас нет gzip на исходном компьютере, убедитесь, что вы распаковали его в месте назначения: sourcehost$ cd sourcedir && tar cf - . | compress | ssh [email protected] "cd destdir && uncompress | tar xf -"

Это было бы быстрее, чем сначала сжать его, затем отправить, затем разархивировать, и это не требует дополнительного дискового пространства с обеих сторон. Я выбрал флаг сжатия (z) на tar, потому что он, вероятно, отсутствует на древней стороне.

2
MattBianco

Или вы можете сделать это наоборот, если вам нужно. Это означает, что нужно перетаскивать архив по сети, а не выдвигать его, как было предложено. Это не решает повторяющуюся часть вашего вопроса, и для этого лучше всего подойдет rsync, но, вероятно, есть ключи tar, чтобы помочь.

Итак на локальной машине:

ssh remote 'tar zcf - /etc/resolv.conf' | tar zxf -

Лучше всего сначала оказаться в нужном каталоге, либо в конце вы должны использовать ключ -C команды unntaring.

Просто упомянуть об этом на случай, если это необходимо. Это для меня, так как в моей ситуации мой локальный сервер отстает от nat, поэтому потребовалось бы некоторое сетевое размышление, чтобы иметь возможность сделать это так, как было упомянуто ранее.

НТН

2
DaveQB

Или смонтируйте удаленную файловую систему через sshfs

sshfs [email protected]:/path/on/remote /path/on/local
1
ivanivan

Хотя он и не самый элегантный, особенно потому, что он не копирует один Zip или tar-файл и вдвойне, так как это не помогает уменьшить нагрузку на сеть, мой единственный выбор - использовать scp -r:

-r

      Рекурсивно копировать целые каталоги. Обратите внимание, что scp следит за символическими ссылками, встречающимися в обходе дерева.
Источник: scp (1)

У меня были проблемы с нехваткой места на диске с архивным файлом 30 Гб. Я думал, что gunzip может сделать это встроенным, то есть, удалив оригинал, так как он был разархивирован (и я, возможно, пропустил результат Google), но я ничего не смог найти.

Наконец, потому что я устал от попыток несколько раз ждать, пока новый TAR или Zip файл будет завершен, tar'ing или zip, я, наконец, просто сделал:

  1. С исходного сервера/ПК/ноутбука перейдите в каталог, где находится ваша папка с многочисленными файлами/папками.
  2. scp -r source_folder_nameyourname@yourservername:destination_folder_name

Тогда просто возьмите немного пива, кофе или попкорна и подождите. Хорошо, что scp будет повторять попытки, если сетевое соединение "зависнет". Просто надеюсь, что он не исчезнет полностью.

1
JGlass