phdru.name / Russian / blog / 2012 / 09 / 20
<-- Отпуск в Тель-Авиве | Debian 7.0 --> |
Есть в Линуксе такая проблема -- работа с большими файлами забивает содержимым этих файлов все кеши и буфера, вытесняя оттуда более полезное содержимое. Скачал образ DVD -- в следующий раз любимый редактор будет подгружать свои плагины с диска, а не из памяти. Посмотрел этот DVD -- и опять всё тормозит по новой.
Я долго искал в Интернете какие-нибудь советы, как это вылечить, но всё найденное -- 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 на сервере.
Эта страница https://phdru.name/Russian/blog/2012/09/20/cgmem.html была сгенерирована 16.06.2024 в 13:04:02 из шаблона CheetahTemplate cgmem.tmpl; Некоторые права зарезервированы. Вы можете узнать о технических аспектах этого сайта.