Лучшее сжатие для ZFS send/recv

Я отправляю инкрементальные снимки ZFS по линии T1 точка-точка, и мы находимся в точке, где снимки за один день едва могут пройти по проводам до начала следующего резервного копирования. Наша команда send/recv:

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | bzip2 -c | \
ssh offsite-backup "bzcat | zfs recv -F tank/vm"

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

14 ответов

Решение

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

Если не считать этого, есть ли какой-то способ снизить объем записываемых данных? Не зная вашего стека приложений, трудно сказать, как, но может помочь только выполнение таких действий, как проверка того, что приложения перезаписывают существующие файлы, а не создают новые. И убедитесь, что вы не сохраняете резервные копии файлов temp / cache, которые вам не нужны.

С тех пор, как был опубликован этот вопрос, все изменилось:

1: ZFS теперь поддерживает сжатую репликацию, просто добавьте флаг -c к команде отправки zfs, и блоки, которые были сжаты на диске, останутся сжатыми, когда они пройдут по каналу на другой конец. Может быть еще больше сжатия, потому что сжатие по умолчанию в ZFS - lz4

2: лучший компрессор для использования в этом случае - это zstd (ZStandard), теперь у него есть "адаптивный" режим, который будет изменять уровень сжатия (между поддерживаемыми 19+ уровнями плюс новые более высокие скорости zstd-fast уровни) на основе скорость соединения между zfs send и zfs recv. Он сжимает столько, сколько может, сохраняя очередь данных в ожидании выхода из канала до минимума. Если ваша ссылка быстрая, она не будет тратить больше времени на сжатие данных, а если ваша ссылка медленная, она продолжит работать, чтобы еще больше сжать данные и сэкономить ваше время в итоге. Он также поддерживает многопоточное сжатие, поэтому я могу использовать преимущества нескольких ядер, которых нет у gzip и bzip, за исключением специальных версий, таких как pigzip.

Вот то, что я узнал, делая то же самое, что и ты. Я предлагаю использовать mbuffer. При тестировании в моей среде это помогало только на приемном конце, без него отправка замедлялась бы, пока прием не догонял.

Некоторые примеры: http://everycity.co.uk/alasdair/2010/07/using-mbuffer-to-speed-up-slow-zfs-send-zfs-receive/

Домашняя страница с опциями и синтаксисом http://www.maier-komor.de/mbuffer.html

Команда send из моего сценария репликации:

zfs send -i tank/pool@oldsnap tank/pool@newsnap | ssh -c arcfour remotehostip "mbuffer -s 128k -m 1G | zfs receive -F tank/pool"

он запускает mbuffer на удаленном хосте в качестве буфера приема, поэтому отправка выполняется максимально быстро. Я запустил 20-мегабитную строку и обнаружил, что наличие mbuffer на отправляющей стороне также не помогло, также мой основной ящик zfs использует весь свой оперативный памяти в качестве кеша, поэтому предоставление даже 1g mbuffer потребовало бы от меня уменьшения некоторых размеров кеша.

Кроме того, и это не моя область знаний, я думаю, лучше просто позволить ssh выполнить сжатие. В вашем примере я думаю, что вы используете bzip, а затем используете ssh, который по умолчанию использует сжатие, поэтому SSH пытается сжать сжатый поток. В итоге я использовал arcfour в качестве шифра, так как он потребляет меньше ресурсов процессора, и это было важно для меня. Вы можете получить лучшие результаты с другим шифром, но я бы определенно предложил разрешить сжатие SSH (или отключить сжатие ssh, если вы действительно хотите использовать то, что он не поддерживает).

Что действительно интересно, так это то, что использование mbuffer при отправке и получении на локальном хосте также ускоряет процесс:

zfs send tank/pool@snapshot | mbuffer -s 128k -m 4G -o - | zfs receive -F tank2/pool

Я обнаружил, что 4g для передачи на локальном хосте, по-видимому, - самая лучшая точка для меня. Это просто говорит о том, что zfs send / receive на самом деле не нравится задержка или любые другие паузы в потоке для лучшей работы.

Просто мой опыт, надеюсь, это поможет. Мне потребовалось некоторое время, чтобы понять все это.

Я использую pbzip2 все время (параллельно bzip2) при отправке через WAN. Поскольку он является многопоточным, вы можете указать количество потоков, которое будет использоваться с опцией -p. Сначала установите pbzip2 на обоих отправляющих и получающих хостах, инструкции по установке находятся по адресу http://compression.ca/pbzip2/.

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | pbzip2 -c | \
ssh offsite-backup "pbzip2 -dc | zfs recv -F tank/vm"

