Почему ZFS отправляет / получает так много данных по моей локальной сети?

479
Stilez

Буквально на прошлых выходных я установил новый (резервный) сервер резервного копирования для своей основной машины FreeNAS и запустил полное резервное копирование пула между ними. Обе машины являются корпоративным оборудованием и работают быстро, связь между ними - прямая оптическая сеть 10G (Chelsio), обе машины имеют много быстрого NVMe ZIL / кеша и 128 ГБ быстрого ddr4, с платами Xeon v4 и Supermicro. Пул, который я копирую / копирую, состоит из 14 ГБ фактических данных, дедуплицированных с использованием 35 ГБ данных (2,5x дедупликация). Пулы представляют собой полосатые зеркала (4 комплекта трехсторонних зеркал с корпоративными дисками 6 + TB 7200), а не RaidZ, поэтому у них даже нет четности для их замедления. На серверах или их соединениях больше ничего не работает, кроме соединений SSH для передач. Команда zfs sendвключает в себя аргументы, необходимые для отправки данных с дедупликацией (хотя из-за надзора не сжимается).

Команда на отправителя:

zfs send -vvDRLe mypool@latest_snapshot | nc -N BACKUP_IP BACKUP_PORT 

Команда на получателя:

nc -l PORT | zfs receive -vvFsd my_pool 

Я ожидал, что произойдет одно из двух: либо он отправит 14 ТБ и завершит работу, либо отправит 35 ТБ, но уже отправленный 21 ТБ (дедуплицированные данные) идет очень быстро, и нужно отправить только 14 и немного ТБ. Но вместо этого он, похоже, намеревается отправить все 35 ТБ полностью и невероятно медленно - я сделал что-то не так или неправильно понял?

Чего я не понимаю, так это того, что даже при сериализации снимков / наборов данных диски серверов резервного копирования работают почти на 100% в соответствии с этим gstatи работают уже 4 полных дня. Данные поступают правильно (я могу смонтировать те снимки / наборы данных, которые были завершены). Но отправка всего пула выглядит так, как будто это займет около 7 дней, почти 100% активности диска все время.

Передача 14 ТБ или даже 35 ТБ по каналу 10 ГБ между двумя быстрыми серверами - независимо от того, какая информация о состоянии отображается на консоли - просто не должна занимать так много времени, если только она невероятно неэффективна, что кажется маловероятным.

Обе системы могут считывать и записывать данные даже с вращающихся дисков HDD со скоростью почти 500 МБ / с, а ZFS оптимизирует доступ к диску и не требует повторной дедупликации данных, поскольку они отправляются уже дедуплированными.

Почему это так долго? Почему бы не отправлять только один раз необработанные блоки в пуле?

Отвечая на некоторые моменты из комментариев:

  1. netcat (nc): netcat (nc) обеспечивает прозрачный незашифрованный tcp транспорт / туннель для передачи данных между двумя системами (среди прочего) - немного похоже на ssh / VPN, но не замедляет и не переупаковывает, кроме простых TCP-соединений на проводе. Что касается zfs send/ zfs receiveони связаны с прямой связью, то за пределами крошечной задержки netcatканал должен работать с максимальной скоростью, которую может обработать отправка / прием.
  2. Скорость зеркального диска: зеркало записывает на самой низкой скорости любого из своих дисков, но ZFS рассматривает диски как чередующееся зеркало (данные разбиваются на 4 vdevs в обеих системах, и каждый vdev является зеркалом). Если исходный пул заполнен на 55%, а пул dest пуст и предполагается, что процессоры могут работать, zfs должен иметь возможность одновременно читать с 12 дисков и записывать на 4 диска, а записи должны быть почти последовательными, нет другая деятельность IO. Я полагаю, что самый медленный диск в любом зеркале может последовательно записывать со скоростью> = 125 МБ / с, что намного ниже скорости для современного корпоративного жесткого диска 7200, и резервная копия может заполняться последовательно, а не случайным вводом-выводом. Вот где я получаю устойчивую скорость репликации >> 500 МБ / с.
  3. Таблица дедупликации / адекватность ОЗУ: Таблица дедупликации составляет около 40 ГБ в ОЗУ (от байтов на запись x общее количество блоков в исходном пуле на zdb). Я установил sysctl в обеих системах, чтобы зарезервировать 85 ГБ ОЗУ для таблицы дедупликации и других метаданных, а значит, около 35 ГБ для кэшированных данных, перед любым использованием L2ARC (если используется с send / rcv). Таким образом, дедупликация и метаданные не должны быть удалены из оперативной памяти на любой машине.

