вторник, 15 декабря 2015 г.

Zram и Zswap или как увеличить эффективность оперативной памяти

Данная статья будет актуальна для владельцев нетбуков, компьютеров с малым количеством оперативки, людей, которые запускают много ресурсоёмких приложений, которые в свою очередь потребляют много памяти и так далее. В ядре Linux не так давно появились две замечательные технологии - zram и zswap. Опишу что это и для чего:


ZRAM - модуль ядра Linux, ранее известный как compcache. До версии ядра 3.14 находился в эксперементальной ветке, с 3.14 перемещён в основную. Суть его в том, что в оперативной памяти создаётся сжатый раздел подкачки (swap). Создавая swap в ОЗУ, мы тем самым хоть и уменьшаем объем доступной оперативной памяти, но тем не менее информация в оперативной памяти всегда хранится в несжатом виде, а при использовании ZRAM происходит следующее: как только системе начинает не хватать оперативной памяти, она начинает активно занимать swap, а так как swap у нас в оперативной-же памяти, то по факту система начинает просто сжимать информацию из оперативки и помещать ее в оперативку же. Скорость работы ОЗУ всегда существенно выше чем дисковой подсистемы, а алгоритмы сжатия lzo и lz4 настолько быстры, что в итоге мы получаем существенное "увеличение" оперативной памяти за счет небольших процессорных издержек на архивацию. Таким образом, ZRAM позволяет разместить в оперативной памяти в несколько раз больше информации за счёт сжатия. Эта технология активно используется в Android, ТВ-приставках, ChromeOS, SteamOS и много где ещё. При использовании ZRAM, swap-раздел на диске необязателен. Это особенно полезно для SSD-накопителей, так как частые записи для них вредны.

ZSWAP - модуль ядра Linux, доступный с версии 3.11. Отличается от ZRAM тем, что использует существующий swap-раздел на диске, а в ОЗУ создаётся пул со сжатыми данными (кэшем). После того как пул до отказа забьётся сжатыми данными, он сбросит их в раздел подкачки и снова начнёт принимать и сжимать данные. Размер пула можно указать вручную, по умолчанию он динамический (то есть будет использовать всю доступную оперативку). Реализация такого подхода позволяет, при возникновении необходимости сброса памяти в раздел подкачки, сократить ввод-вывод и повысить скорость работы системы в целом, за счет того, что по возможности избегается использование медленного носителя. Ценой сокращения ввода/вывода является увеличение нагрузки на процессор, который тратит дополнительные ресурсы на сжатие и распаковку данных. По утверждению разработчиков, в их конфигурации при компиляции ядра в ситуации когда происходит своппинг, выигрыш по объему ввода/вывода составил 76%, а время выполнения операции сократилось на 53%. При использовании ZSWAP, используется раздел swap на диске, в ОЗУ хранится только сжатый кэш. Можно считать ZSWAP продвинутым вариантом ZRAM.

Zram или Zswap?


Чтобы узнать что из этого лучше подойдёт вам, возьмём два примера: ноутбук с 4 гигами оперативки и медленным жёстким диском (представьте себе работу подкачки на таком) или с SSD-накопителем; компьютер с 8 гигами оперативки, на котором планируется запускать много виртуальных машин и других ресурсоёмких приложений. В первом случае, более подходящим будет ZRAM, так как ему не нужен swap-раздел на диске (это особенно вредно для SSD) и он позволит размещать все данные непосредственно в памяти. Однако раздел swap нужно обязательно создать если вы будете использовать на ноутбуке режим сна. На компьютере предпочтительнее будет ZSWAP, так как оперативка не будет занята виртуальными swap-файлами (а виртуалкам нужно много оперативки), а в оперативке будет хранится только сжатый кэш, что при нехватке памяти предотвратит своппинг, а в критической ситуации - быстренько скинет его на swap-раздел на диске.

Установка.


Примеры установки я покажу на дистрибутиве Ubuntu 14.04 и Debian 8. В остальных дистрибутивах различия будут не существенными (обратитесь к документации вашего дистрибутива). Начнём с ZRAM. Для Ubuntu всё просто:

sudo apt install zram-config

Всё. Этот скрипт определит количество оперативной памяти в вашей системе, а также количество ядер процессора и создаст swap-файла в памяти (блочные устройства /dev/zram) по количеству ядер. Это нужно потому что сжатие данных однопоточное (один поток==одно ядро). По умолчанию размер такого swap-файла равен 1/2 от общего количества оперативки. После перезагрузки, выполните в терминале команду swapon -s и вы увидите помимо реального swap-раздела, несколько разделов /dev/zram. Далее. Если вы изменяли значение vm.swappiness (для уменьшения порога включения подкачки), например выставили значение vm.swappiness = 10, то измените его на 40, дабы уже при исчерпании 60% оперативки, включался ZRAM. Если вы ничего не трогали, то можете либо оставить значение по умолчанию (60, то есть при исчерпании 40% оперативки), либо:

sudo nano /etc/sysctl.conf

Дописываем в конец строку:

vm.swappiness = 40

сохраняем и выполняем:

sudo sysctl -p

либо перезагружаемся. Вот и всё. Для Debian всё немного сложнее. Но совсем чуть чуть :) Открываем терминал, вводим:

sudo nano /etc/init.d/zram

Вставляем следующий скрипт:

#!/bin/sh
### BEGIN INIT INFO
# Provides:          zram
# Required-Start:    $local_fs
# Required-Stop:     $local_fs
# Default-Start:     S
# Default-Stop:      0 1 6
# Short-Description: Use compressed RAM as in-memory swap
# Description:       Use compressed RAM as in-memory swap
### END INIT INFO

# Author: Antonio Galea <antonio.galea@gmail.com>
# Thanks to Przemysław Tomczyk for suggesting swapoff parallelization

