Назад | Перейти на главную страницу

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

Мне интересно, может ли 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 

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

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

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

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

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

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

   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 прекратит работу с ошибкой, если версия протокола в пакетном файле слишком новая для обработки rsync для пакетного чтения. См. Также параметр --protocol, чтобы узнать, как создать пакетный файл, который может понять старый rsync. (Обратите внимание, что формат командных файлов изменился в версии 2.6.3, поэтому смешивание более старых версий с более новыми версиями не работает.)

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

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

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

Я представляю, ты можешь попробовать

rsync --write-batch=foo -Pav /junk user@host1:/backup
foo.sh user@host2:/backup
foo.sh user@host3:/backup

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

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

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

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

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

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

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

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

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

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

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

Удачи,
Жуан Мигель Невеш

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

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