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

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

Это продолжение:Высокоскоростная сетевая запись с большой емкостью хранилища. Установка существенно изменилась.

У меня есть пул с одним raid-z2с 6 дисками, все диски Exos X18 CMR. Используя fioи ручные тесты, я знаю, что массив может поддерживать около 800 МБ/с последовательной записи в среднем, это нормально и соответствует ожидаемой производительности этого массива. Машина представляет собой Ryzen5 Pro 2400 GE (4C/8T, 3,8 ГГц boost) с 32G ECC RAM, загрузочным/системным диском NVMe и 2x10Gbps Ethernet-портами (Intel x550-T2). Я использую современную систему Arch с zfs 2.1.2-1.

Мой вариант использования — видеоархив в основном большого (~30G) сжатого видео с однократной записью и однократным чтением. Я отключил atime, установил recordsize=1M, установил compressios=offи , dedup=offпоскольку данные фактически несжимаемы, и тестирование показало худшую производительность, чем , compression=lz4несмотря offна то, что говорилось в Интернете, и по замыслу нет дублирующихся данных. Этот пул совместно используется по сети через Samba. Я настроил свою сеть и Samba до точки, где передача с NVMe NTFS на машине Windows на NVMe ext4 достигает 1 ГБ/с, т. е. достаточно близко к насыщению соединения 10 Гбит/с кадрами Jumbo размером 9 КБ.

Вот тут-то я и сталкиваюсь с проблемами. Я хочу иметь возможность передавать один целый 30G видеоархив со скоростью 1 ГБ/с на raid-z2массив, который может поддерживать только последовательную запись со скоростью 800 МБ/с. Мой план состоит в том, чтобы использовать грязные страницы на основе ОЗУ для поглощения перелива и сбрасывать их на диск после того, как передача будет «завершена» на стороне клиента. Я прикинул, что мне понадобятся только (1024-800)*30~=7Gгрязные страницы в ОЗУ, которые можно сбросить на диск в течение ~10 секунд после завершения передачи. Я понимаю последствия для целостности данных, и риск приемлем, поскольку я всегда могу снова передать файл позже в течение месяца на случай, если отключение питания приведет к потере или неполноте файла.

Однако я не могу заставить ZFS вести себя так, как я ожидаю... Я отредактировал свой /etc/modprobe.d/zfs.confфайл следующим образом:

options zfs zfs_dirty_data_max_max=25769803776
options zfs zfs_dirty_data_max_max_percent=50
options zfs zfs_dirty_data_max=25769803776
options zfs zfs_dirty_data_max_percent=50
options zfs zfs_delay_min_dirty_percent=80

Я выполнил соответствующую mkinitcpio -Pкоманду для обновления initramfs и убедился, что настройки были применены после перезагрузки:

# arc_summary | grep dirty_data
        zfs_dirty_data_max                                   25769803776
        zfs_dirty_data_max_max                               25769803776
        zfs_dirty_data_max_max_percent                                50
        zfs_dirty_data_max_percent                                    50
        zfs_dirty_data_sync_percent                                   20

То есть я установил максимальный размер грязных страниц на 24G, что намного больше, чем 7G, которые мне нужны, и удержал, чтобы начать откладывать запись, пока не будет использовано 80% этого объема. Насколько я понимаю, пул должен быть в состоянии поглотить 19G в ОЗУ, прежде чем он начнет отталкивать записи от клиента (Samba) с задержкой.

Однако, по моим наблюдениям, при записи с клиента Windows, примерно через 16 секунд при скорости записи ~1 ГБ/с производительность записи резко падает ( iostatдиски по-прежнему работают усердно, чтобы сбросить данные), что, как я могу предположить, является механизмом отталкивания для регулирования записи ZFS. Однако это не имеет смысла, так как, по крайней мере, даже если бы ничего не было сброшено в течение 16 секунд, оно должно было установиться через 3 секунды. Кроме того, в конце она снова падает, см. изображение: [ введите описание изображения здесь][https://i.stack.imgur.com/Yd9WH.png]

Я пробовал настроить , zfs_dirty_data_sync_percentчтобы начать запись раньше, потому что буфер грязных страниц намного больше, чем по умолчанию, и я также пробовал настроить масштабирование активного ввода-вывода с , zfs_vdev_async_write_active_{min,max}_dirty_percentчтобы оно начиналось раньше, а также чтобы записи быстрее набирали скорость с большим грязным буфером. Оба они просто немного сместили положение обрыва, но далеко не так, как я ожидал.

Вопросы:

  1. Я неправильно понял, как работает задержка регулирования записи?
  2. Возможно ли то, что я пытаюсь сделать?
  3. Если да, то что я делаю не так?

Да, я знаю, я буквально гонюсь за парой секунд и никогда не окуплю усилия, потраченные на достижение этого. Это нормально, это личное дело между мной и ZFS на данный момент, и дело принципа ;)

решение1

Вам также необходимо увеличить zfs_txg_timeoutпараметр с текущего значения по умолчанию в 5 секунд до значения около 7G/0,2G/s = 35 с, поэтому значения 40 с должно быть достаточно.

В вашей /etc/modprobe.d/zfs.conf:

options zfs zfs_txg_timeout=40

Обратите внимание, что ARC — это именно то, что нужно, кэш «чтения» с нулевым взаимодействием с кэшем записи, поэтому убедитесь, что ваш ARC не настроен на потребление дополнительных 7G+ данных, которые ваш кэш записи блоков должен поглощать на поток записи 30 ГБ. Кэш записи для ZFS похож на любой другой простой кэш записи блоков (например, параметр commitдля файловых систем ext4), поэтому обязательно протестируйте его в непроизводственной среде, чтобы убедиться в отсутствии нехватки оперативной памяти во всех сценариях передачи.

решение2

Каждая запись будет обновлять ARC, если zfs primarycache = all (по умолчанию). Если задержка чтения не важна для данных, которые вы в данный момент записываете, я предлагаю установить zfs primarycache=meta.

решение3

В настоящее время у вас недостаточно оперативной памяти или ресурсов хранения для того, что вы ищете.

Проектируйте с учетом желаемых уровней пропускной способности ввода-вывода и их производительности в наихудшем случае.

Если вам необходима пропускная способность 1 ГБ/с при всех условиях для описываемого рабочего набора данных, то убедитесь, что количество шпинделей диска или пропускная способность интерфейса способны ее поддерживать.

Связанный контент