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

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

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

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

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

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

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

Если вы можете доверять меткам времени последнего изменения файловой системы, вы можете ускорить процесс, объединив Rsync с утилитой «find» UNIX / Linux. '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 . -name '\.svn' -type d -ctime -0 -print

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

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

Он выводит на стандартный вывод полный путь («-print») всего, что соответствует этим критериям. Опции «-name», «-type» и «-ctime» называются «тестами», а опция «-print» называется «действием». На странице руководства по поиску есть полный список тестов и действий.

Если вы хотите быть действительно умным, вы можете использовать тест «-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 часов из-за простоя или какой-либо другой ошибки.

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

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

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

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