суббота, 6 ноября 2010 г.

Фрагментация ZFS - мифы и реальность

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

Давайте расставим точки над Ё.

Прежде всего, определимся со спецификой предмета.

Да, существует такое явление, как фрагментация файловых систем.

На UFS фрагментация диагностируется средствами fsck - которая сразу показывает степень фрагментированности файловой системы. На ZFS инструмента, который бы показывал фрагментированность файловых систем и (опционально) позволял бы выполнять дефрагментацию, не существует.

Соответственно, отсутствие такого инструмента сразу ставит под вопрос большинство заявлений о фрагментации ZFS. 


Ах, ничем... А на основании чего тогда делаются подобные заявления?

Один из наиболее корректных материалов на данную тему был найден здесь.

Вкратце суть этого документа можно пересказать так.

ZFS действительно выделяет пространство экстентами (параметр recordsize), размер которых по умолчанию равен 128К. Это действительно великовато для многих приложений, однако у вас всегда существует возможность изменить размер экстента, как на уровне пула, так и на уровне файловой системы в диапазоне от 512 байт до 128К. 

Да, небольшие файлы могут не заполнять экстент целиком, а идеология COW может привести к появлению некоторого количества мертвого пространства на уровне частично заполненных экстентов. Однако внутренняя структура данных ZFS такова, что данное явление может проявляться лишь кратковременно. Даже UFS умеет использовать частично заполненные блоки для минимизации фрагментации.

Метаданные в ZFS организованы таким образом, что фрагментации на уровне экстентов как таковой нет и быть не может. Читайте исходники.

Тюнить не пробовали?
Если вы ожидаете, что дефолтные настройки ZFS позволят удовлетворить любые требования (один размер для любого), то вы ошибаетесь. И это не недостаток системы, а ее функциональная особенность, позволяющая создавать файловые системы с разным размером экстента для различных задач и приложений.

Говоря простым языком, всего лишь выберите подходящий размер recordsize для вашей файловой системы и проблемы как таковой не будет.

Есть другая сторона медали и она была хорошо документирована.

При высокой степени заполнения пулов идеология COW начинает запинаться, поскольку некуда писать измененные копии данных. Что вызывает резкое падение производительности и увеличение нагрузки на процессор. Данная поведенческая особенность, в общем, совершенно естественна и вытекает из достоинств системы. Собственно, нетрудно было догадаться, что COW будет в подобном случае вести себя именно так. Вовремя расширяйте пулы, добавляя новые vdev, устанавливайте квоты и резервации файловых систем и все будет в порядке. Ах, вы ждали чуда, что система сама за вас все сделает... Ну так это не так. Правильное администрирование никто не отменял. Повторяю для тех, кто на бронепоезде. Квоты и резервации, поддерживаемые ZFS с самых первых релизов. Не допускайте чрезмерного заполнения ФС и все будет в порядке.

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

Если говорить о практической стороне дела, то автор больше трех лет круглосуточно эксплуатировал нагруженный прокси-сервер на ZFS под Solaris 10 с использованием зеркального пула с размером recordsize по умолчанию. Никакого заметного снижения производительности по мере роста аптайма не наблюдалось (это если говорить о гипотетической фрагментации, которая могла бы быть таком образом косвенно измерена), степень заполнения пула составляла около 40%, никаких эффектов и отклонений в худшую сторону по отношению к UFS (на которой первоначально был развернут сервер) не наблюдалось. Был лишь немного лимитирован размер кэша ZFS с целью освободить память под кэш прокси и уменьшить реальную конкуренцию за оперативную память между приложением и файловой системой.

В то же самое время свыше двух лет эксплуатировался сервер с БД Oracle 10 на ZFS. Были выполнены большинство рекомендаций Oracle по ZFS. Пул данных базы был структурирован на несколько файловых систем с разным значением recordsize. Время отклика БД после миграции с UFS на ZFS улучшилось с 0,1с до 0,02с и более не менялось. Степень заполнения пулов составила в среднем 55%.

Что я делаю не так?

1. Я не включаю компрессию пулов. Компрессирование данных на лету может сильно понизить производительность обменных операций. Это самоочевидно и не требует пояснений.
2. Во многих случаях имеет смысл ограничить кэш ZFS. Хотя она освобождает память по первому требованию, существует достаточное количество приложений, агрессивно использующих оперативную память.
3. Я не использую RAID-Z. Я считаю, что большинство RAID-5-подобных организаций недостаточно производительны.
4. При создании зеркальных пулов я высаживаю разные шпиндели на разные контроллеры (каналы ввода вывода).
5. Я выбираю размер recordsize адекватно среднему и ожидаемому размеру файлов, которые предполагаю хранить на ФС.
6. Я никогда не ставлю ZFS поверх аппаратного или софтверного RAID. Это глупо, иррационально и снижает производительнось. А также напоминает известный анекдот про монашку, свечку и презерватив.

В общем-то, это все, коллеги. Никаких волшебных средств и серебряных пуль.