rsync к нескольким адресатам, используя один и тот же список файлов?

22

Мне интересно, возможно ли rsync скопировать один каталог в несколько удаленных мест назначения за один раз или даже параллельно. (не обязательно, но было бы полезно.)

Обычно, что-то вроде следующего будет работать нормально:

$ rsync -Pav /junk user@host1:/backup
$ rsync -Pav /junk user@host2:/backup
$ rsync -Pav /junk user@host3:/backup

И если это единственный вариант, я воспользуюсь этим. Однако / junk находится на медленном диске с довольно большим количеством файлов, и перестройка списка файлов из ~ 12 000 файлов каждый раз мучительно медленна (~ 5 минут) по сравнению с реальной передачей / обновлением. Можно ли сделать что-то подобное, чтобы выполнить то же самое:

$ rsync -Pav /junk user@host1:/backup user@host2:/backup user@host3:/backup 

Спасибо за внимание!

Джесси
источник

Ответы:

12

Вот информация со страницы руководства для rsync о пакетном режиме.

ПАКЕТНЫЙ РЕЖИМ

Пакетный режим можно использовать для применения одного и того же набора обновлений ко многим идентичным системам. Предположим, что у каждого есть дерево, которое реплицируется на несколько хостов. Теперь предположим, что в это дерево исходных текстов были внесены некоторые изменения, и эти изменения необходимо распространить на другие узлы. Чтобы сделать это с помощью пакетного режима, rsync запускается с опцией write-batch, чтобы применить изменения, сделанные в исходном дереве, к одному из деревьев назначения. Опция write-batch заставляет rsync-клиент хранить в «пакетном файле» всю информацию, необходимую для повторения этой операции для других идентичных деревьев назначения.

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

Чтобы применить записанные изменения к другому дереву назначения, запустите rsync с опцией read-batch, указав имя того же пакетного файла и дерево назначения. Rsync обновляет дерево назначения, используя информацию, хранящуюся в командном файле.

Для вашего удобства файл сценария также создается при использовании опции write-batch: он будет называться так же, как и пакетный файл с добавлением «.sh». Этот файл сценария содержит командную строку, подходящую для обновления дерева назначения с использованием связанного пакетного файла. Он может быть выполнен с использованием оболочки Bourne (или Bourne-like), необязательно передавая альтернативное имя дерева назначения, которое затем используется вместо исходного пути назначения. Это полезно, когда путь дерева назначения на текущем хосте отличается от того, который использовался для создания пакетного файла.

   Examples:

          $ rsync --write-batch=foo -a host:/source/dir/ /adest/dir/
          $ scp foo* remote:
          $ ssh remote ./foo.sh /bdest/dir/

          $ rsync --write-batch=foo -a /source/dir/ /adest/dir/
          $ ssh remote rsync --read-batch=- -a /bdest/dir/ <foo

В этих примерах rsync используется для обновления / adest / dir / from / source / dir /, а информация для повторения этой операции хранится в «foo» и «foo.sh». Затем «удаленный» хост обновляется, и пакетные данные попадают в каталог / bdest / dir. Различия между этими двумя примерами показывают некоторую гибкость, которую вы имеете при работе с пакетами:

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

  • В первом примере используется созданный файл "foo.sh" для получения правильных параметров rsync при запуске команды read-batch на удаленном хосте.

  • Во втором примере пакетные данные считываются через стандартный ввод, поэтому нет необходимости сначала копировать пакетный файл на удаленный компьютер. В этом примере не используется сценарий foo.sh, так как ему нужно было использовать измененную опцию --read-batch, но вы можете отредактировать файл сценария, если хотите использовать его (просто убедитесь, что никакой другой параметр не пытается использовать стандартный ввод, такой как опция "--exclude-from = -").

    Предостережения:

    Опция read-batch ожидает, что дерево назначения, которое оно обновляет, будет идентичным дереву назначения, которое использовалось для создания набора файлов пакетного обновления. При обнаружении различий между деревьями назначения обновление может быть сброшено с предупреждением (если файл, по-видимому, уже обновлен), или может быть предпринята попытка обновления файла, а затем, если файл не удается проверить , обновление отменено с ошибкой. Это означает, что было бы безопасно перезапустить операцию чтения пакета, если команда была прервана. Если вы хотите, чтобы пакетное обновление всегда выполнялось независимо от размера и даты файла, используйте параметр -I (при чтении пакета). Если произойдет ошибка, дерево назначения, вероятно, будет в частично обновленном состоянии. В таком случае,

    Версия rsync, используемая во всех местах назначения, должна быть как минимум такой же новой, как та, которая использовалась для создания командного файла. Rsync умрет с ошибкой, если версия протокола в пакетном файле слишком новая для обработки пакетного чтения rsync. Смотрите также параметр --protocol, чтобы способ создания rsync генерировал пакетный файл, который может понять более старый rsync. (Обратите внимание, что пакетные файлы изменились в версии 2.6.3, поэтому смешивание версий более старых, чем с более новыми версиями, не будет работать.)

    При чтении пакетного файла rsync принудительно заставит значения определенных опций соответствовать данным в пакетном файле, если вы не установили их так же, как команда пакетной записи. Другие параметры могут (и должны) быть изменены. Например, --write-batch меняет на --read-batch, --files-from удаляется, а параметры --filter / - include / - exclude не нужны, если не указан один из параметров --delete. ,

    Код, который создает файл BATCH.sh, преобразует все параметры фильтра / включения / исключения в единый список, который добавляется в виде документа «здесь» в файл сценария оболочки. Опытный пользователь может использовать это для изменения списка исключений, если необходимо изменить то, что удаляется с помощью --delete. Обычный пользователь может игнорировать эту деталь и просто использовать сценарий оболочки как простой способ запустить соответствующую команду --read-batch для пакетных данных.

    Исходный пакетный режим в rsync был основан на «rsync +», но в последней версии используется новая реализация.