FRACTION=50

MEMORY=`perl -ne'/^MemTotal:\s+(\d+)/ && print $1*1024;' < /proc/meminfo`
CPUS=`grep -c processor /proc/cpuinfo`
SIZE=$(( MEMORY * FRACTION / 100 / CPUS ))

case "$1" in
  "start")
    param=`modinfo zram|grep num_devices|cut -f2 -d:|tr -d ' '`
    modprobe zram $param=$CPUS
    for n in `seq $CPUS`; do
      i=$((n - 1))
      echo $SIZE > /sys/block/zram$i/disksize
      mkswap /dev/zram$i
      swapon /dev/zram$i -p 10
    done
    ;;
  "stop")
    for n in `seq $CPUS`; do
      i=$((n - 1))
      swapoff /dev/zram$i && echo "disabled disk $n of $CPUS" &
    done
    wait
    sleep .5
    modprobe -r zram
    ;;
  *)
    echo "Usage: `basename $0` (start | stop)"
    exit 1
    ;;
esac


Сохраняем. Далее даём права на исполнение:

sudo chmod +x /etc/init.d/zram

и активируем:

sudo insserv zram

Перезагружаемся и всё.



Теперь о ZSWAP. Здесь всё значительно проще. Нужно лишь передать ядру во время загрузки, параметр zswap.enabled=1. Для этого открываем файл /etc/default/grub

sudo nano /etc/default/grub

И в строку GRUB_CMDLINE_LINUX_DEFAULT дописываем этот параметр. Чтобы было вот так:

GRUB_CMDLINE_LINUX_DEFAULT="zswap.enabled=1 quiet"

Далее:

sudo update-grub

и перезагрузка. После перезагрузки, можете убедиться в работе ZSWAP, введя команду  dmesg | grep zswap Если ответом будет

[    1.273249] zswap: loading zswap
[    1.273252] zswap: using lzo compressor


значит всё сработало на отлично. Способ включения ZSWAP одинаков для большинства дистрибутивов. Если нужно ограничить объём пула для ZSWAP, то там же в параметрах указываем:

zswap.max_pool_percent=x

где x - процент отведённой памяти под ZSWAP.

Вот так мы быстро и без лишних телодвижений, увеличили эффективность оперативной памяти, лишь незначительно увеличив нагрузку на процессор.


Ссылки:

Статья по ZRAM для пользователей ArchLinux
Обсуждение на Habrahabr
ZSWAP на Debian Forum

 

16 комментариев:

  1. Хорошая статейка, жаль что раньше не попадалась.

    ОтветитьУдалить
  2. Как вернуть все назад, до установки ZRAM? Отвалилась 1 память на 2 гигабайта. Убунту 14 х64 ее вообще не видит, а в Винде х32 видно 3 из 4 гигов, но один гиг зарезервирован, т.е. использовать можно все кроме опять же этой 2Гб планки памяти. Удаление zram-config нечего не дало.

    ОтветитьУдалить
    Ответы
    1. ZRAM тут не при чём. Он просто сжимает данные в памяти, но память под себя не трогает. И тем более не прячет от системы. Скорее всего проблема в самой планке. Сканируйте мемтестом всю память. 32х битная винда не увидит 4 гига, будет видеть только 3 с копейками.

      Удалить
    2. Удалить, то что Вы по этой статье сваяли:
      sudo /etc/init.d/zram stop
      sudo rm -f /etc/init.d/zram
      Проверить можно так:
      swapon -s

      Удалить
  3. Анонимный30 мая 2016 г., 19:44

    А если оба поставить?

    И если я поставил swapspace вместо раздела или жёсткого файла swap, тогда что?

    ОтветитьУдалить
    Ответы
    1. Zram не нужен Swap, в отличии от Zswap. Со swapcpace скорее всего Zswap работать не будет, так как ему нужен фиксированный раздел подкачки. А вот Zram вполне сможет, однако я не тестировал такой вариант.

      Удалить
  4. Анонимный31 мая 2016 г., 8:50

    Ещё можно файл прикрутить в качестве свопа вместо раздела, он то хоть будет работать с Zswap?

    Я поставил swapspace и Zswap, делаю swapon -s, а там молчок. И почему только разработчик не научил их работать вместе.

    ОтветитьУдалить
    Ответы
    1. swapspace и обычный swap это разные вещи. Первый - это демон, который динамически создаёт файлы подкачки. Второе - это постоянная область для этого. Команда swapon монтирует раздел подкачки как SWAP. Zswap работает именно с реальным своп-разделом.

      Удалить
    2. Анонимный31 мая 2016 г., 21:39

      Да нет, вопрос в том, будет ли он работать с файлом подкачки, а не с разделом подкачки?

      Удалить
  5. А если я уже в этот параметр вставил строку GRUB_CMDLINE_LINUX_DEFAULT="init=/sbin/e4rat-collect"
    Могут ли быть в этом файле две строки GRUB_CMDLINE_LINUX_DEFAULT="zswap.enabled=1 quiet"?

    ОтветитьУдалить
    Ответы
    1. В эту же строку через пробел пишите остальное

      Удалить
  6. Этот комментарий был удален автором.

    ОтветитьУдалить
  7. Написал скрипт для автоматической установки и удаления zRAM: https://drive.google.com/file/d/0B5yYOZjNEYKmY0k4UnJyTl9DRkk/view?pref=2&pli=1
    Тестировал на Linux Mint LMDE 2 Betsy (3.16.0-4-amd64 #1 SMP Debian 3.16.7-ckt25-2+deb8u3 (2016-07-02) x86_64 GNU/Linux)

    ОтветитьУдалить
  8. Aleksey Samoilov и Серёга Кулибин, спасибо Вам!

    ОтветитьУдалить