memory cgroup
Oct. 19th, 2012 02:13 amЕсть в Линуксе такая проблема — работа с большими файлами забивает содержимым этих файлов все кеши и буфера, вытесняя оттуда более полезное содержимое. Скачал образ DVD — в следующий раз любимый редактор будет подгружать свои плагины с диска, а не из памяти. Посмотрел этот DVD — и опять всё тормозит по новой.
Я долго искал в Интернете какие-нибудь советы, как это вылечить, но всё найденное — ulimit, ionice и т.п. — помогало, как мёртвому припарки. Болезнь сидит глубоко в ядре, и лечить её надо там внутри.
И вот во время одного их таких регулярных вылазок за советами я нашёл… не совет даже, а намёк. Но я стал с этим намёком экспериментировать, и развил его до работающего решения. Проблема оказалась решаема, хотя и не вполне тривиально.
Ключевое слово того намёка было — cgroup. А конкретней — memory cgroup.
Я захотел с этим поэкспериментировать, и тут же упёрся в проблему — в дебиановском ядре memory controller выключен. Он тормозит систему, даже если им не пользоваться.
Пришлось перекомпилировать ядро. Мне не впервой. Да что там "не впервой" — я это регулярно вынужден делать.
Группы включаются в /etc/fstab:
После перезагрузки я написал скрипт с несколькими вызовами sudo, который создавал memory cgroup на каждый вызов и засовывал текущий shell в эту группу (для этого надо ID процесса записать в файл tasks группы). Первый же эксперимент показал, что это действительно работает — shell, запертый в ограниченной группе, скачивает файл, а кеши и буфера не теряются. И никакого торможения системы я не заметил.
Создавать memory cgroup на каждый чих, конечно, неправильно — нет смысла создавать десяток групп, в каждой из которых ограничение по памяти полгигабайта — у меня памяти всего 2 гига. Я создал 3 группы — с ограничением 10 мегабайт, 100 и полгига. 10 мегабайт для скачивания и прочих мелких задачек, 100 для видеоплеера (mplayer) и задач покрупнее, 500 метров — для браузера.
Группы создаются автоматом в /etc/rc.local, и там же файл tasks открывается на запись группе root — sudo мне больше не нужен:
Для засовывания программ в группы — вот такой скрипт:
Удалить программу из группы нельзя — каждый процесс всегда принадлежит какой-нибудь группе. Можно переносить процессы из группы в группу путём записи ID процесса в соответствующий файл tasks группы. Можно перенести процесс в группу без ограничений (дефолтную группу я сделал без ограничений):
Теперь дождаться Debian 7.0 с ядром 3+, и урезать аппетит transmission-bt на сервере.
http://phdru.name/Russian/blog/2012/09/20/cgmem.html
Я долго искал в Интернете какие-нибудь советы, как это вылечить, но всё найденное — ulimit, ionice и т.п. — помогало, как мёртвому припарки. Болезнь сидит глубоко в ядре, и лечить её надо там внутри.
И вот во время одного их таких регулярных вылазок за советами я нашёл… не совет даже, а намёк. Но я стал с этим намёком экспериментировать, и развил его до работающего решения. Проблема оказалась решаема, хотя и не вполне тривиально.
Ключевое слово того намёка было — cgroup. А конкретней — memory cgroup.
Я захотел с этим поэкспериментировать, и тут же упёрся в проблему — в дебиановском ядре memory controller выключен. Он тормозит систему, даже если им не пользоваться.
Пришлось перекомпилировать ядро. Мне не впервой. Да что там "не впервой" — я это регулярно вынужден делать.
Группы включаются в /etc/fstab:
none /sys/fs/cgroup cgroup memory 0 0
После перезагрузки я написал скрипт с несколькими вызовами sudo, который создавал memory cgroup на каждый вызов и засовывал текущий shell в эту группу (для этого надо ID процесса записать в файл tasks группы). Первый же эксперимент показал, что это действительно работает — shell, запертый в ограниченной группе, скачивает файл, а кеши и буфера не теряются. И никакого торможения системы я не заметил.
Создавать memory cgroup на каждый чих, конечно, неправильно — нет смысла создавать десяток групп, в каждой из которых ограничение по памяти полгигабайта — у меня памяти всего 2 гига. Я создал 3 группы — с ограничением 10 мегабайт, 100 и полгига. 10 мегабайт для скачивания и прочих мелких задачек, 100 для видеоплеера (mplayer) и задач покрупнее, 500 метров — для браузера.
Группы создаются автоматом в /etc/rc.local, и там же файл tasks открывается на запись группе root — sudo мне больше не нужен:
CGROUPS=/sys/fs/cgroup
for size in 10M 100M 500M; do
mkdir $CGROUPS/$size &&
echo $size > $CGROUPS/$size/memory.limit_in_bytes
done
find $CGROUPS -name tasks -exec chmod g+w '{}' \+Для засовывания программ в группы — вот такой скрипт:
#! /bin/sh
size="$1" # in megabytes
shift
CGROUPS=/sys/fs/cgroup
echo $$ > "$CGROUPS"/${size}M/tasks || exit 1
ulimit -d ${size}000
exec nice -20 ionice -c3 "${@:-$SHELL}"Удалить программу из группы нельзя — каждый процесс всегда принадлежит какой-нибудь группе. Можно переносить процессы из группы в группу путём записи ID процесса в соответствующий файл tasks группы. Можно перенести процесс в группу без ограничений (дефолтную группу я сделал без ограничений):
echo $$ > "$CGROUPS"/tasks
Теперь дождаться Debian 7.0 с ядром 3+, и урезать аппетит transmission-bt на сервере.
http://phdru.name/Russian/blog/2012/09/20/cgmem.html