Скорость и прогресс обновления:

  • После 5 дней выполнения у меня есть некоторые обновленные показатели прогресса. Он отправляет данные со средней скоростью около 58 МБ / с. Не совсем пагубно, но все же лежит в основе вопроса выше. Я ожидаю, что скорость будет примерно в 10 раз выше, поскольку наборы дисков могут одновременно считывать до 12 жестких дисков (почти 2 ГБ / с) и записывать до 4 дисков одновременно (около 500 ГБ / с). Он не должен дедуплицировать или повторно дедуплицировать данные (AFAIK), он работает на 3,5 ГГц 4 + 8-ядерном Xeon v4 с тоннами оперативной памяти в обеих системах и локальной сети, которая может обрабатывать 1 ГБ / с.
2
Если `zfs send` отправляет 35TB, как вы ожидаете, что` nc` узнает, какие данные уже были отправлены? grawity 6 лет назад 0
Конечно, netcat - это просто прозрачный транспорт между процессами `zfs send` и` zfs receive`. Ему не нужно ничего знать, больше, чем процесс ssh или VPN должен понимать rsync или другие протоколы, проходящие через них? Обычный незашифрованный транспортный туннель между портами не может повлиять на то, будет ли zfs send синхронизировать 14 или 35 ТБ исходных (не транспортируемых) данных в своем выводе состояния, или на то, что на это уходит неделя, а не день. или так пул переносить? Что вы думаете, что случилось, как вы, вероятно, знаете больше, чем я об этом? Stilez 6 лет назад 0
Возможно, я неправильно понял, что вы имели в виду: «... он отправляет 35 ТБ, но уже отправленный 21 ТБ (дедуплицированные данные) идет очень быстро, ...» grawity 6 лет назад 0
Я имел в виду, что ожидал (а), что он будет отправлять каждый логический блок только один раз - это означает, что он отправляет 14 ТБ, а счетчик хода выполнения останавливается на 14 ТБ, или (b) он будет отправлять каждую ссылку, в общей сложности 35 ТБ, но любые блоки уже отправленный, он просто отправит указатель, а не полные данные, поэтому только 14 ТБ из его «счета» будет медленным из-за фактических данных, остальные 21 ТБ будут учитываться в информации о ходе выполнения, но будут пролетать как только указатели / дубликаты необходимо было отправить идентификаторы блоков (не фактическое содержимое блока) для всех дублирующих блоков. Это то, что я имел в виду / ожидал. Stilez 6 лет назад 0
Смотрите обновление до ОП. Stilez 6 лет назад 0

1 ответ на вопрос

1
Dan

Из того, что вы упомянули о сжатии, я предполагаю, что все размеры / скорости хранения, которые вы описали, были в несжатом размере. В противном случае это может увеличить время передачи на коэффициент, равный вашему среднему коэффициенту сжатия (но не в том случае, если доступ к диску является узким местом, поскольку распаковка / сжатие происходит после чтения с диска zfs sendи перед записью на диск zfs receive).

Судя по собранной вами информации, похоже, что вы ограничены пропускной способностью диска, а не сетевым подключением. Вы упомянули, что каждая система может выполнять чтение / запись со скоростью ~ 500 МБ / с, поэтому лучшее время передачи для 35 ТБ составляет около 20 часов (примерно в 2,5 раза медленнее, чем просто передача по сети 10 Гбит / с). Но, основываясь на вашей настройке зеркалирования, я удивлен, что чтение и запись будут иметь одинаковую пропускную способность - вы уверены в этом? В отправляющей системе вам нужно только читать с одного диска (чтобы вы могли распараллеливать чтение на трех дисках), но в принимающей системе вы должны записывать на все три диска (так что вы ограничены пропускной способностью самого медленного диска в в любое время). Чтобы проверить пропускную способность записи на принимающей стороне, вы можете запустить dd if=/dev/urandom of=some_file_in_pool bs=1M count=1024 conv=fdatasync.

