Синхронизация очень больших структур папок

У нас есть структура папок в нашей интрасети, которая содержит около 800000 файлов, разделенных на около 4000 папок. Нам нужно синхронизировать это с небольшим кластером машин в наших DMZ. Глубина конструкции очень мала (она никогда не превышает двух уровней глубины).

Большинство файлов никогда не меняются, каждый день появляется несколько тысяч обновленных файлов и 1-2 тысячи новых файлов. Данные представляют собой исторические отчетные данные, которые хранятся там, где исходные данные были очищены (т.е. это завершенные отчеты, для которых исходные данные достаточно стары, чтобы мы их заархивировали и удалили). Синхронизация один раз в день достаточна, учитывая, что это может произойти в разумные сроки. Отчеты создаются в одночасье, и мы первым делом синхронизируем утром как запланированное задание.

Очевидно, что из-за того, что очень немногие файлы изменяются на регулярной основе, мы можем значительно выиграть от инкрементного копирования. Мы попробовали Rsync, но это может занять от восьми до двенадцати часов, только чтобы завершить операцию "создание списка файлов". Понятно, что мы быстро перерастаем то, на что способен rsync (12-часовой период слишком длинный).

Мы использовали другой инструмент под названием RepliWeb для синхронизации структур, и он может выполнять поэтапную передачу примерно за 45 минут. Однако, кажется, что мы превысили его предел, он начал видеть, что файлы отображаются как удаленные, когда их нет (возможно, какая-то внутренняя структура памяти была исчерпана, мы не уверены).

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

5 ответов

Если вы можете доверять меткам времени последней модификации файловой системы, вы можете ускорить процесс, сочетая Rsync с утилитой UNIX/Linux 'find'. 'find' может собрать список всех файлов, которые показывают время последнего изменения за прошедший день, и затем направить ТОЛЬКО этот сокращенный список файлов / каталогов в Rsync. Это намного быстрее, чем Rsync сравнивает метаданные каждого файла в отправителе с удаленным сервером.

Короче говоря, следующая команда выполнит Rsync ТОЛЬКО в списке файлов и каталогов, которые изменились за последние 24 часа: (Rsync НЕ БУДЕТ проверять любые другие файлы / каталоги.)

find /local/data/path/ -mindepth 1 -ctime -0 -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.

В случае, если вы не знакомы с командой 'find', она рекурсивно просматривает определенное поддерево каталога, ища файлы и / или каталоги, которые соответствуют любым заданным вами критериям. Например, эта команда:

find . -name '\.svn' -type d -ctime -0 -print

начнется в текущем каталоге (".") и будет проходить по всем подкаталогам в поисках:

  • любые каталоги ("-type d"),
  • с именем ".svn" ("-name '.svn'"),
  • с метаданными, измененными за последние 24 часа ("-ctime -0").

Он печатает полное имя пути ("-print") чего-либо, соответствующего этим критериям, в стандартном выводе. Параметры '-name', '-type' и '-ctime' называются "тестами", а опция "-print" называется "действием". Страница man для 'find' содержит полный список тестов и действий.

Если вы хотите быть действительно умным, вы можете использовать тест '-cnewer' команды 'find' вместо '-ctime', чтобы сделать этот процесс более отказоустойчивым и гибким. '-cnewer' проверяет, были ли метаданные каждого файла / каталога в дереве модифицированы более недавно, чем какой-либо справочный файл. Используйте "touch", чтобы создать справочный файл СЛЕДУЮЩЕГО запуска в начале каждого запуска, прямо перед "find... | Команда rsync... 'выполняется. Вот основная реализация:

#!/bin/sh
curr_ref_file=`ls /var/run/last_rsync_run.*`
next_ref_file="/var/run/last_rsync_run.$RANDOM"
touch $next_ref_file
find /local/data/path/ -mindepth 1 -cnewer $curr_ref_file -print0 | xargs -0 -n 1 -I {} -- rsync -a {} remote.host:/remote/data/path/.
rm -f $curr_ref_file

Этот скрипт автоматически знает, когда он был запущен в последний раз, и он передает только файлы, измененные с момента последнего запуска. Хотя это более сложно, это защищает вас от ситуаций, когда вы могли пропустить выполнение задания более 24 часов из-за простоя или другой ошибки.

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

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

http://oss.linbit.com/csync2/ предназначен для такого рода вещей, я бы попробовал.

Удаление команды -z из команды rsync, которая не является сжатием, сделало "список принимаемых файлов" намного быстрее, и нам пришлось перенести около 500 ГБ. Прежде чем это заняло один день с ключом -z.

Другие вопросы по тегам