Scp довольно медленно передает отдельные файлы. Как это сделать быстрее всего?
Причина, по которой мне нужна скорость, не в том, что мне нужно передать большое количество файлов. Я просто хочу, чтобы передача отдельных файлов (от начала до конца) завершилась быстро (так что rsync, tar и передача выполняются недостаточно быстро).
Существует множество ограничений на передачу большого количества небольших файлов. Некоторые из них уже упоминались: задержка в сети, скорость записи на диск и т. Д. Однако большинство из них можно оптимизировать лучше всего с помощью «rsync». Если файлы не существуют в месте назначения, и вы уверены, что процесс не будет прерван, использование tar, переданного в tar, будет очень эффективным:
cd /SOURCE/DIR && tar cf - . | ssh DESTINATIONHOST "cd /DESTINATION/DIR && tar xpvf -"
В корне вам нужно сгруппировать все файлы вместе, чтобы накладные расходы на запуск / завершение SCP происходили только один раз. Если вы выполните этот запуск / завершение работы для каждого файла, это будет очень неэффективно. Вышеупомянутая трубка "tar" сделает это. Фактически, для 90% всех случаев использования этого будет достаточно.
Этот «tar pipe» имеет преимущество параллельной обработки (чтение в одном процессе и запись в другом). Однако он ограничен несколькими вещами:
Вы можете обойти №2 с помощью различных приемов, таких как запуск двух или более процессов, каждый из которых работает с подмножеством файлов. Однако они несовершенны и немного небрежны.
TCP / IP труднее обойти, и он по-прежнему будет вашим пределом. Фактически, если вы настроите систему так, чтобы все было оптимально, TCP / IP не будет использовать весь канал. Каждый раз, когда TCP / IP считает, что нашел оптимальную скорость отправки, он пытается отправить еще немного, чтобы проверить, есть ли «больше места». Это не удастся, и TCP / IP немного отключится. Этот постоянный цикл увеличения / сбоя / отката означает, что поток TCP / IP будет чередоваться между 100% и 50% загрузкой ... в результате в среднем канал будет загружен на 75-80%. (ПРИМЕЧАНИЕ: это оценки ... выполните поиск в Google, чтобы найти точные числа. Дело в том, что это будет среднее значение 100%, а что-то не 100%, поэтому оно никогда не будет 100%) .
Если вы запустите несколько потоков TCP / IP, все они будут постоянно проходить через этот цикл увеличения / отказа / возврата. Если вам не повезет, они все столкнутся одновременно и отодвинутся очень далеко, в результате чего труба будет еще больше недоиспользована. Если вам повезет, они будут меньше сталкиваться, и вы получите график, который выглядит как множество прыгающих мячей ... все еще оставляя трубу недоиспользованной в совокупности.
Да, и если у вас есть одна машина, на которой реализация TCP / IP не имеет последних оптимизаций или не настроена идеально, она может отправить всю систему из строя.
Итак, если TCP / IP настолько ужасен, почему мы продолжаем его использовать? Это не так уж плохо в типичном случае множества различных типов трафика, разделяющих канал. Проблема здесь в том, что у вас есть очень конкретное приложение с очень конкретными требованиями. Поэтому вам нужно очень конкретное решение. К счастью, многие люди также находятся в вашем положении, поэтому такие решения становится все легче найти.
Системы вроде http://asperasoft.com/ использовать настраиваемый протокол поверх UDP / IP, чтобы они могли управлять алгоритмом отката / возврата. Они используют прямое исправление ошибок (FEC) так что небольшие ошибки не требуют повторной передачи (с TCP / IP небольшая ошибка является сигналом к отступлению), пользовательские схемы сжатия, дельта-копирование, а также собственные алгоритмы отката и системы ограничения скорости для достижения полной (или закрытой) -полное) использование трубы. Все они запатентованы, поэтому неясно, какие именно методы используют Aspera и их конкуренты и как именно они работают.
Есть много компаний, которые изобрели такие системы и либо сделали их частью своих собственных продуктов, либо продают их как коммерческий продукт.
В настоящее время я не знаю ни одной реализации с открытым исходным кодом. (Хочу исправить!)
Если это очень серьезная проблема и на ее решение стоит потратить деньги, попробуйте один из коммерческих продуктов. Или, если вы не можете изменить свое программное обеспечение, вам нужно будет купить трубу большего размера. К счастью, сетевые интерфейсы 10G и 40G дешевеют.
Уильям Глик разработал элегантное решение: распараллеливание rsync.
/bin/bash
# SETUP OPTIONS
export SRCDIR="/folder/path"
export DESTDIR="/folder2/path"
export THREADS="8"
# RSYNC TOP LEVEL FILES AND DIRECTORY STRUCTURE
rsync -lptgoDvzd $SRCDIR/ /$DESTDIR/
# FIND ALL FILES AND PASS THEM TO MULTIPLE RSYNC PROCESSES
cd $SRCDIR; find . -type f | xargs -n1 -P$THREADS -I% rsync -az % /$DESTDIR/%
# IF YOU WANT TO LIMIT THE IO PRIORITY,
# PREPEND THE FOLLOWING TO THE rsync & cd/find COMMANDS ABOVE:
# ionice -c2
Волшебство происходит в xargs -P
который автоматически разбивает ввод на $THREADS
куски. Быстро, эффективно, просто.
Видеть Оригинальная публикация Уильяма для подробностей.