
Я использую сервер rsync (на базе Linux) для распространения ПО. Сервер репозитория исходных кодов (на базе Windows), который находится вне моего контроля, отправляет пакеты ПО на него через rsync, и около сотни сателлитных серверов по всему миру забирают их оттуда также через rsync.
Исходный репозиторий содержит много больших дубликатов файлов. Я хочу сократить дисковое пространство и потребление полосы пропускания на сателлитных серверах, заменив эти дубликаты жесткими ссылками. Администратор исходного репозитория не хочет или не может сделать это на источнике, поэтому я пытаюсь сделать это постфактум на сервере распространения. Я создал простой скрипт bash на основе команды, fdupes
которая находит группы дубликатов и заменяет их жесткими ссылками на один файл. Передачи rsync на сателлитные серверы сохраняют эти жесткие ссылки, как и требовалось, благодаря опции -H. Однако передача из исходного репозитория дает непоследовательные результаты. Иногда дедупликация сохраняется. Иногда исходный сервер повторно передает все файлы дедуплицированной группы, и дедупликация нарушается, даже если исходные файлы не изменились.
Отсюда мой вопрос: каково официальное поведение rsync в случае, если его просят синхронизировать два идентичных, но отдельных файла, а файлы уже существуют в месте назначения с правильным содержимым, но как жесткие ссылки на тот же файл? Каковы точные критерии повторной передачи файла? Есть ли способ гарантировать, что жесткая ссылка в месте назначения сохранится в этой ситуации, даже если жесткой ссылки не существует в источнике?
решение1
tl;dr: Чтобы сохранить дедупликацию на уровне файлов с помощью жестких ссылок в месте назначения, запустите rsync
с --checksum
опцией.
Полный ответ, согласно серии проведенных мной экспериментов:
Если два файла не связаны жесткой ссылкой в источнике, rsync
синхронизирует каждый из них по отдельности с местом назначения. Неважно, связаны ли файлы жесткой ссылкой в месте назначения. Если один из файлов (или оба) оказывается повторно переданным, жесткая ссылка в месте назначения будет разорвана, в противном случае она останется нетронутой. То есть, даже с опцией --hard-links
, rsync
не разорвет жесткую ссылку в месте назначения только потому, что файлы не связаны жесткой ссылкой в источнике.
Критерии повторной передачи файла зависят от параметров --checksum
( -c
) и --ignore-times
( -I
).
- Если задана эта опция
--checksum
, ретранслируются только файлы, отличающиеся по размеру или контрольной сумме между источником и местом назначения. Следовательно, если содержимое файла не изменилось, то жесткая ссылка в месте назначения будет сохранена, даже если ее нет в источнике. - Если указана эта опция
--ignore-times
, все файлы передаются повторно, разрывая любую жесткую ссылку в месте назначения, которая не существует в источнике. - Если ни один из этих двух вариантов не указан,
rsync
для принятия решения будут использоваться временные метки модификации исходного и конечного файлов. В этом случае, если временные метки двух исходных файлов различаются, жесткая ссылка в месте назначения всегда будет разорвана, поскольку может совпадать только одна из двух временных меток.
решение2
Сохраняет исходные жесткие ссылки, если вы используете опцию -H или --hard-links
Что будетнетсоздайте жесткие ссылки — вам придется делать это постфактум, находя файлы с одинаковой контрольной суммой, удаляя один и добавляя жесткую ссылку для его замены. В конце концов, вы бы не хотели, чтобы rsync делал каждый файл с дублированным контентом жесткой ссылкой на тот же файл. Представьте, если бы каждый файл длиной 0 был жесткой ссылкой — вы добавляете контент в один, вы меняете контент для всех.