Skip to content


About code writing...

"Debugging is twice as hard as writing the code in the first place. Therefore, if you write the code as cleverly as possible, you are, by definition, not smart enough to debug it." - Brian W. Kernighan.

Posted in Цитатник.


Былина о memory overcommit

Давным-давно в одной далёкой деревне заморской жили серверов линуксячих CentOS-ных десятков пару. Ядра – чистый изумруд (2.6.18-194.17.1.el5). Жили-не тужили, винтами шуршали да лампочками весело перемигивались. И жили вместе с ними в той деревне девелопер-буйная головушка и админ-добрый молодец. Девелопер всякие хитрые штуки на java выдумывал, а админ мёд-пиво пил, по усам текло, на клавиатуру капало.

И вот однажды девелоперу пришла в светлу головушку мысль – на этих серверах всякие документы дивные в форматах иноземных в чистый html превращать, да не просто превращать, а через openoffice. Задумано - сделано. И стали вдруг в одночасье чудеса происходить - сервера повадились один за другим кручиниться, работать как заведено переставали, на консоль жалобно писали, что, мол, нету в них больше силушки богатырской, ибо память оперативныя вся свободная вышла, и даже oom-killer делу не помогает (ибо хоть и пытается процессы до памяти охочие казнить, да редко попадает в какие нужно). Да не просто вышла, а так что и "swap free: 0Kb". И далее только волшебный ребут помогал. Загрустил тогда админ, ибо мёд-пиво больше пить было некогда, всё сервера упавшие только и поднимал. Да делать нечего – не будешь же писАлом на бересте html писать, openoffic-ом как-то всё ж сподручнее было.

Однажды приснился админу сон. Явился ему святой Патрег в золотом сиянии и говорит человеческим голосом: "А ты политику выделения памяти, издревле в линукс-ядрах по-умолчанию принятую, да поменял бы. Поставь vm.overcommit_memory=2 вместо дефолтного 0, авось, перестанет память заканчиваться". Послушался совета админ, поутру взял bash чудодейственный и сделал как ему Патрег во сне говорил:

echo 2 > /proc/sys/vm/overcommit_memory

И случилось чудо тогда – перестали сервера в кручину впадать, вновь заработали пуще прежнего. Возрадовался админ, и решил мудрость добытую в скрижалях высечь, дабы сыновьям и внукам легче было с норовистым линуксом совладать и еще впрок в /etc/sysctl.conf запасы сделал:

vm.overcommit_ratio = 100
vm.overcommit_memory = 2

Про vm.overcommit_ratio = 100 админ уже сам смекнул, ибо с дефолтным 50 слишком часто java "Cannot allocate memory" получала. И вот дошла с той поры мудрость следующая до наших времён:

Есть ядре два основных параметра, отвечающих за overcommit памяти:

  • vm.overcommit_memory — отвечает за стратегию overcommit.
  • vm.overcommit_ratio — отвечает за уровень (в процентах) overcommit-а

Стратегии есть такие (см. файл с исходниками ядра mm/mmap.c):

  • 0 - OVERCOMMIT_GUESS — эвристический подход к распределению памяти. В нем выделяется столько памяти, сколько хочет процесс. Но в swap/res попадает только те страницы, которые используются этим процессом.
  • 1 - OVERCOMMIT_ALWAYS — overcommit памяти есть всегда. Использовать лучше с совсем кривыми приложениями и быть готовым при этому ко всему.
  • 2 - OVERCOMMIT_NEVER — без overcommit. В этом случае допустимый объем пространства памяти будет swap+ram*overcommit_ratio/100 .

По умолчанию используется стратегия OVERCOMMIT_GUESS, а vm.overcommit_ratio находится в значение 50% и используется только в случае OVERCOMMIT_NEVER. Система резервирует около 3% памяти для процессов пользователя root.

Posted in *nix, Howto.

Tagged with , , , .


Terje Sørgjerd. Смотреть всем.

Смотреть со звуком

И подумать: "А что я сделал для того, чтобы сохранить красоту этой планеты?"

Вам требуется в Петербурге эрозионный прошивочный станок? обращайтесь: http://meatec.ru/

Posted in Разное.


Проброс портов с помощью xinetd

Когда возникает необходимость перенести какой-нибудь сервис с одного сервера на другой, иногда бывает сложно (или даже невозможно) сразу быстро переконфигурировать клиентов, работающих с этим сервисом, на использование нового IP-адреса. Эту проблему, конечно, проще всего было бы решить переносом старого IP-адреса на новый сервер, но если на старом сервере этот IP-адрес используется еще каким-нибудь другим сервисом, то данное решение не подходит. Поэтому в таком контексте часто возникает задача проброса портов, когда на старом сервере мы просто перенаправялем клиентов на новый сервер прозрачно и незаметно для последних. Один из вариантов решения такой задачи --- использование xinetd (extended Internet services daemon).
Пусть, для примера, у нового сервера будет IP-адрес 10.10.10.18, тогда конфиг xinetd будет примерно такой:

service redir8182
{
 disable = no
 type = UNLISTED
 socket_type = stream
 wait = no
 user = nobody
 group = nobody
 protocol = tcp
 port = 8182
 redirect = 10.10.10.18 80
 per_source = UNLIMITED
 instances = UNLIMITED
 cps = 10000 1
}

Это всё записываем в файл с именем redir8182 и кладём в директорию /etc/xinetd.d. В 3-ей строке мы говорим, что данный сервис активирован. В 4-й строке говорим, что данный сервис не является общеизвестным и не упоминается в файле /etc/services, следовательно xinetd не будет там его искать. Если опустить эту строку, то следует убедиться, что в файле /etc/services для нашего сервиса (redir8182) существует запись с указанием номера порта и при отсутствии такой записи добавить её. В 5-ой строке стоит stream, потому что сервис работает по протоколу TCP (для UDP следовало бы поставить dgram). В 6-ой строке указываем, что сервис является многопоточным (multi-threaded), то есть xinetd не будет ожидать завершения обработки n-го запроса, прежде, чем приступить к обработке (n+1)-го. В 7,8 строках указываем uid и gid порождаемых новыми подключениями процессов xinetd. Далее указываем протокол и порт, который слушает xinetd. В 11-ой строке указываем, что запросы нужно перенаправлять на хост 10.10.10.18 на порт 80. Последние 3 строки не обязательны, но они нужны для случаев, когда интенсивность запросов довольно велика и мы не хотим, чтобы xinetd стал узким местом (например, если пробрасываем порт mysql-сервера, который обслуживает сайт с посещаемостью в несколько тысяч хостов в минуту). Если их не указать, то будут использоваться значения по-умолчанию, указанные в xinetd.conf, которые могут быть совсем далеки от того, что мы ожидаем получить. Например, в случае с CentOS 5.5 настройки по-умолчанию (живут в /etc/xinetd.conf) такие:

  cps   = 50 10
  instances = 50
  per_source  = 10

То есть к сервису разрешено не более 50-ти подключений в секунду (строка 1) (в случае превышения сервис временно отключается на 10 секунд), количество одновременных подключений --- не более 50-ти (строка 2) и с одного IP-адреса не более 10-ти одновременных подключений (строка 3).

О своей работе xinetd обычно пишет в /var/log/messages (и туда же пишет об ошибках в конфиге, если таковые имеются). Чтобы заставить его перечитать кофиг, следует послать ему сигнал SIGHUP. Также проброс портов можно построить с помощью iptables.

Posted in *nix, Howto.

Tagged with , .