What the eyes see and the ears hear, the mind believes
Я решил вплотную заняться тюнингом своего хранилища.
дальнейший текст будет полезен/интересен либо для IT-просвященных, либо чтобы просто оценить глубину моего падения
Вот не подумал бы , что буду лезть править поведение ядра freebsd. А не подумал бы почему? FreeBSD многим кажется и казалась мне чем-то аццки сложным, хитрым и из-за того надежным (не зря же у них символ - хитрый чёртик), и кажется, что лезть в её внутренности как-то стремно (потому как трудно) и некошерно (потому как много умных людей уже там все сделали "как надо"). Отчасти так и есть: "фря" - действительно нечто аццки хитрое и надежное и у нее внутри действительно умные люди все сделали так, что out_of_the_box оно будет надежно работать для широкого круга конфигураций и задач. Но предусмотреть все невозможно в принципе, к тому же есть различные workload-ы, которые требуют от операционной системы диаметрально противоположного поведения. Вот здесь-то и вступает в игру тюнинг ядра ОС под конкретную задачу. И как показывает практика в этом аспекте freebsd не совсем оправдывает мнение, что "лезть ей под капот" - процедура архисложная и только для мегазадротов, которые в случае чего включат дебаг и полезут трэйсить ассемблерные вызовы. На самом деле для тюнинг ядра - процедура технически не сложная, просто нужно четко понимать что ты делаешь и какие будут от этого эффекты.
Начну издалека. It's all about memory, and OS memory management. То есть (практически) главное в работе ОС - это распределение и использование памяти. При неправильной политике распределения памяти возникают неприятности, торможения, в худшем случае - крах ядра ОС и ребут/фриз. Управление памятью, к счастью, не является слабой стороной unix-систем, да и никогда таковой не была. FreeBSD памятью управляет хорошо, можно сказать среднестатистически-оптимально. Но, как я уже говорил, для оптимизации производительности специфических workload-ов требуются специфические настройки... то есть нужно просто подсказать операционке что именно мы от нее хотим. Для этого надо понять это самому, что , соответственно, влечет определенное изучение организации неких внутренностей ОС. Вот этим я и занимался последнее время.
Ситуация моя такова: есть самосборный NAS, который состоит из процессора Celeron E3200 (LGA775, 2 ядра, 2.4 ГГц, Wolfdale), четырех гигабайт оперативы DDR3 и четырех дисков WD15EADS (Caviar Green 1.5 ТБ, SATA2, 5400rpm) + Samsung 500G 7200 rpm. Поверх всего этого с флэшки работает freebsd и в качестве файловой системы я выбрал ZFS. Про выбор ФС я уже писал, и с тех пор я ZFS изучил глубже и убедился, что это однозначно труЪ. Даже подумываю набросать научно-познавательный пост про вкусности ZFS. В общем передо мной встал выбор оставить как есть или полезть в оптимизацию... естественно, выбор предопределен: лезем оптимизировать. Начинаем читать литературу и форумы и впитывать информацию. В этом месте я обрадовался, что выбрал 64хбитую версию, в которой значительно улучшен механизм распределения памяти между "kernel cage" и "userspace". В моем случае это важно, так как интеллектуальный кэш ZFS-а, и его префетчер хранят данные именно в памяти ядра, что полностью исключает вариант swapout-а этих данных на диск (а засвопить кэш файловой системы - это полный бред... можно сравнить например с километровым походом по морозу на стоянку за автомобилем, чтоб на нем 500 метров проехать от дома до магазина в тепле). Так вот, кэш - штука хорошая, при чем чем больше - тем лучше. И на системах архитектуры i386 рост этого кэша вызывал проблемы. Изначально не предполагалось, что ядро будет расти до больших объемов, так как в те времена и памяти столько не было, да и ядро вроде как должно просто обеспечивать работу процессов в userspace. Соответственно в релизах i386 под память ядра изначально не выделено даже подобающее адресное пространство. Ну а 64хбитные архитектуры с рождения не имеют ограничений по адресному в силу своей 64хбитности
. Кроме того во времена изобретения и массового распространения машин 64хбитной архитектуры памяти уже было у всех много и этот факт так же учли. В общем и целом freebsd-amd64 научена правильному и хорошему memory management и по результату максимальный размер памяти ядра (при автопрофилировании) составляет порядка 95% физически установленной памяти (в 32хбитных версиях для увеличения доступной для распределения памяти ядра выше гигабайта приходилось пересобирать ядро, а для использования больше 3 гигабайт - собирать PAE версию с отключением многих полезностей).
Теперь беремся за непосредственно мой workload. Что нужно от хранилища и чем оно будет заниматься? Нужно оптимальное хранение терабайт данных и скоростной доступ к ним. Что там будет работать? Файловая система, отвечающая за хранение и скоростной доступ к данным для ОС, и сервисы, которые обеспечивают клиентский доступ к данным. Сервисы - это NFS, SMB и FTP... то есть в userspace, в моем случае, не будет никаких memory-intensive движений. Соответственно подавляющее большинство оперативки можно отдать на откуп ядру и файловой системе дабы повысить производительность работы с данными. Вот об этом факте freebsd в принципе не знает и ведет себя не оптимально для такой задачи. "Из коробки" она настроила максимальный размер kernel cage на 3.5 гигабайта и максимальный размер кэша ZFS (который, к слову, называется ARC - Adaptive Replacement Cache) 950 МБ. В результате в системе (после стабилизации под типичной нагрузкой I/O) остается 1.7-1.8 гиг памяти, которую ОС "приберегла на случай ядерной войны" (ну или я, например, захочу запустить БД на гиг) и которая мне не нужна вообще (так как я не собираюсь запускать БД на гиг
).
В общем смысл ясен - надо сказать фре, и больше ZFS-у, чтоб они не стеснялись жрать память, так как они и являются основными потребителями, и именно они и есть production load. Практически все параметры freebsd смотрятся/правятся в sysctl. Но переменные, которые вызывают серьезные system-wide изменения, обычно через sysctl не правятся, и вообще во время работы ОС изменению не подлежат. И все параметры, которые мне надо было поменять как раз к таким и относятся. Такие переменные задаются во время загрузки и фиксируются. Менять их можно в loader.conf, и вот тут у меня начинаются проблемы. Система зрузится с флэшки, причем на флэшке образ, который распаковывается при загрузке и править файлы внутри образа - удовольствие сомнительное, но пришлось. В итоге пока мне почему-то не удается задать размер ARC больше 1250 мегабайт. Пока, в принципе, хватает, но надо разбираться. Вообще можно использовать на не-RAID диске (он у меня под промежуточное хранение данных... всякие торренты, прочие качалки) UFS вместо ZFS, у нее тоже есть кеш (правда не такой умный) и хранит она его в userspace. Но я все-таки хочу ZFS везде и хочу размер ARC в 2.5 ГБ. Буду бороться дальше.
И скоро-таки напишу пост про ZFS... уж очень хороша.
дальнейший текст будет полезен/интересен либо для IT-просвященных, либо чтобы просто оценить глубину моего падения

