Skip to content


Былина о 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 чудодейственный и сделал как ему Патрег во сне говорил:

  1. echo 2 > /proc/sys/vm/overcommit_memory

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

  1. vm.overcommit_ratio = 100
  2. 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 будет примерно такой:

  1. service redir8182
  2. {
  3.  disable = no
  4.  type = UNLISTED
  5.  socket_type = stream
  6.  wait = no
  7.  user = nobody
  8.  group = nobody
  9.  protocol = tcp
  10.  port = 8182
  11.  redirect = 10.10.10.18 80
  12.  per_source = UNLIMITED
  13.  instances = UNLIMITED
  14.  cps = 10000 1
  15. }

Это всё записываем в файл с именем 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) такие:

  1.   cps   = 50 10
  2.   instances = 50
  3.   per_source  = 10

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

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

Posted in *nix, Howto.

Tagged with , .


Правильная перезагрузка linux-сервера

Хаос царит в системе;
Подумай, раскайся и перезагрузись -
Порядок должен вернуться

Пособие для начинающих сотрудников суппорта датацентров. При необходимости перезагрузить сервер делать это следует в таком порядке:

  1. Подключить клавиатуру и, желательно, монитор тоже (чтобы видеть обратную связь на свои действия) или получить доступ к консоли через IPKVM. Если на мониторе видно какие-то странные/нестандартные сообщения об ошибках, желательно их записать или сфотографировать (может пригодится при выяснении причин зависания).
  2. Нажать комбинацию клавиш Ctrl-Alt-Delete.
  3. Если на предыдущее действие реакции со стороны сервера нет, последовательно нажать комбинации клавиш:
    • Alt-PrintScreen-S (запись данных из дисковых буферов на физический носитель)
    • Alt-PrintScreen-U (отмонтирование файловых систем)
    • Alt-PrintScreen-B (перезагрузка)
  4. Если на предыдущее действие реакции со стороны сервера нет, поискать на нём кнопку «Reset» и при её наличии нажать.
  5. Если на предыдущее действие реакции со стороны сервера нет, выключить питание сервера, подождать 10-15 секунд, затем снова включить.

Действия из пункта 3 имеет смысл пробовать только если в файле /etc/sysctl.conf имеется строчка

  1. kernel.sysrq = 1

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

Если известно, что одна или более файловых систем не находятся в состоянии clean (проверить можно командой dumpe2fs -h) и хочется избежать их автоматической проверки при следующей загрузке (что может занять даже несколько часов), следует сделать так:

  1. touch /fastboot

Очень полезно для минимизации downtime сервера. После команды reboot или аналогичной на консоли появится сообщение "On the next boot fsck will be skipped". Проверялось на дистрибутиве CentOS. Файл /fastboot автоматически удалится при следующей загрузке ОС.

Posted in *nix, Howto.

Tagged with , .