вторник, 27 мая 2014 г.

Solaris: Resource capping

После пересборки Squid 2.7 в полностью 64-битном режиме я столкнулся с тем, что памяти стало как-то неуютно не хватать. Более того - стал появляться свопинг. На машине, где его прежде не было. Кроме чисто символического.


Это само по себе достаточно неприятное явление, кроме того, на сервере стоит ZFS (с ограничением ARC до номинального 1 Гб). И провоцирует эпизодический IO.

Изучение вопроса напомнило вот об этом: http://wiki.squid-cache.org/SquidFaq/SquidMemory

Однако еще более тщательное изучение показало, что речь идет не об утечках памяти. А о склонности сквида выползать за границы cache_memory. Особенно с учетом дочерних процессов - AIO, редиректоров итп. Это вовсе не вся память, которую использует Squid.

При конфигурировании Squid важно помнить, что не стоит задавать чрезмерно большого значения maximum_object_size_in_memory. Это приведет к непродуктивному перерасходу кэша в оперативной памяти и к быстрому расползанию процессов squid в RAM. Опытным путем были установлены оптимальные значения для данной конкретной инсталляции:


Обратите внимание: cache_mem и memory_pool_limit вы можете скорректировать по своей необходимости (в зависимости от вашего объема доступной физической памяти на сервере).

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

Первое действие - собрать Squid с dlmalloc, причем сама библиотека должна собираться thread aware:


'--enable-dlmalloc' 'CFLAGS=-DMSPACES -DUSE_LOCKS'


Кроме того, у нас есть rcapd. Зададим необходимые параметры и запустим службу:

root @ ktulhu / # rcapadm -c 95 -E

Получаем следующую конфигурацию:



95% в случае RCAP означает, что реальный resource capping начнется лишь при заполнении физической памяти на 95% (документация rcapd совершенно четко объясняет работу службы). Значение по умолчанию - 0, что означает "capping всегда действует, если заданы ограничения".

Кроме этого, необходимо явно задать ограничения пользователю/группе/процессу с помощью /etc/project:

/etc/project не редактируется руками, для его модификации используются команды projadd/projmod/projdel. В нашем случае используется команда:

projadd -n -c "Squid processes" -U squid -G squid -p 100 -K rcap.max-rss=1500MB user.squid


Для того, чтобы ограничение начало работать, необходимо обеспечить запуск процессов контролируемого пользователя посредством команды newtask:


Так как процессы нашего пользователя управляются SMF, модифицируем контролирующий скрипт (управляющий метод):



Как видно из скрипта, в случае, если запись в /etc/project создана, процесс будет запущен посредством newtask с использованием созданного проекта и его ресурсных ограничений, которые и будет контролировать rcapd.

Чтобы убедиться, что все сделано правильно и rcapd работает (а также для мониторинга rcap), используется штатная утилита rcapstat:


Вызванная без параметров, она будет использовать установки rcap из /etc/rcap.conf:


и будет выполняться непрерывно до нажатия Ctrl+C.