linux zswap - дайте машине шанс

06/04/2017

Zswap - технология, позволяющяя оптимизировать работу ядра со swap - хранилищем избыточных страниц памяти. Когда оперативной памяти начинает нехватать, ядро может принять решение о сливе (перемещении) некоторых страниц памяти из оперативного хранилища на диск. Программы таким образом смогут продолжить работу, но скорость их выполнения может существенно снизиться - в отличие от оперативной памяти, хранилища энергонезависимые не могут похвастаться высокой скоростью работы. Начинается своего рода трейдинг - происходит выбор  какой кусок памяти какой прораммы перемещать чтобы не дать ей упасть и потерять данные. Во вногих дистрибутивах по-умолчанию эта граница отмечена в 60. Это число не связано с процентами от свободной памяти - оно обозначает насколько агресивно ядро может свопить страницы памяти. 0 - свопим только когда памяти почти нет, 100 - свопим агрессивно. Этот параметр настраивается довольно легко, и об этом есть много статей в интернете. Мы же хотим рассказать о нововведении в этой области - zswap. Механизм работы swap остается тот же, но на этой самой границе - 60, когда страница уже готова отправиться на диск, ее перехватывает zswap, анализирует на предмет того, можно ли ее хорошенько сжать, и если да, сжимает ее, затем аллоцирует все в той же памяти (60 ведь подразумевает, что память еще есть - процентов так 40) под нее, но уже сжатую, место и записывает туда, вместо диска. Таким образом основная память высвобождается, запись на диск не инициируется, головки не скрипят, перемещаясь по поверхности диска, а если это SSD - счетчик количества перезаписей ячейки не уменьшает срок ее жизни. Более того, если даже пожатую страницу программа захочет снова прочитать, разжать её и отдать программе будет все равно быстрее, чем вытаскивать ее в энергонезависимого хранилища. Да, не все страницы могут быть сжаты, и да, та память, в которую можно помещать сжатые страницы не безгранична. В этом случае "неудачники" будут выселены на диск. Смысл zswap - максимально отсрочить этот момент, ведь велик шанс того, что благодаря zswap он никогда и не наступит.

Прежде чем настраивать zswap стоит сразу понять ряд вещей:

  • zswap - это не  zram. zram - это виртуальное блочное устройство, использующее оперативную память компьютера в качестве носителя, а zswap - это вообще не устройство, а технология, интегрировнная в ядро linux. В отличие от zram, вам не надо предварительно создавать виртуальное блочное устройство, делать из него swap с помощью команд "mkswap" затем "swapon" и т.д. - zswap не требует никаких дополнительных телодвижений, он сам выделяет память и сам объявляет себя в качестве swap-бэкенда
  • вы все еще не можете отказаться от классического swap раздела или файла, иначе zswap работать не будет. zswap создан перехватывать страницы памяти, которые по мнению ядра пора сливать в swap, а чтобы это произошло, у ядра должно быть для этого зарегистрированное место + как вы уже знаете, далеко не каждая страница может в итоге попасть в zswap - она должна быть способной быть пожатой
  • вам нужно ядро версии минимум 3.11, но в CentOS 7 работать будет (фича бэкпортирована)

И так, настраиваем zswap. Первое и самое важное действие - его нужно включить. В некоторых статьях вы можете обнаружить способ примерно такой

echo 1 > /sys/module/zswap/parameters/enabled

Не работает! Может, конечно, у кого-то и работает, но на CentOS 7 это гарантировано не прокатит. К тому же это изменение временное, т. е. после перезагрузки все будет по старому. Единственный надежный способ фишку включить - это воспользоваться опциями ядра, а именно нам нужно выставить ключ "zswap.enabled" в значение "1". Если вы используете GRUB в качестве загрузчика, самым простым спобом будет отредактировать его переменные окружения. Откройте файл /etc/default/grub и добавите в строку "GRUB_CMDLINE_LINUX=" указанный выше ключ. Таким образом должно получится что-то вроде этого:

cat /etc/default/grub
 
#...вывод опущен
GRUB_CMDLINE_LINUX="net.ifnames=0 zswap.enabled=1"
#...вывод опущен

Далее необходимо сгененировать новый конфиг GRUB, перезаписав старый. На CentOS команда будет выгляеть так

grub2-mkconfig -o /boot/grub2/grub.cfg

Для дистрибутивов, основанных на Debian, скорее всего сработает команда

grub-mkconfig -o /boot/grub/grub.cfg

Т. е. в конечном итоге в конфиг GRUB'а должны попасть вышеуказанные параметры, проверим на CentOS

grep zswap /boot/grub2/grub.cfg
linux16 /boot/vmlinuz-3.10.0-514.16.1.el7.x86_64 root=/dev/sda ro net.ifnames=0 zswap.enabled=1

На Debian

grep zswap /boot/grub/grub.cfg
linux    /boot/vmlinuz-4.9.0-2-amd64 root=/dev/sda ro quiet net.ifnames=0 zswap.enabled=1

Все на месте. Перезагружаемся. Как только система загрузиться, можно сделать дабл-чек, чтобы знать наверняка, что zswap включился - он должен был наследить в dmesg

dmesg | grep zswap
 
[88634.310906] zswap: using lzo compressor
[88634.354798] zswap: using zbud pool
[88634.354864] zswap: loading zswap

При чем, как вы видите, нам даже сообщили некоторую полезную информацию, например, что в качестве компрессора у нас выступает lzo. А как узнать теперь, что zswap реально работает - спросите вы. К сожалению, он не особо разговорчив, но кое-что выяснить все-таки можно, например, воспользовавшись специальной файловой системой debugfs

grep . -R /sys/kernel/debug/zswap/
 
/sys/kernel/debug/zswap/stored_pages:261778
/sys/kernel/debug/zswap/pool_total_size:536121344
/sys/kernel/debug/zswap/duplicate_entry:0
/sys/kernel/debug/zswap/written_back_pages:0
/sys/kernel/debug/zswap/reject_compress_poor:415
/sys/kernel/debug/zswap/reject_kmemcache_fail:0
/sys/kernel/debug/zswap/reject_alloc_fail:0
/sys/kernel/debug/zswap/reject_reclaim_fail:0
/sys/kernel/debug/zswap/pool_limit_hit:0

Здесь

  • stored_pages - показывает текущее количество страниц, помещенных в zswap
  • pool_total_size - размер аллоцированной zswap памяти в байтах
  • duplicate_entry - количество дублирующихся записей, как правило не должно превышать нуля

и т.д.

Happy swapping!

При написании статьи были использованы следующие материалы:

https://www.kernel.org/doc/Documentation/vm/zswap.txt

Темы:

Добавить комментарий