- PVSM.RU - https://www.pvsm.ru -

Некоторое время назад пользователь Practical ZFS [1] задал обманчиво простой вопрос:
«У меня есть пул Proxmox из трёх RAIDz1 vdev (virtual device, виртуальное устройство) по 4 диска. Проблема в том, что во время работы VM все двенадцать дисков минимум раз в секунду издают громкий звук, причём в течение всего дня. Что может быть причиной, и как это устранить?»
Естественно, на этот простой вопрос есть простой ответ: «Рассматриваемая VM наверняка просто непрерывно выполняет поток записей на диск, и эти записи раз в секунду синхронизируются с физическим диском».
К сожалению, этот простой ответ не проникает в суть вопроса, как и не предлагает каких-либо способов решения. Для того, чтобы ответить на этот вопрос полностью — и предложить возможные решения — нужно углубиться в принципы работы ZFS.
Ответ на этот, казалось бы, простой вопрос потребовал очень много отступлений. В какой-то степени это можно сравнить с просьбой к пользователю собрать кадиллак Джонни Кэша [2] только для того, чтобы научиться его мыть.
При рассмотрении обозначенной пользователем проблемы, одним из первых вариантов на ум приходит топология vdev: у человека всего 12 дисков, выстроенных в три vdev RAIDz1 по четыре штуки. Но это неидеальная ширина.
И чтобы понять почему, нужно немного поговорить о принципе работы RAIDz. В своей сути, каждый блок — фундаментальная единица хранения данных в ZFS, чей размер определяется свойствами recordsize или volblocksize — разделён на n-p частей, где n представляет общее число дисков vdev, а p — уровень чётности.
Поскольку размер блока должен быть чётной степенью 2, то если вы хотите, чтобы фрагменты каждого блока поровну делились между дисками vdev, тогда величины n-p также должны быть равны чётной степени 2. Посмотрим, как это работает на практике:
Тем не менее ничто из этого не ведёт к трагедии — к примеру, создатель OpenZFS Мэтт Аренс сказал [3], что перестал беспокоиться и научился любить RAIDz. С него следует брать пример. В частности, пулы, которые в основном хранят сжимаемые данные, минимально подвержены отрицательному влиянию неидеальной ширины vdev, поскольку сжатие OpenZFS в любом случае ведёт к получению полос с неполным размером.
Но лично я с Мэттом не согласен — обычно влияние неидеальной ширины vdev довольно незначительно, и я редко советую кому-либо демонтировать рабочий пул, только из-за использования неоптимальной ширины.
Тем не менее, если вы собираете пул с нуля, то неидеальная ширина заметно скажется на производительности и эффективности. Поэтому желательно сразу делать пулы оптимальными…но в нашем конкретном случае нас волнует не столько производительность и эффективность хранилища, сколько шум.
При этом мы также работаем с очень маленьким размером блоков, что — как мы увидим в следующем разделе — значительно усиливает все обозначенные проблемы.
Следующая проблема уже чуть тоньше и для своего выявления требует некоторых знаний о реализации распределения в ZFS — задавший вопрос человек использует Proxmox, основанную на дистрибутиве Debian. Эта система упрощает работу с виртуальными машинами (VM), хранящимися поверх OpenZFS.
Proxmox — это очень предвзятый дистрибутив — он требует от вас использования для виртуальных машин zvols (датасетов блочной системы хранения данных), а не файловых систем (датасетов файлового хранилища), и по умолчанию задействует очень маленький volblocksize — 8 КиБ. Это касается всех релизов, кроме последнего, где этот размер увеличен до 16 КиБ.
Помните наши расчёты, когда мы пытались понять, является ли оптимальной та или иная ширина vdev? В Proxmox при использовании предустановленных параметров обычно идеальной ширины RAIDz vdev нет — блоки слишком малы, чтобы делить их между дисками.
Для тех, кто пользуется Proxmox v7 или более ранними версиями, параметр volblocksize = 8 КиБ означает, что каждый блок содержит всего два сектора данных, то есть не может быть разделён равным образом между более, чем двумя дисками.
Жалующийся на шум форумчанин использует Z1 шириной в четыре диска, то есть каждый блок 8 КиБ — два сектора данных — может занимать только три сектора (два сектора данных и один сектор чётности). И это ширина всего в три диска — значит, OpenZFS сохраняет каждый блок 8 КиБ только на трёх дисках, каждый из которых записывает всего один сектор.
Поскольку каждую полосу мы записываем всего на три диска, то получаем лишь 67% эффективности хранилища вместо 75%, которые могли бы ожидать, если бы ширина Z1 составляла четыре диска — или даже 72,7%, которые должны получиться при такой же конфигурации с учётом лишних полос.
Мы также записываем на каждый диск по одному сектору, что крайне негативно сказывается на производительности и шуме привода. То есть мы максимизируем потенциал для фрагментации, что ведёт к максимально долгим периодам позиционирования головки, максимальному уровню шума и минимальному быстродействию.
Начиная с Proxmox 8, предустановленный volblocksize для новых VM составляет уже не 8 КиБ, а 16 КиБ. И во многих типичных сценариях этого по-прежнему очень мало.
Как мы видели в предыдущем разделе, нельзя разделить блок ровно на три части — поэтому в конце каждого блока нужна одна узкая полоса. К сожалению, мы работаем единовременно всего с 16 КиБ, а не 128 КиБ, которые разбирали ранее, что ведёт к более пагубным последствиям.
Каждый блок 16 КиБ необходимо разделять на четыре сектора по 4 КиБ. Три этих сектора вместе с сектором чётности отправляются на одну полноразмерную полосу, после чего оставшийся сектор получает свой сектор чётности во второй, более узкой полосе — в результате чего общая эффективность хранилища при 4 секторах данных / 2 секторах чётности == 67%.
Но это не означает, что при каждом чтении или записи блока половина дисков должна проделывать 8 К операций ввода-вывода вместо 4 К. Это несколько повысит производительность и может слегка уменьшить шум…но в обоих случаях вряд ли заметным образом.
Теперь, когда мы вручную собрали кадиллак Джонни Кэша, можно, наконец, обсудить его мойку.
Немного подытожим. Наш пользователь жалуется на сильный шум дисков его сервера на платформе Proxmox. Нам известно, что в сервере работает 12 дисков, разбитых по трём RAIDz1 vedv шириной четыре диска каждый. Это первый сервер Proxmox у пользователя, то есть он наверняка использует его базовые установки с размером volblocksize = 8K или volblocksize = 16K.
Как мы уже поняли, комбинация zvol, небольшого volblocksize и неоптимальной ширины RAIDz vdev ведёт к тому, что записывается больше секторов, чем нужно — потенциально намного больше, чем можно предполагать из простейших математических расчётов.
К сожалению, ни один из этих неудачных вариантов конфигурации легко не исправить — RAIDz vdev перекроить на данный момент нельзя, и volblocksize после своей установки остаётся неизменным. Поэтому в надежде разрешить сложившуюся ситуацию мы готовимся практически к полному демонтажу пула.
В отношении топологии пула мы можем предположить, что пользователь хотел получить те самые 75% эффективности хранилища, которые предполагает (но обычно не обеспечивает) Z1 при ширине в четыре диска. Не знаем же мы то, насколько ему фактически важно это обещанное дополнительное пространство хранилища.
Если пользователя реально интересует именно 75% эффективности, то ему сильно не повезло — этого уровня не удастся достичь, пока вы не соберёте RAIDz2 шириной в десять дисков, которая является идеальной и обещает 80% эффективности хранилища.
У нашего пользователя 12 дисков, значит Z2 с шириной в десять, по крайне мере, организовать можно. Но в этом случае количество vdev понизится с трёх до одного, и потребуется минимальный volblocksize = 32 КиБ (восемь секторов по 4 КиБ), только чтобы обеспечить запись всей ширины по одному сектору на диск.
Если пользователя меньше интересует общий объём, то, возможно, разумнее будет рассмотреть одну из следующих топологий:
Говоря в общем, чем больше volblocksize, тем выше максимальная пропускная способность может быть достигнута ценой увеличения задержки при каждой отдельной операции ввода-вывода. Эта максимальная производительность может быть получена, когда volblocksize соответствует или слегка превышает размер самой частой произвольной операции ввода-вывода в выполняемой рабочей нагрузке.
Это означает, что для базы данных PostgreSQL, использующей страницы по 8 КиБ, нужно использовать volblocksize равный 8 КиБ или 16 КиБ. И хотя 8 КиБ обеспечивает полное соответствие, 16 КиБ может быть предпочтительнее — больший volblocksize обеспечивает более высокий потенциал сжатия и больше размер операции ввода-вывода на диск (то есть повышенное быстродействие каждого диска). Что касается жалобы на шум — нам определённо нужно придерживаться большего volblocksize, поскольку больший размер отдельных операций означает меньше позиционирований головки, а значит, меньше шума от приводов.
Тем не менее большинство виртуальных машин не работают исключительно с PostgreSQL. Даже в мире движков баз данных — самых чувствительных к задержкам приложений — MySQL InnoDB по умолчанию использует страницы по 16 КиБ, а в MSSQL их размер обычно составляет 64 КиБ. Тем временем VM, используемые для масштабного хранения «ISO Linux» чаще всего перемещают целые файлы по несколько ГиБ.
Для виртуальных машин общего назначения я рекомендую volblocksize = 64 КиБ. Это будет золотая середина между минимальной задержкой и максимальной пропускной способностью при хорошем потенциале к сжатию.
При volblocksize = 16 КиБ в пуле, состоящем из трёх Z1 vdev шириной в 4 диска, наш пользователь неоправданно теряет значительную долю эффективности, получая при этом лишний шум. Каждая запись в каждом vdev производится всего на три из четырёх дисков и состоит из всего одного сектора на диск — максимально увеличивая фрагментацию, которая, в свою очередь, минимизирует быстродействие и повышает шум. Всё это сопровождается потерей общей эффективности хранилища, которую пользователь наверняка рассчитывал получить.
И хотя мы не знаем точно, какую рабочую нагрузку этот пользователь предполагает для своей VM, можно предположить некую комбинацию операций с файлами и работы в десктопном UI — иными словами, стандартное использование. В таком случае обычно желательно, чтобы размер блока составлял примерно 64 КиБ.
Если мы решим перекроить пул, сделав четыре Z1 из 3 дисков вместо трёх Z1 из четырёх, а также поменяв volblocksize с 16 КиБ на 64 КиБ, то значительно повысим эффективность и производительность хранилища, попутно уменьшив шум.
Разберём процесс записи 64 КиБ в наш исходный пул и тех же 64 КиБ в его уже изменённую форму при всё тех же двенадцати дисках:
Когда мы сравниваем эти две конфигурации, то видим, что исходный пул для передачи каждых 64 КиБ требует аж в пять раз больше операций записи в сравнении с исправленной версией.
Это, естественно, означает, что изменённая конфигурация будет отличаться значительно повышенной производительностью — и, благодаря выводам из предыдущих разделов, мы также знаем, что попутно повысим эффективность хранилища.
Самое же главное — поскольку основной проблемой пользователя был шум, а не производительность или ёмкость — 20% из всех операций записи означает 20% дополнительных возможностей для выполнения позиционирования головки. То есть теперь мы можем ожидать, что наш пул из 12 дисков будет работать намного тише.
И если этого мало, пул из шести зеркал шириной в два диска требует для передачи тех же 64 КиБ данных всего двух операций записи шириной в 16 секторов. И это всего 12,5% от отдельных операций записи, которые требовалось выполнять при исходной конфигурации.
Будет понятнее, если рассмотреть визуальное представление записи 64 КиБ данных в нескольких вариантах рассмотренных нами топологий при разных volblocksize, начиная с менее производительного (и менее шумного) до наиболее быстрого (и самого тихого).
Мы покажем все 12 дисков и то, как они упорядочены в пуле, после чего продемонстрируем каждую последовательную операцию записи, необходимую для передачи в этот пул 64 КиБ. Серые ячейки представляют не пустую область — они просто показывают, что для операции записи этот диск не использовался.

