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

Вопрос или проблема

Предположим, у меня есть большое дерево директорий с большими файлами на диске A. Я делаю резервную копию этого дерева с помощью rsync -a --delete /A /B. Все хорошо. Между резервными копиями добавляются некоторые файлы, некоторые переименовываются, в общем, всё как обычно.

Интересно то, что A регулярно реорганизуется: файлы перемещаются (переименовываются, меняются директории или оба варианта). Поэтому rsync в конечном итоге удаляет файлы на B, чтобы снова скопировать их с A, и с большими файлами через сеть это занимает вечность.

Существует ли какой-нибудь параметр rsync, который я мог бы использовать? Я перечитал список параметров и не смог ничего найти, что могло бы подойти, что-то связанное с --size-only мне было бы вполне приемлемо (малый риск коллизий).

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

Существует два основных подхода:

  1. параметр --fuzzy, вместе с --compare-dest для указания дополнительных директорий для поиска эталонных файлов.
  2. директория, полная жестких ссылок на большие файлы, которая передается первой и инициирует обнаружение жестких ссылок.

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

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

find files -type f -size +2G | (while read f; do ln -f "$f" _links/`sha256sum "$f" | cut -d\  -f1`; done)

а затем передал _links перед files — вот так.

Ни один из этих вариантов не является особенно хорошим.

Когда файлы перемещаются в пределах одной и той же файловой системы, они обычно сохраняют тот же номер инода. Вы можете, таким образом, создать список пар инода и имени файла на диске A сразу после резервной копии, а затем сформировать новый список перед новой резервной копией. Сравнив два списка, вы можете создать список команд перемещения, сопоставив иноды, где имена файлов различаются. Примените этот список перемещений к диску B перед выполнением резервного копирования. Вам, конечно, может понадобиться сначала создать новые директории. Вот объясняющий сценарий:

#!/bin/bash
list(){
  find A -type f -printf "%i %P\n" | # инод и путь не включая A
  sort
}

list >after
#... несколько дней спустя, перед резервной копией:
list >before
join -j 1 -o 1.2 2.2 after before | # один и тот же инод, старое и новое имя файла
awk '{if($1!=$2)printf "mv %s %s\n",$1,$2}' >cmds
(cd A; find . -type d -print0) |
(cd B; xargs -0 mkdir -p )
(cd B; sh -x ) <cmds
# теперь делаем резервную копию, и в конце:
mv before after

Это явно только для простых случаев. Он не обрабатывает директории или имена файлов с пробелами и специальными символами, и оставляет старые имена директорий. Возможно, его можно применить только к аккуратно названным огромным файлам (find ... -size +10M ...).

Ответ или решение

Оптимизация rsync при перемещении крупных файлов

Когда вы осуществляете бэкап большой структуры каталогов с помощью rsync, переименование и перемещение файлов может значительно увеличить время, необходимое для выполнения операций. Это происходит из-за того, что rsync будет удалять файлы на целевом диске (/B) и копировать их заново из исходного (/A). Однако существует несколько стратегий, которые могут помочь оптимизировать этот процесс и минимизировать объем передаваемых данных.

1. Использование параметров rsync

Первый вариант – это использование параметров rsync, таких как --delete, --size-only, и --compare-dest. К примеру:

  • --size-only: Этот параметр позволит rsync игнорировать разницу в содержимом файлов и учитывать только их размеры. Это может быть полезно, если вероятность изменения содержимого файла невелика, но следует помнить, что это не всегда надежно из-за возможности изменения файла с одинаковым размером.

  • --compare-dest: Этот параметр может быть использован вместе с --fuzzy для поиска файлов, которые могли быть перемещены или изменены. Это требует предварительного создания списка каталогов, где ваши файлы могут находиться, однако он не требует изменений в вашей структуре каталогов.

2. Использование жёстких ссылок

Другим подходом является создание каталога с жёсткими ссылками на большие файлы, которые нужно оптимизировать. Вы можете перенести файлы, используя метод, который будет выявлять уже существующие файлы и делать ссылки на них, а не копировать. Пример команды на Bash:

find files -type f -size +2G | while read f; do ln -f "$f" _links/$(sha256sum "$f" | cut -d\  -f1); done

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

3. Сравнение инодов для определения перемещённых файлов

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

#!/bin/bash

list(){
  find A -type f -printf "%i %P\n" | sort
}

list >after

# ... через несколько дней, перед бэкапом:
list >before
join -j 1 -o 1.2 2.2 after before | awk '{if($1!=$2)printf "mv %s %s\n",$1,$2}' >cmds
(cd A; find . -type d -print0) | (cd B; xargs -0 mkdir -p)
(cd B; sh -x ) <cmds

# Теперь производим бэкап
mv before after

Этот скрипт позволяет переименовывать файлы на диске B, если их иноды совпадают, минимизируя необходимость в повторном копировании.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...