Home » International » Russian » Странный рост показаний счётчика dcachesize
Странный рост показаний счётчика dcachesize [message #48265] |
Wed, 10 October 2012 11:24 |
kopytov
Messages: 17 Registered: July 2007 Location: Cyprus, Limassol
|
Junior Member |
|
|
Я столкнулся с очень странной проблемой роста параметра dcachesize в одном из контейнеров. Контейнер создан на базе официального образа centos-6-x86_64, поверх которого установлена контрольная панель для управления хост-нодами. В состав контрольной панели входят скрипты, которые запускаются по крону каждые 5 минут, собирают различную статистику и выполняют служебные функции. Скрипты успешно отрабатывают, завершаются и исчезают из таблицы процессов, но после каждого запуска увеличивается показания счётчика dcachesize, который растёт линейно в течение некоторого времени и затем съедает всю память, выделенную контейнеру. Как это происходит, можно увидеть на графике.
При этом показания счётчиков UBC выглядят так:
----------------------------------------------------------------
CT 2003 | HELD Bar% Lim%| MAXH Bar% Lim%| BAR | LIM | FAIL
-------------+---------------+---------------+-----+-----+------
kmemsize|1.78G - - |1.78G - - | - | - | -
lockedpages| - - - | 32K - - | - | - | -
privvmpages| 236M - - | 416M - - | - | - | -
shmpages| 4K - - |2.57M - - | - | - | -
numproc| 38 - - | 123 - - | - | - | -
physpages|1.94G - 97%| 2G - 100%| - | 2G| -
vmguarpages| - - - | - - - | - | - | -
oomguarpages|73.1M - - |79.3M - - | - | - | -
numtcpsock| 8 - - | 17 - - | - | - | -
numflock| 8 - - | 16 - - | - | - | -
numpty| - - - | 3 - - | - | - | -
numsiginfo| - - - | 21 - - | - | - | -
tcpsndbuf| 136K - - | 708K - - | - | - | -
tcprcvbuf| 128K - - | 272K - - | - | - | -
othersockbuf| 133K - - | 372K - - | - | - | -
dgramrcvbuf| - - - |8.52K - - | - | - | -
numothersock| 117 - - | 158 - - | - | - | -
dcachesize|1.77G - - |1.77G - - | - | - | -
numfile| 836 - - |2.25K - - | - | - | -
numiptent| 39 - - | 39 - - | - | - | -
swappages|27.9M - 0.7%|29.2M - 0.7%| - | 4G| -
----------------------------------------------------------------
Хотя в процессах контейнера ничего необычного нет, всё довольно типично:
PID %CPU %MEM VSZ RSS STAT STARTED TIME COMMAND
18571 0.0 0.0 0 0 S 13:28:09 00:00:00 \_ kthreadd/2003
18572 0.0 0.0 0 0 S 13:28:09 00:00:00 \_ khelper/2003
18570 0.0 0.0 19232 1304 Ss 13:28:09 00:00:00 init
18722 0.0 0.0 10660 304 S<s 13:28:10 00:00:00 \_ udevd
19067 0.0 0.0 6160 500 Ss 13:28:11 00:00:00 \_ portreserve
19073 0.0 0.0 183544 1924 Sl 13:28:12 00:00:00 \_ rsyslogd
19084 0.0 0.0 197776 3488 S 13:28:12 00:00:19 \_ snmpd
19099 0.0 0.0 64076 600 Ss 13:28:12 00:00:00 \_ sshd
19106 0.0 0.0 22092 724 Ss 13:28:12 00:00:00 \_ xinetd
19141 0.0 0.0 108168 1244 S 13:28:12 00:00:00 \_ mysqld_safe
19218 0.0 0.2 969432 11636 Sl 13:28:12 00:01:18 | \_ mysqld
19240 0.0 0.0 64272 900 Ss 13:28:13 00:00:00 \_ saslauthd
19241 0.0 0.0 64272 644 S 13:28:13 00:00:00 | \_ saslauthd
19317 0.0 0.0 78680 2512 Ss 13:28:13 00:00:00 \_ master
19325 0.0 0.0 78932 3108 S 13:28:13 00:00:00 | \_ qmgr
294687 0.0 0.0 78760 3172 S 11:07:29 00:00:00 | \_ pickup
19327 0.0 0.0 52352 3032 S 13:28:13 00:00:06 \_ lighttpd
19329 0.0 0.2 235480 8172 Ss 13:28:13 00:00:00 | \_ php-cgi
19338 0.0 0.3 242604 12024 S 13:28:13 00:00:03 | | \_ php-cgi
19344 0.0 0.1 235480 6520 Ss 13:28:14 00:00:00 | \_ php-cgi
19345 0.0 0.2 243116 11080 S 13:28:14 00:00:06 | | \_ php-cgi
19346 0.0 0.2 235480 8172 Ss 13:28:14 00:00:00 | \_ php-cgi
19347 0.0 0.2 242592 11468 S 13:28:14 00:00:02 | | \_ php-cgi
19348 0.0 0.2 235480 8172 Ss 13:28:14 00:00:00 | \_ php-cgi
19349 0.0 0.4 248608 17828 S 13:28:14 00:00:08 | \_ php-cgi
58919 0.0 0.0 117212 1252 Ss 16:26:41 00:00:02 \_ crond
Конфигурационный файл контейнера также вполне стандартен:
PHYSPAGES="0:524288"
SWAPPAGES="0:1048576"
DISKSPACE="10485760:11534336"
DISKINODES="1000000:1100000"
QUOTATIME="0"
CPUUNITS="1000"
OSTEMPLATE="centos-6-x86_64"
ORIGIN_SAMPLE="vswap-2g"
ONBOOT="yes"
Версия ядра: 2.6.32-042stab061.2 (CentOS 6.3)
vzctl 4.0.
После перезагрузки контейнера dcachesize приходит в норму, затем опять линейно увеличивается по мере запуска скриптов, пока не съедает всю память.
Из подозрительного, в логах были сообщения:
Oct 9 01:00:02 tools2 kernel: [4025069.891406] VZDQ: Tried to clean orphans on qmblk with 1 state
Oct 9 01:00:02 tools2 kernel: [4025069.891411] BUG: Quota files for 2003 are broken: no quota engine running
Но они исчезли после пересоздания квоты и (или) перезагрузки хост-ноды.
И один раз во время перезагрузки контейнера, получил такие сообщения в лог:
Oct 9 10:35:34 tools2 kernel: [4059601.590679] CT: 2003: stopped
Oct 9 10:35:34 tools2 kernel: [4059601.598205] UB: 2003 has 31 swap entries to unuse.
Oct 9 10:35:34 tools2 kernel: [4059601.739865] Ub 2003 helds 4360 in tcpsndbuf on put
Oct 9 10:35:34 tools2 kernel: [4059601.739873] UB: leaked beancounter 2003 (ffff88012df70040)
Oct 9 10:35:54 tools2 kernel: [4059621.003883] CT: 2003: started
Я пробовал перезагружать хост-ноду во время обновления ядра, это никак не отразилось на поведении счётчика.
С подобной проблемой столкнулся впервые, хотя пользуюсь OpenVZ уже много лет. В связи с этим вопрос, чем может быть вызвано такие показания счётчиков - виноваты скрипты или следует подозревать утечки в ядре? Если скрипты, подскажите, чем именно такое поведение может быть вызвано?
|
|
|
|
|
|
Re: Странный рост показаний счётчика dcachesize [message #48517 is a reply to message #48488] |
Fri, 19 October 2012 13:38 |
|
Я наконец разобрался в этом вопросе и смогу популярно объяснить, что это и зачем и почему.
dcachesize контролирует размер dentry и inode кешей.
Про dentry кеш. Когда кто-то открывает какой-нибудь файл, скажем, /var/log/httpd/access_log, в dentry кеше появляются объекты для /, var, log, httpd и для access_log, то есть пять штук (впрочем, / там уже скорее всего есть). Соответственно, когда в следующий раз кто-то будет смотреть в /var/log/httpd/access/log (или просто в /var) -- ядро будет использовать этот кеш. Второе открытие (или stat, например) того же самого файла не будет приводить к увеличению кеша -- там все эти объекты уже есть.
К примеру, можно «вырастить» размер dcache командой ls -lR /, которая по-stat()-ает все имеющиеся файлы. Если запустить ls -lR / сразу ещё раз, dcache уже не подрастёт. Для обычного контейнера значение будет несколько десятков мегабайт.
Отсюда у юношей, обдумывающих житьё, возникает справедливый и каверзный вопрос -- а как тогда удаётся подрастить dcache до ужасающих значений в 12 гигабайта, если в системе нет такого количества файлов? Ага! Бага!! БАГА!!!
Нет, не бага. Дело в том, что от файла, которого НЕТ, dentry тоже кешируется (чтобы в следующий раз быстрее ответить на вопрос, есть ли такой файл). Теперь, если создавать и удалять много временных файлов (впрочем, достаточно просто генерировать рандомное имя файла и делать на него stat() или access() или open()), то можно вырастить dcache до упора.
«Упором» в данном случае может являться
-- barrier/limit бинкаунтера dcachesize в конкретном контейнере
-- barrier/limit бинкаунтера kmemsize (в него включается dcachesize)
-- limit бинкаунтера physpages (на 042stab ядре в него включается kmemsize)
-- объём свободной памяти в системе
Обычно на vswap-enabled конфигах упором является physpages или объём свободной памяти. В вашем случае, судя по всему, памяти в системе много, и кто-то делает что-то вроде создания/удаления временных файлов, вот кеш и вырастает до максимально возможного размера. Это абсолютно нормальное, правильное и разумное поведение системы.
Дальше, если памяти хватать не будет, кеш уменьшится в объёме, ядро само подропает наиболее редко используемые объекты кеша.
Это такая теория. Практика чуть позже.
Kir Kolyshkin
|
|
|
|
Re: Странный рост показаний счётчика dcachesize [message #48553 is a reply to message #48265] |
Mon, 22 October 2012 11:16 |
kopytov
Messages: 17 Registered: July 2007 Location: Cyprus, Limassol
|
Junior Member |
|
|
Спасибо за подробное разъяснение. Всё происходит так как вы говорите. Я попробовал проверить в тестовом контейнере и вот такой скрипт увеличил dcachesize до гигабайтов за считанные минуты:
#!/usr/bin/perl
use strict;
use warnings;
use File::Temp ();
while (1) {
my $tmp_fh = File::Temp->new();
my $tmp_fname = $tmp_fh->filename();
my @tmp_stat = stat $tmp_fname;
unlink $tmp_fname;
}
При этом, когда достигается предел, память больше не расходуется и ничего страшного не происходит - даже ООМ-киллер никого не трогает.
Единственное что мне осталось непонятно, откуда такое расхождение в показаниях занятости памяти в контейнере и на хост-ноде. Если посмотреть на графики, которые я опубликовал вначале, то на них видно, что за эти 12 часов в контейнере потребление памяти выросло примерно на 1,8-1,9 Гбайт, но в самой системе - на 450-500 Мбайт. Разница почти в четыре раза, что выглядит довольно странным.
koct9i wrote on Mon, 22 October 2012 08:54dcache считается в ресурсы dcachesize и kmemsize, а kmemsize поделённый на 4096 считается в physpages.
Так что поставьте лимит на dcachesize или kmemsize, скажем в 1Gb.
В том ядре был баг что лимит на physpages не очень хорошо лимитирует dcache и ядро может постреливать OOM-килами время от времени.
Спасибо за совет, так и сделаю.
|
|
|
Re: Странный рост показаний счётчика dcachesize [message #48561 is a reply to message #48553] |
Mon, 22 October 2012 19:14 |
|
koct9i
Messages: 51 Registered: February 2008
|
Member |
|
|
kopytov wrote on Mon, 22 October 2012 15:16Единственное что мне осталось непонятно, откуда такое расхождение в показаниях занятости памяти в контейнере и на хост-ноде. Если посмотреть на графики, которые я опубликовал вначале, то на них видно, что за эти 12 часов в контейнере потребление памяти выросло примерно на 1,8-1,9 Гбайт, но в самой системе - на 450-500 Мбайт. Разница почти в четыре раза, что выглядит довольно странным.
Просто что-то ещё параллельно освобождалось, на хосте или в другом контейнере. Ядро держит очень небольшой резерв свободной памяти, остальное используется для всевозможных кэшей которые быстро освобождаются по первому требованию.
|
|
|
Goto Forum:
Current Time: Sun Dec 22 11:10:38 GMT 2024
Total time taken to generate the page: 0.04751 seconds
|