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

Лучшее сжатие для отправки / получения ZFS

Я отправляю инкрементные снимки состояния 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"

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

Вот что я узнал, делая то же самое, что и вы. Предлагаю использовать 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

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

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 при отправке и получении на localhost также ускоряет работу:

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

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

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

Все изменилось за годы, прошедшие с момента публикации этого вопроса:

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

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

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

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

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

Можешь попробовать rzip, но работает он немного иначе, чем compress / bzip / gzip:

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

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

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

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

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

я использую 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.

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

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

Если вы используете что-то вроде оптимизатора 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 - гораздо более вероятный способ решить эту проблему (ну, метро Ethernet - это большинство вероятный способ решить эту проблему, но мы оставим это вне таблицы). Rsync - это просто дикий выстрел в темноте, который стоит протестировать (локально; rsync сообщит вам, сколько времени он сэкономил по сравнению с прямой копией) на ваших локальных данных, прежде чем выписывать большой чек для установки волокна или русла реки.

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

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

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

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

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

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

Сколько данных вы отправляете каждый день?

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

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

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

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

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

После выполнения 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:

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

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

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

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