как однонаправить зеркалирование всего пула zfs в другой пул zfs


15

У меня есть один пул zfs, содержащий несколько zvols и наборов данных, некоторые из которых также являются вложенными. Все наборы данных и zvols периодически снимаются с помощью zfs-auto-snapshot. Все наборы данных и zvols также имеют некоторые снимки, созданные вручную.

Я настроил удаленный пул, в котором из-за нехватки времени первоначальное копирование по локальной высокоскоростной сети через zfs send -R не завершилось (некоторые наборы данных отсутствуют, некоторые наборы данных устарели или отсутствуют снимки).

Теперь пул физически удален через медленное соединение, и мне нужно периодически синхронизировать удаленный пул с локальным пулом, то есть данные, присутствующие в локальном пуле, должны быть скопированы в удаленный пул, данные, отправленные из локального пула, должны быть удалены из удаленного пула, и данные, присутствующие в удаленном пуле, но не в локальном пуле, должны быть удалены из удаленного пула с помощью данных, означающих «zvols», «наборы данных» или «моментальные снимки».

Если бы я делал это между двумя обычными файловыми системами, используя rsync, это было бы «-axPHAX --delete» (это то, что я на самом деле делаю для резервного копирования некоторых систем).

Как настроить задачу синхронизации, чтобы удаленные пулы zvols и наборы данных (включая их снимки) могли синхронизироваться с локальными zvols, наборами данных и моментальными снимками?

Я хотел бы избежать передачи по ssh из-за низкой производительности ssh; Я бы предпочел вместо этого mbuffer или iscsi.


Как ты сделал свой начальный zfs send -R ...? Если вы передали вывод через ssh, вы отключили escape-символы с помощью zfs send -R ... | ssh -e none ...?
Эндрю Хенле

Кроме того, вам нужно убедиться, что ваше медленное соединение имеет достаточную пропускную способность, чтобы поддерживать актуальность удаленной копии. Если вы получаете больше изменений в локальной системе, чем можете отправить в удаленную систему, вы никогда не сможете поддерживать удаленную копию в актуальном состоянии. Возьмите инкрементный поток репликации zfs и сохраните его в файл. Если размер файла превышает объем данных, которые вы можете отправить на удаленный сайт за промежуток времени между моментальными снимками, вы никогда не будете в курсе. zfs send -R -i pool@snap1 pool@snap2 | gzip --fast > /output/file.gz
Эндрю Хенле

Вы также можете попытаться использовать этот скрипт, чтобы сделать это автоматически: github.com/psy0rz/zfs_autobackup/blob/master/README.md
edwin eefting

Ответы:


11

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


Ваш вопрос на самом деле несколько вопросов, я стараюсь отвечать на них отдельно:

Как реплицировать / зеркально отразить полный пул в удаленном местоположении

Вам нужно разделить задачу на две части: во-первых, первоначальная репликация должна быть завершена, после чего возможна добавочная репликация, если вы не связываетесь со своими снимками репликации . Чтобы включить инкрементную репликацию, необходимо сохранить последние моментальные снимки репликации, все перед этим можно удалить. Если вы удалите предыдущий снимок, zfs recvбудет жаловаться и прервать репликацию. В этом случае вы должны начать все сначала, поэтому постарайтесь не делать этого.

Если вам просто нужны правильные параметры, они:

  • zfs send:
    • -R: отправить все под данным пулом или набором данных (рекурсивная репликация, необходимая постоянно, включает -p). Кроме того, при получении все удаленные исходные снимки удаляются в месте назначения.
    • -I: включить все промежуточные снимки между последним снимком репликации и текущим снимком репликации (необходимо только для инкрементных отправок)
  • zfs recv:
    • -F: расширить целевой пул, включая удаление существующих наборов данных, которые удаляются из источника
    • -d: отбросьте имя исходного пула и замените его на имя целевого пула (остальные пути файловой системы будут сохранены, а при необходимости также созданы)
    • -u: не монтировать файловую систему в месте назначения

Если вы предпочитаете полный пример, вот небольшой скрипт:

#!/bin/sh

# Setup/variables:

# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname

# Initial send:

# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"

# Incremental sends:

# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
    zfs destroy "$snap"
done

Используйте что-то быстрее, чем SSH

Если у вас достаточно защищенное соединение, например, туннель IPSec или OpenVPN и отдельная VLAN, которая существует только между отправителем и получателем, вы можете переключиться с SSH на незашифрованные альтернативы, такие как mbuffer, как описано здесь , или вы можете использовать SSH со слабым шифрованием / без шифрования и отключено сжатие, которое подробно описано здесь . Был также веб-сайт о том, чтобы рекомендовать SSH, чтобы быть намного быстрее, но, к сожалению, я не помню URL - я отредактирую его позже, если найду.

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

Проблема с испорченными снимками

Как указывалось ранее, если вы удалите / измените свои снимки репликации, вы получите сообщение об ошибке

cannot send 'pool/fs@name': not an earlier snapshot from the same fs

Это означает, что либо ваша команда неверна, либо вы находитесь в несовместимом состоянии, когда вы должны удалить снимки и начать все сначала.