Основной ключ заключается в создании снимков с частыми интервалами (~10 минут), чтобы уменьшить размер снимка, а затем отправлять каждый снимок. ssh не возобновит работу с поврежденного потока снимков, поэтому, если у вас есть огромный снимок для отправки, направьте поток в pbzip2, затем разделите на куски управляемого размера, затем rsync разделите файлы на принимающий хост, затем передайте в zfs восстановленные объединенные файлы pbzip2.

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 | pbzip2 -c | \
split -b 500M - /somedir/snap-inc-10-to-12.pbzip2--

это создаст файлы с именами по 500 МБ:

/somedir/snap-inc-10-to-12.pbzip2--aa
/somedir/snap-inc-10-to-12.pbzip2--ab
/somedir/snap-inc-10-to-12.pbzip2--ac
...

rsync для получения хоста несколько раз (вы можете rsync даже до того, как отправка zfs завершится, или как только вы увидите полный блок размером 500 МБ), нажмите ctrl+c в любое время для отмены:

while [[ true ]]; do rsync -avP /somedir/snap-inc-10-to-12.pbzip2--* offsite-backup:/somedir ; sleep 1; done;

ZFS получают:

cat /somedir/snap-inc-10-to-12.pbzip2--* | pbzip2 -dc | zfs recv -Fv tank/vm

Пользователь freind упомянул: для чего это стоит. Я бы не стал делать прямую отправку | сжимать | распаковывать | получить это может привести к проблемам на приемном конце, если линия передачи оборвется и ваши пулы будут в автономном режиме в течение длительного времени во время приема. - Ранее я сталкивался с проблемами со старыми версиями zfs <28 на принимающем хосте, если текущая отправка / восстановление прерывается из-за сбоя сети, но не в той степени, в которой пулы отключены. Это интересно. Повторно отправляйте снимок, только если "zfs recv" вышел на принимающей стороне. Убейте "zfs recv" вручную, если это необходимо. zfs send/recv теперь значительно улучшен во FreeBSD или Linux.

Мой опыт таков, что zfs send довольно бурный, несмотря на то, что он намного быстрее (в среднем), чем следующий шаг сжатия. Моя резервная копия добавляет значительную буферизацию после zfs send и еще после gzip:

zfs send $SNAP | mbuffer $QUIET -m 100M | gzip | mbuffer -q -m 20M | gpg ... > file

В моем случае устройство вывода подключено через USB (не по сети), но буферизация важна по той же причине: общее время резервного копирования сокращается, когда USB-накопитель занят на 100%. Вы не можете отправлять меньше байтов в целом (как вы просите), но вы все равно можете закончить раньше. Буферизация удерживает шаг сжатия, связанный с ЦП, от того, чтобы стать связанным с IO.

Это ответ на ваш конкретный вопрос:

Вы можете попробовать rzip, но он работает немного иначе, чем сжатый / bzip / gzip:

Ожидается, что rzip сможет читать весь файл, поэтому его нельзя запустить в конвейере. Это значительно повысит ваши требования к локальному хранилищу, и вы не сможете запускать резервное копирование и отправлять резервное копирование по каналу в одном канале. Тем не менее, полученные файлы, по крайней мере, в соответствии с этим тестом, немного меньше.

Если ваше ресурсное ограничение - это ваш канал, вы все равно будете выполнять резервное копирование в режиме 24x7, поэтому вам нужно будет просто постоянно копировать снимки и надеяться, что вы все равно продолжите.

Ваша новая команда будет:

remotedir=/big/filesystem/on/remote/machine/
while 
  snaploc=/some/big/filesystem/
  now=$(date +%s)
  snap=snapshot.$now.zfssnap
  test -f $snaploc/$snap
do
  sleep 1
done

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 > $snaploc/$snap &&
rzip $snaploc/$snap &&
ssh offsite-backup "
        cat > $remotedir/$snap.rzip && 
        rzip -d $remotedir/$snap.rzip && 
        zfs recv -F tank/vm < $remotedir/$snap &&
        rm $remotedir/$snap " < $snaploc/$snap &&
rm $snaploc/$snap

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

Я предполагаю, что вы просто не можете увеличить сырую пропускную способность вашего сайта...

Вы можете увидеть выгоду от неиспользования сжатия на хосте.

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