Я полагаю, вы могли бы попробовать

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup
Хлоя
источник
Предлагаемая команда не работает:remote destination is not allowed with --read-batch
kynan
Покажите полную команду. -имя файла означает чтение из стандартного ввода, а STDIN также читается из fooлокального файла.
Хлоя
2
Похоже, это максимально правильное решение для того, что я пытался сделать, хотя мой сценарий использования этого уже давно испарился в эфире. : D
Джесси
4

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

Джейсон Аксельсон
источник
2
Примечание: Unison не хранит «кэш» файлов. Он только хранит базу данных имен файлов, временных отметок, контрольных сумм. Он по-прежнему выполняет сканирование файловой системы и создает контрольную сумму для сравнения с удаленной. Единственное преимущество Unison - двусторонняя синхронизация. Я рекомендую Unison, но здесь это не поможет.
Хлоя
4

Поддержка rsync --batch-modeмногоадресной рассылки. Если это возможно в вашей сети, возможно, стоит изучить это.

codecrank
источник
2

как насчет смены файловых систем?

Некоторое время назад я переключил мульти-терабайтную FS с ext3 на XFS. Время сканирования каталогов (около 600 000 файлов в прошлый раз, когда я проверял) увеличилось с 15-17 минут до менее 30 секунд!

Хавьер
источник
1

Не прямой ответ, но если вы используете rsync версии 3+, он начнет передачу до того, как сгенерирует весь список файлов.

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

Кроме того, я подумал об этой странности, если вы не возражаете против использования tar:

tar cf - . | tee >(ssh localhost 'cat > test1.tar') >(ssh localhost 'cat > test2.tar') >/dev/null

Конечно, где каждый локальный хост - это разные серверы (предполагается, что для входа используется ключ). Никогда не использовал выше, хотя.

Кайл Брандт
источник
Хм! Как ни странно, cwrsync (rsync 3.0.7), похоже, этого не делает. Но мне придется разобраться, почему это так, поскольку это очень помогло бы сократить эти огромные времена выполнения. Благодарность!
Джесси
Эта версия с обеих сторон?
Кайл Брандт
На самом деле, нет; локальная машина - cwrsync 3.0.7, а удаленный хост (ну, тот, с которым я сейчас работаю) - rsync 3.0.3 на Debian Lenny. Не похоже, что это будет слишком большой разницей в версиях, чтобы она могла плохо себя вести, но я не знаю ... Я посмотрю на обновление стороны Debian.
Джесси
1
Какая странная маленькая строчка. Это, вероятно, сработало бы, если бы я не использовал тот факт, что rsync не нужно дублировать несколько гигабайт данных по нескольким медленным каналам связи, когда, самое большее, изменилось всего несколько сотен килобайт. Кроме того, получение обоих концов к (cw) rsync 3.0.7 все еще выполняло сборку списка файлов и последовательную передачу. Хотя, не слишком беспокоюсь об этом.
Джесси
Разве это не "tar cf -." так же, как "tar c." ?
Йохан Буле
1

Как насчет запуска заданий rsync из host1, host2 и host3? Или запустите задание для копирования на host1, а затем запустите его на host2 и host3, чтобы получить его с host1.

mfinni
источник
1

Лучшим решением было бы создать репозиторий с git и просто отправить 3 хостам. Быстрее вам не понадобится часть списка файлов, и она потребляет меньше ресурсов.

Удачи,
Жоао Мигель Невес

jneves
источник
10
git не сохраняет ни время модификации, ни разрешения (за исключением бита выполнения) и требует сохранения второй копии данных в качестве объектов git, .git/хотя отправка на удаленные узлы, которые уже имеют большую часть данных, будет быстрее. Git не является заменой Rsync.
Дэн Д.
Плюс, git общедоступен, если вы не платите.
Хлоя
8
@Chloe, ты принимаешь Git за GitHub. Сам Git является свободным открытым исходным кодом распределенная система контроля версий, и любой желающий может разместить GIT репозиторий любыми средствами, в том числе http, nfsи afp. GitHub - это веб-сайт, который заботится о создании и поддержке git-репозиториев для вас и делает их общедоступными (если вы не платите).
Торининген
1
@Chloe GitHub доступен для публичного просмотра, но BitBucket предоставляет частные репозитории.
21:15
2
Также Git не отслеживает пустые каталоги.
Флим
1

В поисках этого ответа я думаю, что вам нужно сначала создать пакет, используя rsync, а затем отправить его всем им, что приведет к тому, что список файлов будет сжат только один раз, а затем вы можете просто фон все три rsyncs, чтобы запустить их параллельно.

Морган
источник
1

Другое возможное решение - просто запустить столько процессов rsync параллельно, сколько у вас есть хостов, то есть fork.

Алексей Тигарев
источник