Это имеет несколько негативных последствий:

  1. Вы не можете удалить моментальный снимок репликации, пока новый моментальный снимок репликации не будет успешно передан. Поскольку эти снимки репликации включают в себя состояние всех других (более старых) снимков, пустое пространство удаленных файлов и снимков будет восстановлено только после завершения репликации. Это может привести к временным или постоянным проблемам с пространством в вашем пуле, которые вы можете исправить только путем перезапуска или завершения полной процедуры репликации.
  2. У вас будет много дополнительных снимков, что замедляет команду list (кроме Oracle Solaris 11, где это было исправлено).
  3. Вам может потребоваться защитить снимки от (случайного) удаления, кроме как самим сценарием.

Существует возможное решение этих проблем, но я сам не пробовал. Вы можете использовать zfs bookmarkновую функцию в OpenSolaris / illumos, созданную специально для этой задачи. Это освободит вас от управления снимками. Единственным недостатком является то, что в настоящее время он работает только для отдельных наборов данных, а не рекурсивно. Вам нужно будет сохранить список всех ваших старых и новых наборов данных, а затем зациклить их, добавить в закладки, отправить и получить их, а затем обновить список (или небольшую базу данных, если вы предпочитаете).

Если вы попробуете маршрут закладки, мне было бы интересно услышать, как это сработало для вас!


Большое спасибо за этот подробный ответ. я просто отправляю .. получаю zpool.
дрожание

1
хороший сценарий Я бы добавил -d 1к обеим zfs listкомандам, чтобы ограничить глубину поиска (нет необходимости искать под именем пула). Это позволяет избежать длительных задержек в пулах с большим количеством моментальных снимков (например, в моем «резервном» пуле 320000 моментальных снимков, и zfs list -r -t snapshot backupего запуск занимает 13 минут. Это занимает всего 0,06 секунды с -d 1). zfs destroyКоманды в течение цикла , то нужна -rвозможность рекурсивно удалить все снимки с той же snapname.
Cas

5

Лично я бы сам составил список zvols, наборов данных и т. Д. На удаленном сервере, на которых нет актуальных моментальных снимков, а затем обновил бы эти моментальные снимки zfs send, даже если это отнимает много времени и использует много пропускной способности.

Тогда я мог бы просто продолжать использовать zfs sendс тех пор и не нужно заново изобретать колесо, написав свой собственный код синхронизации. rsyncхорошо для старых файловых систем, но zfs sendгораздо лучше для zfs - он точно знает , какие блоки изменились в снимке и отправляет только их, тогда как rsync должен сравнивать отдельные файлы и / или временные метки между локальными и удаленными серверами. btrfs sendТо же самое относится и к пулам btrfs.

Если у вас есть только небольшое количество снимков, которые необходимо обновить, это можно сделать вручную. В противном случае, чтобы сделать это автоматически, вам потребуется список последних локальных снимков по сравнению с удаленными снимками и сценарий для сравнения версий, а затем zfs sendлокальных снимков, которые устарели на сервере rmeote.

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

Если вам нужно безопасное соединение с удаленным сервером, у вас действительно нет другого выбора, кроме как использовать ssh- или, возможно, настроить туннель с помощью openvpnчего-то и использовать netcat.


Как насчет использования Zrep? bolthole.com/solaris/zrep
XDG

не знаю, никогда не использовал его. похоже, это даст хороший ответ, хотя, если кто-то проведет небольшое исследование и тестирование и напишет его (это подсказка).
Cas

Я тестировал его на Ubuntu (ZFS на Linux), и он не работал на более глубоких наборах данных (tank / что-то / someother). Я использовал этот порт для оболочки - ссылка . Рекурсивный флаг export ZREP_R=-Rне работал вообще. :(
Xdg

1

Взгляните на `zrepl ', на FreeBSD, которая может сделать вашу жизнь, и кому бы то ни было, намного проще. Он был представлен несколько дней назад во время BSDCan2018 в Оттаве. Это выглядит многообещающе и может быть решением ваших проблем



Вопрос в вопросе: «Как настроить задачу синхронизации, чтобы удаленные пулы zvols и наборы данных (включая их снимки) могли синхронизироваться с локальными zvols, наборами данных и снимками?»
Джефф Шаллер

0

zrep - это отличное решение «все в одном», в котором есть документация и подсказки о том, как получить более быструю передачу, чем обычная передача по SSH

https://github.com/bolthole/zrep

он также кроссплатформенный: поддерживается на Linux, FreeBSD и Solaris / Illumos



1
Вопрос в вопросе: «Как настроить задачу синхронизации, чтобы удаленные пулы zvols и наборы данных (включая их снимки) могли синхронизироваться с локальными zvols, наборами данных и снимками?»
Джефф Шаллер

Джефф, ты предлагаешь, что лучшим "ответом" будет вырезать биты из документации zrep, а не просто дать ссылку на zrep?
Филипп Браун

1
Я не знаю, какой будет лучший ответ, но ссылка на программное обеспечение не является решением. Это уже упоминалось, на самом деле. Вопрос состоит в следующем: «Как настроить задачу синхронизации, чтобы удаленные пулы и наборы данных (включая их снимки) могли синхронизироваться с локальными zvols, наборами данных и моментальными снимками?»
Джефф Шаллер

да, это вопрос. Однако, чтобы выполнить задачу ХОРОШО, требуется гораздо больше, чем небольшая рецензия на веб-странице здесь. Вот почему zrep - это оболочка из 2000 строк. Даже если бы нужно было удалить все части, которые никогда не требовались в исходной задаче, все равно для этого потребовалось бы несколько сотен строк сценария.
Филипп Браун
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.