Изображение: Jim Salter, CC-BY-SA 4.0
Если бы мы работали с Proxmox 7 или ниже, то в качестве volblocksize использовали величину 8 КиБ. Но блок 8 КиБ никак не растянуть по RAIDz1 шириной четыре, поэтому мы последовательно записываем полосы из 3 блоков по группам из четырёх дисков.
Это даёт ужасные результаты в плане производительности и шума — каждый из дисков при каждой записи в vdev вынужден выполнять отдельные операции по 4 КиБ (один сектор).
Нам нужно выполнить 24 отдельных операции записи, каждая шириной в один сектор… в результате чего остаётся лишь надеяться, что OpenZFS хотя бы удастся смежно расположить основную часть этих операций сейчас и в будущем.

Изображение: Jim Salter, CC-BY-SA 4.0
Начиная с Proxmox 8, базовый volblocksize стал равен 16 КиБ. В целом это улучшает ситуацию, но всё же оставляет нас в затруднительном положении из-за неоптимального размера vdev.
Для того, чтобы записывать блоки по 16 КиБ, OpenZFS записывает на каждое vdev по одной полной полосе (по одному сектору на каждый диск), сопровождаемых записью частичной полосы. Первая полоса содержит три из четырёх секторов данных, которые нам нужно записать, а также один сектор чётности. Вторая полоса состоит из оставшегося сектора данных, а также соответствующего ему сектора чётности.
Эта мешанина позволяет дискам выполнять операции по 8 КиБ примерно вдвое быстрее, а операции по 4 КиБ ещё вдвое быстрее. Это определённо улучшение, но для передачи 64 КиБ на диск нам всё равно нужно 18 отдельных операций записи.