Поскольку вы сказали, что принимающие диски заняты на 100%, я предполагаю, что они не достигают пропускной способности записи 500 МБ / с. Это может быть связано либо с тем, что реальный лимит записи ниже этого ( ddкоманда, приведенная выше, должна подтвердить), либо с тем, что системе приходится выполнять чтение метаданных во время приема, и это нарушает вашу приятную рабочую нагрузку при записи большого размера IO добавив кучу дисков ищет в миксе. Вы должны быть в состоянии исследовать вторую гипотезу более глубоко, используя DTrace, чтобы увидеть, как ioпоставщик считает ваши размеры чтения / записи.

Спасибо, я еще не справился с dtrace (я надеюсь, вам нужно знать больше о структуре / ядре, чем я). Если здесь есть какой-то конкретный код liners / dtrace, можете ли вы мне его предложить, чтобы я мог его попробовать? Как не уверен, что я могу проверить скорость dd в середине репликации? Также, чтобы уточнить, да, одно зеркало работает на самой медленной из всех своих дисков. Но пул zfs из 4 чередующихся зеркал может записывать на все 4 самых медленных диска одновременно (4 vdevs), поэтому, если предел ввода-вывода для жесткого диска, общая максимальная скорость все равно должна быть примерно в 4 раза выше, чем мог бы достигнуть один диск. Это то, что я думал о скорости записи. Stilez 6 лет назад 0
Большая часть сжатия в исходном пуле происходит из-за дедупликации - его сильно дедуплицированных данных, примерно в 2,6 раза. В отличие от сжатия сжатие является меньшим фактором, только около 1,17x. Возможно, не совсем сравнимо, так как один взят из списка zpool, а другой из списка ZFS в основном наборе данных (90% пула), но дает представление. Stilez 6 лет назад 0
Да, вы правы, чередование поможет, хотя нет никакой гарантии, что IO будут равномерно распределены по полосам. Самый простой способ получить хорошее представление - это просто измерить его. Да, на результаты будет влиять текущая отправка или получение (но, учитывая, что спецификации каждой системы одинаковы, вы можете запустить ее на стороне отправки). Для DTrace проще всего начать с DTraceToolkit, который доступен здесь: https://github.com/opendtrace/toolkit/blob/master/Docs/Contents. Похоже, сжатие не должно сильно влиять на производительность. Dan 6 лет назад 0
Еще одна мысль: я думаю, что дедупликация при отправке / получении не работает так же, как дедупликация по всему пулу - в основном, она дедуплирует блоки в потоке отправки, но принимающая сторона все еще должна восстановить таблицу дедупликации пула с нуля (IIRC) , Это может быть причиной чтения метаданных с произвольным доступом, о котором я упоминал, если таблица дедупликации не помещается в ОЗУ. У рабочей нагрузки dd со случайными данными также было бы это ограничение, так что это все еще кажется хорошим способом реплицировать рабочую нагрузку, подобную получению, для тестирования. Dan 6 лет назад 0
ОЗУ рассчитано на хранение полной таблицы дедупликации и еще 50 ГБ кеша / метаданных и метаданных ARC sysctl используется для обеспечения достаточного количества зарезервированных ОЗУ (85 ГБ), чтобы таблицы дедупликации не выселялись - по крайней мере, я надеюсь, что нет! Я рассчитал размер дедупликации в оперативной памяти, он составляет около 40 ГБ или 2,5-3 ГБ на ТБ). Я посмотрел на dtrace, выясняя, как сделать то, что вы предлагаете, без моего ведома. Есть ли какой-нибудь шанс на подсказку, которую я могу использовать на этот раз и учиться у / строить? Stilez 6 лет назад 0
Смотрите обновление до ОП. Stilez 6 лет назад 0
Причина, по которой я не хочу приводить слишком много подробностей о расследовании небольших операций ввода-вывода, нарушающих вашу потоковую передачу, заключается в том, что на самом деле не будет ничего, что вы можете сделать, чтобы это исправить. Тем не менее, у меня была одна заключительная мысль, которая могла бы быть полезной, которая написана здесь: http://everycity.co.uk/alasdair/2010/07/using-mbuffer-to-speed-up-slow-zfs-send- ZFS-прием / Dan 6 лет назад 0

Похожие вопросы