Если у вас ограниченный бюджет, вы можете увидеть подобное улучшение, используя rsync и rsyncing несжатый снимок, то есть:

zfs send -i tank/vm@2009-10-10 tank/vm@2009-10-12 > /path/to/snapshotdir/snapshotfile
rsync /path/to/snapshotdir/snapshotfile offsite-backup:/remote/path/to/snapshotfile
ssh offsite-backup 'zfs recv -F tank/vm < /remote/path/to/snapshotfile'

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

Оптимизатор wan является гораздо более вероятным способом решения этой проблемы (хорошо, Metro Ethernet является наиболее вероятным способом решения этой проблемы, но мы оставим это вне рассмотрения). Rsync - это просто дикий выстрел в темноте, который стоит протестировать (локально; rsync сообщит вам, сколько времени он сэкономил на прямой копии) на ваших локальных данных, прежде чем писать большую проверку на наличие оптоволокна или установку на русле.

Для чего это стоит. Я бы не стал делать прямую отправку | сжимать | распаковывать | получить это может привести к проблемам на приемном конце, если линия передачи оборвется и ваши пулы будут в автономном режиме в течение длительного времени во время приема. Мы отправляем в локальный файл, затем gzip снимок и передачи с помощью rsync (с руслом реки), а затем мы получаем из файла. Русло реки не оптимизирует движение, НО, если есть проблема с передачей, и его необходимо перезапустить, русло реки ускоряет повторную передачу.

Мы рассмотрели, как не сжимать инкрементный снимок, использовать сжатие Rsync и не использовать никакое сжатие, кроме русла реки. Трудно сказать, какой из них лучше, но когда мы переносим архивные журналы из oracle со сжатием rsync, скорость передачи примерно в два раза выше, чем у простых файлов и русло (с RSync).

Если у вас есть русло, тогда используйте rsync, а не ssh, так как русло понимает rsync и попытается оптимизировать его и добавит данные в кеш (см. Выше, перезапуск пересылок).

После выполненияzfs send tank@datasnapshot > /dev/nullЯ понял, что в любом случае не собираюсь перегружать свою 10-гигабитную сеть, поэтому решил просто позволить использовать резервный пул.zfs set compression=gzip.

Цифры оказываются схожими.

Это довольно сильно нагружает процессор, но использование mbuffer очень помогает.

отправитель:zfs send -v dank/data@snapshot | mbuffer -s 128k -m 10G -O s2dna:9090

получатель:mbuffer -s 128k -m 10G -I 9090 | zfs receive -s -v backuppool/engram/data

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

В целом я доволен пропускной способностью, которая без mbuffer выражалась двузначными числами:

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

Вам нужно будет проверить с вашими данными. Просто отправьте его в файл и сожмите с каждым методом.

Для нас gzip имел огромное значение, и мы все через это проходили, но между gzip и bzip или 7z разницы не было даже в 1%.

Если вы используете медленный T1, вам нужно будет сохранить его в файл и повторно выполнить его синхронизацию.

Для тех (не для вас), которые ограничены чуть больше процессором, чем пропускной способностью, как, например, lstvan сказал, что другой шифр, например arcfour128, ускоряет процесс. Мы используем это внутренне при перемещении вещей.

Вы можете подобрать более быстрый шифр для ssh, возможно, blowfish-cbc, также попробуйте переключатели -123456789

-1 (or --fast) to -9 (or -best)

"Лучший" алгоритм сжатия зависит от того, какой тип данных у вас есть - если вы нажимаете на сжатие коллекции MP3, вероятно, замедлит процесс, в то время как текстовые / лог-файлы могут быть значительно сжаты с помощью gzip -9,

Сколько данных вы нажимаете каждый день?

Рассматривали ли вы настройку стека TCP/IP так, чтобы вы были буфером TCP и размеры окон были немного больше? Вы можете использовать ndd инструмент на Solaris для этого или sysctl инструмент на Linux/BSD/Mac OSX. На Солярисе вы ищете /dev/tcp tcp_max_buf а также /dev/tcp tcp_cwnd_max значения, а в Linux sysctl вы ищете net.ipv4.tcp_mem, net.ipv4.tcp_rmem а также net.ipv4.tcp.wmem ценности.

Кроме того, эти ссылки могут быть полезны:

Настройка производительности Solaris TCP

Внизу этой страницы есть набор ссылок, которые объяснят, как сделать то же самое для Linux/BSD/OSX.

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