пятница, 26 сентября 2014 г.

Solaris 10 u11: Утечка памяти ARC

Затяжная проблема с памятью (тут) возымела совершенно неожиданное продолжение.

Вскрытие показало, что больной умер в результате вскрытия ;)  что в Solaris 10 u11 практически не работает ARC reclaim и система напрочь игнорирует hard limit на размер ARC. Что при достаточно длительном аптайме приводит к внезапному и сильному свопингу и резкому падению производительности сервера, при том, что top показывал зачастую достаточно много свободной памяти.

Детальное изучение вопроса привело к внимательному изучению показаний arc_summary.pl. В результате которого и было обнаружено превышение текущим размером ARC жестко заданного hard limit (Честно говоря, впервые видел, как ОС игнорирует hard limit):


Немного пояснений. Сейчас этот показатель в норме. Системные лимиты были заданы (выше) в значения minimum=512 Mb, maximum=1024 Mb. При появлении описываемого эффекта, выделенное текущее значение превышало 1,5 Гб и росло и дальше, вплоть до глубокого свопинга. Система в итоге не падала, но дьявольски замедлялась, IO подскакивал в разы и латентность увеличивалась в десятки раз.

Любые попытки решить проблему мирным путем (отключение prefetch, игры с параметрами ФС primarycache и secondarycache, попытки использовать rcap, урезание потребления памяти приложениями) - ни к чему не привели. Момент свопинга иногда удавалось оттянуть (до двух недель), но при дальнейшем росте аптайма эффект проявлялся неизбежно.

Как выяснилось, данная проблема вызвана целой серией вновь внесенных багов в u11 и лечение возможно лишь при помощи kernel-патча 150401-16 (для x86/x64). Мало того, пререквизитом он требует целую серию патчей (в т.ч. ядерных), включенных в июльский recommended update.

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

Что делать тем, у кого подписки нет и не будет?

Откатывайтесь на u10. Да, я знаю, что еще начиная с u9 индусня из Оракла к чертовой матери изломала Live Upgrade и он больше не работает как часики.

Однако других вариантов у вас просто нет.

Ну либо по-окошечному рестартуйте сервер каждые несколько дней.

Плагин Munin для мониторинга размера ARC

В процессе разбирательств с ARC выяснилось, что контрибьюторский плагин zfs_memory показывает погоду (вытаскивая неведомо какие показатели zfs посредством kstat) и что надо бы написать человеческий плагин для мониторинга показателей ARC  в динамике.

Что и было проделано.

Код плагина zfs_arc_memory ниже:

#!/bin/bash
#
# munin plugin for monitoring zfs ARC memory on solaris
#
# Y.Voinov (c) 2014
#

#%# family=auto
#%# capabilities=autoconf

# ZFS ARC parameters
CURRENT="zfs:0:arcstats:size"
TARGET="zfs:0:arcstats:c"
MIN="zfs:0:arcstats:c_min"
MAX="zfs:0:arcstats:c_max"

# Utilities
AWK=`which awk`
KSTAT=`which kstat`

if [ "$1" = "config" ]; then
echo "graph_title ZFS ARC Memory Consumption"
echo 'graph_category disk'
echo 'graph_vlabel Memory in MB'
echo 'memory.label current'
echo 'target.label target'
echo 'min.label min'
echo 'max.label max'
exit 0
fi;

$KSTAT -p $CURRENT | $AWK '{print "memory.value", $2}'
$KSTAT -p $TARGET | $AWK '{print "target.value", $2}'
$KSTAT -p $MIN | $AWK '{print "min.value", $2}'
$KSTAT -p $MAX | $AWK '{print "max.value", $2}'

Код, как видите, простенький. Можно скачать плагин по ссылке. Как обычно, не забывайте дать права на выполнение, создать линк в директории plugins и рестартовать сервис svc:/application/cswmuninnode:default.

Данный плагин позволяет гораздо более информативно контролировать поведение ARC и выловить описанную выше проблему с неограниченным ростом ARC.

Он контролирует четыре основных показателя статистики ARC. Минимальные и максимальные значения в моем случае показаны прямыми линиями, поскольку заданы лимитами в /etc/system.