Начну издалека. It's all about memory, and OS memory management. То есть (практически) главное в работе ОС - это распределение и использование памяти. При неправильной политике распределения памяти возникают неприятности, торможения, в худшем случае - крах ядра ОС и ребут/фриз. Управление памятью, к счастью, не является слабой стороной unix-систем, да и никогда таковой не была. FreeBSD памятью управляет хорошо, можно сказать среднестатистически-оптимально. Но, как я уже говорил, для оптимизации производительности специфических workload-ов требуются специфические настройки... то есть нужно просто подсказать операционке что именно мы от нее хотим. Для этого надо понять это самому, что , соответственно, влечет определенное изучение организации неких внутренностей ОС. Вот этим я и занимался последнее время.
Ситуация моя такова: есть самосборный NAS, который состоит из процессора Celeron E3200 (LGA775, 2 ядра, 2.4 ГГц, Wolfdale), четырех гигабайт оперативы DDR3 и четырех дисков WD15EADS (Caviar Green 1.5 ТБ, SATA2, 5400rpm) + Samsung 500G 7200 rpm. Поверх всего этого с флэшки работает freebsd и в качестве файловой системы я выбрал ZFS. Про выбор ФС я уже писал, и с тех пор я ZFS изучил глубже и убедился, что это однозначно труЪ. Даже подумываю набросать научно-познавательный пост про вкусности ZFS. В общем передо мной встал выбор оставить как есть или полезть в оптимизацию... естественно, выбор предопределен: лезем оптимизировать. Начинаем читать литературу и форумы и впитывать информацию. В этом месте я обрадовался, что выбрал 64хбитую версию, в которой значительно улучшен механизм распределения памяти между "kernel cage" и "userspace". В моем случае это важно, так как интеллектуальный кэш ZFS-а, и его префетчер хранят данные именно в памяти ядра, что полностью исключает вариант swapout-а этих данных на диск (а засвопить кэш файловой системы - это полный бред... можно сравнить например с километровым походом по морозу на стоянку за автомобилем, чтоб на нем 500 метров проехать от дома до магазина в тепле). Так вот, кэш - штука хорошая, при чем чем больше - тем лучше. И на системах архитектуры i386 рост этого кэша вызывал проблемы. Изначально не предполагалось, что ядро будет расти до больших объемов, так как в те времена и памяти столько не было, да и ядро вроде как должно просто обеспечивать работу процессов в userspace. Соответственно в релизах i386 под память ядра изначально не выделено даже подобающее адресное пространство. Ну а 64хбитные архитектуры с рождения не имеют ограничений по адресному в силу своей 64хбитности

