пятница, 7 октября 2011 г.

Повышение системных лимитов в Solaris 10

Хотя Солярис достаточно неплохо оптимизирован "из коробки", в некоторых случаях может возникнуть необходимость повысить системные лимиты, например, с целью масштабирования системы.

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

Как и обычно, все это делается через kernel tunables. Да, безусловно, можно попробовать поиграться с ulimit, НО - не все глобальные параметры можно изменить даже от рута.
Рассмотрим простенький пример. Прокси-сервер бизнес-центра. Должен масштабироваться по умолчанию. Железка достаточно сильная, однако в пиках нагрузки дает too many open files/too much user processes.

Вскрытие показывает, что на машине работает Squid с 192 редиректорами (суммарно). Ругается на процессы/открытые файлы явно прокси.

ulimit показывает нам маленькое количество файловых дескрипторов на пользователя и лимит в 27 с чем-то тысяч процессов на пользователя.

Мониторинг сервера показывает наличие свободных ресурсов по памяти и процессору (само собой разумеется, Squid не склонен к перегрузке процессоров).

Что ж, увеличиваем:

set rlim_fd_max=65536


Перезапускаем, смотрим. Ругань на файлы исчезла, ulimit показывает заданную величину.

Займемся процессами.

set max_nprocs=65536
set maxuprc=32767


Первый параметр - максимально количество процессов в системе. По умолчанию около 30 тысяч. Если его не задать, второй параметр будет ограничен той же величиной (чуть меньшей, 29995).

Перезапускаем. Смотрим:

root @ ktulhu / echo max_nprocs/D | mdb -k
max_nprocs:
max_nprocs:     30000
root @ ktulhu /

root @ ktulhu / echo maxuprc/D | mdb -k
maxuprc:
maxuprc:        29995


Почему? Мы ведь увеличили таблицу процессов. Оказывается, мы забыли один лимитирующий параметр, впрямую связанный с max_nprocs - pidmax. Задаем:

set rlim_fd_max=65536
set pidmax=65536
set max_nprocs=65536
set maxuprc=32767


Перезапускаемся еще раз. Проверяем:

root @ ktulhu / # ulimit -a
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 10
stack size              (kbytes, -s) 10240
cpu time               (seconds, -t) unlimited
max user processes              (-u) 32767
virtual memory          (kbytes, -v) unlimited


Вот теперь порядок. Наша заданная величина max user processes установлена глобально, проблема решена.

Маленькое предупреждение напоследок. Повышение системных лимитов не должно выполняться бездумно. Это чревато, например, исчерпанием их в случае перегрузки сверх расчетных пределов. Желательно запустить калькулятор и перед повышением оценить и просчитать возможности сервера по повышению этих самых лимитов. В противном случае неумышленный DDoS весьма вероятен.

PS. С другой стороны, планка оперативной памяти стоит как лопата дерьма и, в нашем конкретном примере с прокси, при необходимости можно достаточно легко нарастить физические пределы сервера по процессам. В любом случае следует помнить, что оптимизация производительности и масштабирование на 90% состоят из мониторинга и медитации.