Сегодняшний материал об отличиях в ядрах server-версии Ubuntu от
desktop-версии. Он поможет вам понять, почему использование серверной
версии все-таки предпочтительнее именно для решения серверных задач, на
тот случай, если вы вдруг задумали заточить под это дело desktop-версию.
Кроме того, для тех, кто еще только осваивает ядро Linux или
готовится сделать свою первую пересборку ядра, здесь есть довольно
интересная и полезная информация.
Внимание, материал создан на базе статьи, оригинал которой лежит здесь (часть 1, часть 2), автор Carla Schroder.
Итак, чем кроме меньших требований к
ресурсам и отсутствием графического интерфейса отличается Ubuntu
Server, копнем вглубь ядра.
Чтобы выяснить это, мы будем сравнивать файлы (Server) /boot/config-2.6.22-14-server и (Desktop) /boot/config-2.6.22-14-generic.
Подмонтируем два .iso образа во временную директорию, извлечем файлы, а затем сравним их (работаем из под root):
Теперь эти файлы надо распаковать в две различные директории,
поскольку внутри deb архива есть файлы с одинаковыми именами:
control.tar.gz, data.tar.bz2, и debian-binary.
Используем команды ar и tar для распаковки .deb файлов, и разпаковки находящихся в них .tar.gz файлов:
# ar -x linux-image-2.6.22-14-server_2.6.22-14.46_i386.deb
# tar jxvf data.tar.bz2
Теперь достаем из директории boot, файлы config-2.6.22-14-server и
config-2.6.22-14-generic, копируем в одну директорию и сравниваем их:
Получаем вывод diff: несколько десятков отличий, в сравнении 3,100 строк этих файлов.
Давайте рассмотрим эти отличия.
Тип ввода-вывода
Существует четыре различных типа планирования I/O (ввода/вывода): CFQ (Completely Fair Queuing), Deadline, NOOP, и Anticipatory.
Ubuntu по умолчанию для десктопов ставит CFQ, а Deadline для серверов.
Цель, преследуемая планированием ввода/вывода одинакова:
оптимизировать пропускную способность жесткого диска для различных
классов рабочей нагрузки.
В вашем конфигурационном файле это описано опциями CONFIG_DEFAULT_IOSCHED, CONFIG_IOSCHED_CFQ, _DEADLINE, _AS, _NOOP.
* CFQ пытается сбалансировать и сделать равными все запросы на чтение/запись.
* Deadline дает приоритет на запросы чтения.
* Anticipatory дает приоритет уже запущенным приложениям.
* NOOP рассчитан на системы с железом, поддерживающим планирование I/O, например большие RAID-массивы SCSI.
Вопрос о предпочтительном типе ввода/вывода упирается в имеющееся у
вас железо: сколько в вашем компьютере процессоров, жестких дисков,
каковы типы запускаемых приложений и какова нагрузка, с которой должна
справляться ваша система.
Можете поэкспериментировать с этими значениями, сверить
бенчмарк-тесты и соответсвенно выбрать для себя самую оптимальную
опцию. Кстати, можно указывать эти опции при загрузке, использовать
различные типы для любого блочного устройства или менять их на лету.
Идущие по умолчанию значения в Ubuntu – неплохие для начала, но если вы
хотите их поменять, то сделать это можно так же, как и в любом другом
дистрибутиве Linux.
У серверного ядра оно выключено(CONFIG_PREEMPT_NONE=y), а у
десктопного ядра – включено (CONFIG_PREEMPT_BKL=y,
CONFIG_PREEMPT_VOLUNTARY=y). ППО взаимодействует с планированием
ввода/вывода, для достижения лучшей производительности, большей
эффективности и отдачи. В ядрах без ППО код выполняется вплоть до
завершения. Поскольку ядро Linux позволяет прервать любую задачу в
любой точке ее работы (но, конечно не в тот момент, когда это
небезопасно), и задачи с меньшим приоритетом могут выскочить наверх
списка задач, то ППО подходит именно для десктоп-систем, потому что
пользователи обычно выполняют множество задач одновременно: пишут
документы, слушают музыку, загружают файлы и т.п. И пользователям
безразлично насколько эффективно фоновое приложение, им важно то
приложение, с которым они в данный момент работают.
Если загрузка веб-страницы будет длится чуть дольше, пока
пользователь пишет e-mail, что же, это приемлемая цена. В общем,
эффективность и производительность снижаются, но не настолько, чтобы
пользователя это беспокоило.
На серверах вам необходимо минимизировать любые и все возможные
перепады в производительности, поэтому обычно и практикуется отключение
ППО.
Память.
32-битное серверное ядро поддерживает до 64 Гб памяти, ядро десктопа
4 Гб – (CONFIG_HIGHMEM64G=y, CONFIG_HIGHMEM4G=y). Эти опции можно
увидеть только в 32-битных ядрах, поскольку 32-битная адресация
позволяет по честному поддерживать только 4 Гб. Ну а 64 Гб доступны
только с Intel Physical Address Extension (PAE). Linux поддерживает
PAE, но вам будет нужна и поддержка PAE в вашем CPU (процессоры новее
чем Pentium Pro или AMD K6-3 сойдут). На 64-битной системе вы не
увидите таких опций, потому что там нет недостатка в адресном
пространстве для памяти.
Тики и Герцы (Ticks & HZ)
Оба ядра поддерживают таймеры прерывания по-запросу(CONFIG_NO_HZ=y),
так называемая "tickless” опция. Это значит, что в периоды отсутствия
активности система действительно бездействует, это предполагает меньший
расход энергопотребления и меньший нагрев процессора.
Таймер прерываний ядра сервера установлен на 100 Гц (CONFIG_HZ=100,
CONFIG_HZ_100=y), что означает, что он принимает 100 прерываний своей
деятельности в секунду. С другой стороны на это можно взглянуть так:
ядро 100 раз в секунду проверяет есть ли у процессора какие-либо задачи.
Таймер прерываний ядра десктопа установлен в 250 Гц. Меньшие
значение означают меньшие издержки и высокие задержки, большие значения
– высокие издержки и меньшие задержки, то есть при больших значениях
система быстрее отвечает, но ценой высокой нагрузки на процессор.
Некоторые процессы требуют больших значений прерываний, например
сервера обработки видео и голосовых данных (VoIP) требуют 1000Гц.
Если вам нужно поменять это значение, вам придется перекомпилировать ядро.
Семейства CPU
Серверное ядро использует опцию CONFIG_M686=y, а десктопр CONFIG_M586=y.
Это означает, что ядро сервера оптимизировано под набор инструкций
Pentium Pro, а ядро десктопа работает с семействами 586 и 686. Честно
говоря даже ядро для 486 системы будет работать на современных машинах,
поэтому при компиляции своих ядер, знайте, что для лучшей
производительности опция CPU должна соответствовать вашему процессору,
чтобы полноценно работать с его набором инструкций.
Утечка в пространстве имен
До того, как появилась виртуализация, существовал один набор
объектов Inter-Process Communications – IPC, (shared memory segments,
message queues и semaphores), которые ядро использовало для всего. Но
виртуальное окружение должно сохранять свои собственные IPC внутри
своих контейнеров, без возможности утечки. Это включено в ядре
сервера(CONFIG_IPC_NS=y, CONFIG_UTS_NS=y) и не включено в ядре десктопа.
Означает ли это, что виртуальное окружение небезопасно и имеет утечки в
ядре для десктопа? (Прим.: скорее эта фича необходима для однозначной
подстраховки от утечек для серверной версии)
И финальное отличие: ядро сервера поддерживает множественные таблицы маршрутизации IPv6, которые ядро десктопа не поддерживает.