Теперь беремся за непосредственно мой workload. Что нужно от хранилища и чем оно будет заниматься? Нужно оптимальное хранение терабайт данных и скоростной доступ к ним. Что там будет работать? Файловая система, отвечающая за хранение и скоростной доступ к данным для ОС, и сервисы, которые обеспечивают клиентский доступ к данным. Сервисы - это NFS, SMB и FTP... то есть в userspace, в моем случае, не будет никаких memory-intensive движений. Соответственно подавляющее большинство оперативки можно отдать на откуп ядру и файловой системе дабы повысить производительность работы с данными. Вот об этом факте freebsd в принципе не знает и ведет себя не оптимально для такой задачи. "Из коробки" она настроила максимальный размер kernel cage на 3.5 гигабайта и максимальный размер кэша ZFS (который, к слову, называется ARC - Adaptive Replacement Cache) 950 МБ. В результате в системе (после стабилизации под типичной нагрузкой I/O) остается 1.7-1.8 гиг памяти, которую ОС "приберегла на случай ядерной войны" (ну или я, например, захочу запустить БД на гиг) и которая мне не нужна вообще (так как я не собираюсь запускать БД на гиг

В общем смысл ясен - надо сказать фре, и больше ZFS-у, чтоб они не стеснялись жрать память, так как они и являются основными потребителями, и именно они и есть production load. Практически все параметры freebsd смотрятся/правятся в sysctl. Но переменные, которые вызывают серьезные system-wide изменения, обычно через sysctl не правятся, и вообще во время работы ОС изменению не подлежат. И все параметры, которые мне надо было поменять как раз к таким и относятся. Такие переменные задаются во время загрузки и фиксируются. Менять их можно в loader.conf, и вот тут у меня начинаются проблемы. Система зрузится с флэшки, причем на флэшке образ, который распаковывается при загрузке и править файлы внутри образа - удовольствие сомнительное, но пришлось. В итоге пока мне почему-то не удается задать размер ARC больше 1250 мегабайт. Пока, в принципе, хватает, но надо разбираться. Вообще можно использовать на не-RAID диске (он у меня под промежуточное хранение данных... всякие торренты, прочие качалки) UFS вместо ZFS, у нее тоже есть кеш (правда не такой умный) и хранит она его в userspace. Но я все-таки хочу ZFS везде и хочу размер ARC в 2.5 ГБ. Буду бороться дальше.
И скоро-таки напишу пост про ZFS... уж очень хороша.