Изображение: Jim Salter, CC-BY-SA 4.0
На этот раз мы смотрим на Z1 vdev с идеальной шириной и volblocksize = 64 КиБ, наблюдая кардинальные отличия. Здесь нам нужно записывать всего один блок, и этот блок задействует лишь три диска.
Мы передали на диск те же 64 КиБ, но дали приводам в шесть раз меньше возможностей для позиционирования головки (напомним: лишнее позиционирование снижает производительность и создаёт шум).
Кроме того, мы в общей сложности использовали также 24 сектора по 4 КиБ, как и в случае с двумя Z1 vdev из четырёх дисков. Хорошо запомните этот урок — если vdev немного шире, это не обязательно обеспечит повышенную эффективность хранилища.

Изображение: Jim Salter, CC-BY-SA 4.0
Наконец, рассмотрим мою любимую топологию для относительно небольших пулов — зеркальные vdev. Мы по-прежнему используем volblocksize = 64K, поэтому также отправляем в пул по одному блоку — но теперь делаем запись только на два диска, а не три, потенциально на 1/3 снижая шум, который создавал RAIDz1 из 3 дисков выше.
Наши зеркальные vdev предлагают чуть более высокую производительность, чем даже vdev RAIDz1 из 3 дисков: мы получаем вдвое меньше vdev и удваиваем количество IOPS (операций ввода-вывода в секунду) на каждое. При этом также слегка повышается устойчивость к сбоям — каждое vdev выдерживает лишь один сбой работы диска, но сейчас в каждом vdev присутствует меньше дисков.
Если вы хотите ещё больше повысить устойчивость к сбоям, рассмотрите вариант с RAIDz2 шириной в 4 или 6 дисков.
Несмотря на то, что мы успешно ответили на вопрос: «Почему мои диски шумят?», мы не до конца ответили на ещё более важный вопрос «Как избавиться от их шума?».
Путём грамотной настройки топологии пула и размера блоков можно значительно снизить количество позиционирований головок приводов, что, в свою очередь, сделает их менее шумными. Но тут следует задаться таким вопросом: «А как избавиться от шума полностью?»
Степень шума, издаваемого механическими приводами, в значительной степени определяется корпусом, в который вы их устанавливаете. В идеале вам нужен тяжёлый алюминиевый или стальной системник, в котором приводы крепятся винтами с резиновыми уплотнителями, и в местах их установки имеются резиновые прокладки.
Демпфирование вибраций на корпус — желательно с тяжёлыми стенками (в идеале не геймерскими стекляшками) — способно чудесным образом значительно снизить издаваемый вашими приводами шум.
Автор: Bright_Translate
Источник [4]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/hranilishha-danny-h/398559
Ссылки в тексте:
[1] Practical ZFS: https://discourse.practicalzfs.com/
[2] кадиллак Джонни Кэша: https://www.atlasobscura.com/places/johnny-cash-s-one-piece-at-a-time-cadillac
[3] сказал: https://www.delphix.com/blog/zfs-raidz-stripe-width-or-how-i-learned-stop-worrying-and-love-raidz
[4] Источник: https://habr.com/ru/companies/ruvds/articles/847882/?utm_source=habrahabr&utm_medium=rss&utm_campaign=847882
Нажмите здесь для печати.