LINUX.ORG.RU

Как закалялся шакал: а где можно download more ram?

 , , ,


4

2

Вступление

Данная статья написана с целью концентрации знаний о сжатии данных оперативной памяти.

Я использую gentoo, поэтому имена пакетов будут приводиться в формате этого дистрибутива.

Подразумевается, что читающий имеет желание и возможность (одно из):

  • произвести конфигурацию и/или сборку ядра;
  • в случае отсутствия искомой функциональности в «ванильном» - найти и использовать ядро, в котором уже всё есть.

zram

zram это, если описать попроще, tmpfs со сжатием.

Необходимо включить zram в ядре: CONFIG_ZRAM=m (или =y, но настоятельно рекомендуется загружать как модуль), либо в menuconfig:

Device Drivers  --->
[*] Block devices  --->
<M>   Compressed RAM block device support

Также стоит обратить внимание на другие доступные опции конфигурации, например - метод компрессии ZRAM_BACKEND_XXX.

Важно заметить, что zram может использоваться как простое блочное устройство и как приоритетный своп, аналогично zswap (см. ниже). В случае последнего необходимо собирать модуль с опцией CONFIG_ZRAM_WRITEBACK, которая позволяет отгружать данные из zram-девайса на ФС.

Наличие zram можно проверить по наличию модуля zram (только если zram собран модулем) или существованию /dev/zramX (если модуль загружен или zram вшит в ядро).

Утилита zramctl входит в состав sys-apps/util-linux (которая, скорее всего, уже стоит в системе), с её помощью можно создать юзабельный zram диск. Описание утилиты можно прочитать на man 8 zramctl.

Одновременно может существовать несколько устройств zram, каждое со своей собственной конфигурацией (объём, путь, права, writeback итд). Для zram есть вспомогательные проекты, например sys-apps/zram-generator и sys-block/zram-init, которые упрощают конфигурацию функциональности, но использовать их не является строгой необходимостью.

Ряд полезных инструкций можно найти тут: арчвики, гентувики.

zswap

zswap представляет из себя прослойку между RAM и swap: вместо простой выгрузки неактивных страниц в своп, сначала они подвергаются компрессии и помещаются в отдельное виртуальное хранилище в оперативной памяти; затем данные страницы выгружаются в своп при нехватке RAM или заполнении данного хранилища и при выгрузке производится декомпрессия.

Необходимо включить zswap в ядре: CONFIG_ZSWAP=y, либо в menuconfig:

Memory Management options  --->
[*] Support for paging of anonymous memory (swap)  --->
[*]   Compressed cache for swap pages

Также стоит обратить внимание на другие доступные опции конфигурации, например - выбрать дефолтные метод компрессии CONFIG_ZSWAP_COMPRESSOR_DEFAULT_XXX и аллокатор CONFIG_ZSWAP_ZPOOL_DEFAULT_XXX.

Проверить сессию на наличие zswap можно несколькими способами:

  1. # dmesg | grep zswap

  2. $ grep -r . /sys/module/zswap/parameters/

Настройку параметров можно производить либо в рантайме (через манипуляцию параметров в /sys/module/zswap/parameters/max_pool_percent), либо в параметрах загрузки ядра. Доступные параметры и их расшифровка описаны здесь: https://docs.kernel.org/admin-guide/mm/zswap.html

Если используешь не очень старую версию htop, то там эта память будет учитываться в общих графах compressed и frontswap.

Если используются одновременно zswap и zram (конкректно для swap), то лучше выбрать что-то одно, особенно при использовании ZRAM_WRITEBACK.

KSM

Kernel Samepage Merging - технология дедупликации одинаковых страниц памяти. Не является непосредственно сжатием, но позволяет получить больше свободной RAM, так что пусть тут будет.

На ядро должен быть наложен патч UKSM.

Необходимо включить KSM в ядре: CONFIG_KSM=y, либо в menuconfig:

Memory Management options  --->
[*] Enable KSM for page merging

Проверить сессию на присутствие и работоспособность KSM можно через проверку в /sys, например:

$ grep -r . /sys/kernel/mm/ksm

Если ядро настроено корректно, то каталог /sys/kernel/mm/ksm должен существовать и значение /sys/kernel/mm/ksm/run быть «1».

Слияние памяти происходит только для процессов, помеченных madvise(). Так как ручками мы делать это не будем, далее стоит установить sys-process/uksmd. Данный демон работает в фоне и производит инициализацию слияния автоматически, достаточно закрепить его в системе как сервис.

Послесловие

Надеюсь, что тебе понравилось читать эту статью настолько же, насколько мне нравилось её писать.

Предложения/исправления/дополнения приветствуются.

Форумчанин @kirill_rrr произвёл бенчмарк разных наборов конфигураций zram, swap и zswap в 2023.

★★★★★

Проверено: cetjs2 ()
Последнее исправление: Bfgeshka (всего исправлений: 5)

в ядре: ..., либо в menuconfig:

фраза некорректна. одно не противоречит другому. надо что-то типа:
в ядре: .... В menuconfig:

teod0r ★★★★★
()

значение /sys/kernel/mm/ksm/run быть «1».

а если «0»?
вообще какая-то куцая статья. Надо больше про конфигурирование.

teod0r ★★★★★
()

zram это, если описать попроще, tmpfs со сжатием.

Слой блочного устройства может (и будет) немного срать.

Гентувики заточена конкретно под компиляцию генту, общие вопросы там крайне поверхностные. sys-apps/zram-generator и sys-block/zram-init не особо то раскрыты. На первый взгляд это менее удобный способ прямой настройки zram.

ZRAM_WRITEBACK это то же что и /sys/block/zram*/backing_dev если я ничего не путаю? Важность этой опции надо раскрыть отдельно: если zram используется для свопа с возможностью физического свопинга, то можно влететь на повисание в оперативке сжатых, но всё таки мёртвых данных в потенциально огромных количествах. Т.е. чтобы не слить производительность при неудачных обстоятельствах - backing_dev именно вместо физического свопа. Именно поэтому я предпочитаю zswap, хотя теоретически zram выигрывает условные ~5% скорости. Если нормально настроен.

KSM

У меня был неудачный опыт с появлением фризов и нагрузкой на цпу. Правда это было давно и на pf-sources а н ванильном ядре. Прочесать бы этот вопрос... В конце концов где «умная дедупликация» там и возможность косяков «сборщика мусора».

kirill_rrr ★★★★★
()

KSM

Я правильно понимаю, что есть у меня сервер на котором docker и крутится десяток контейнеров с nginx (одной версии) то оно будет дедуплицировать в памяти общие либы nginx?

Kolins ★★★★★
()

В арче все по дефолту включено. Но ты главного не написал: как zram включить чтобы перестать насиловать диск, ловя лаги из-за высокой латентности последнего (в тыщу раз медленее) в сравнении с рамой

rtxtxtrx ★★★
()
Ответ на: комментарий от kirill_rrr

Гентувики заточена конкретно под компиляцию генту, общие вопросы там крайне поверхностные.

Там по конкретному вопросу очень мало специфичного, чуть-чуть про настройку ядра и остальное про то, как настраивать zram в юзерспейсе.

sys-apps/zram-generator и sys-block/zram-init не особо то раскрыты.

zram-init очень простой в настройке и использовании - мб могу впилить пару примеров, но там всё в конфиге описано, опять же. Про sys-apps/zram-generator я ничего сказать не могу, т.к. не использую systemd.

Важность этой опции надо раскрыть отдельно: если zram используется для свопа с возможностью физического свопинга, то можно влететь на повисание в оперативке сжатых, но всё таки мёртвых данных в потенциально огромных количествах. Т.е. чтобы не слить производительность при неудачных обстоятельствах - backing_dev именно вместо физического свопа. Именно поэтому я предпочитаю zswap, хотя теоретически zram выигрывает условные ~5% скорости. Если нормально настроен.

Упомянул в zswap, но мб будет лучше яснее описать, ок.

У меня был неудачный опыт с появлением фризов и нагрузкой на цпу. Правда это было давно и на pf-sources а н ванильном ядре. Прочесать бы этот вопрос… В конце концов где «умная дедупликация» там и возможность косяков «сборщика мусора».

Я на него как только не смотрю, он нагрузку всегда 0.0% даёт. Сложно сравнивать «на глаз», но никогда негатив от него не замечаю.

Bfgeshka ★★★★★
() автор топика
Ответ на: комментарий от Kolins

Я правильно понимаю, что есть у меня сервер на котором docker и крутится десяток контейнеров с nginx (одной версии) то оно будет дедуплицировать в памяти общие либы nginx?

В этом замысел, да. KSM изначально для виртуалок KVM вообще писался, а вот оттуда уже его сделали «для народа».

Bfgeshka ★★★★★
() автор топика
Последнее исправление: Bfgeshka (всего исправлений: 1)
Ответ на: комментарий от Kolins

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

rtxtxtrx ★★★
()

далее стоит установить sys-process/uksmd

Утверждение верно только для пропатченных ядер, в основном zen, linux-pf, Liquorix…:

UKSMD-BUILTIN
(linux-rangho, linux-zencjk, linux-zen-pds, linux-zen-bmq, linux-cachyos-server, linux-cachyos-bmq, linux-zen-flukejones, linux-gaokun3, linux-zener, linux-pf, linux-lqx, linux-cachyos, linux-cachyos-bore, linux-cachyos-eevdf, linux-cachyos-lts, linux-cachyos-rc, linux6.13.6.zen1-1-zen-bin, linux-cachyos-hardened, linux-zen)
aur

krasnh ★★★★
()
Ответ на: комментарий от rtxtxtrx

Но ты главного не написал: как zram включить чтобы перестать насиловать диск, ловя лаги из-за высокой латентности последнего (в тыщу раз медленее) в сравнении с рамой

Нужно отключить writeback и тогда он писать на диск вообще не будет. Либо манипулировать параметрами для уменьшения приоритета записи, если без него никак.

Bfgeshka ★★★★★
() автор топика
Ответ на: комментарий от Bfgeshka

В этом замысел, да. KSM изначально для виртуалок KVM вообще писался

Больше 10 лет назад именно так и использовал
ЕМНИП, там тогда было 2 демона: ksmd и ksmtuned, да и в самих виртуалках модуль должен был быть загружен

Myp3ik ★★★
()
Последнее исправление: Myp3ik (всего исправлений: 1)

Дополнительные интересные параметры:

/sys/kernel/mm/lru_gen/enabled - Вкл/Выкл MGLUR, новый планировщик памяти. В районе ядер 6.1 - 6.9 активно патчился и менял своё поведение. Я натыкался на косяк когда он просто тупо не использовал черверть объёма вообще ни подо что. Предлагаю тестировать самостоятельно по месту.

/proc/sys/vm/page-cluster - число страниц, которые будут сбрасываться на диск своп-подсистемой за 1 раз. Для чистого zram хорошо 0, но мне кажется что если в итоге придётся свопиться на ssd то лучше сделать пакеты побоьше, как минимум не меньше физического кластера ssd. А ещё это работает как кеш записи в ФС, только для свопа. Вроде помогает когда на диск падает хаотичный i/o и от софта, и от свопа.

/proc/sys/vm/watermark_scale_factor - «новый swappines», через сложные и непонятные алгоримы, но в итоге задаёт насколько рано начинать свопиться и насколько жирный кусок памяти держать свободным на всякий случай.

/proc/sys/vm/min_free_kbytes - а стоит ли его сейчас трогать? А если стоит, то может выкрутить в ноль?

kirill_rrr ★★★★★
()
Ответ на: комментарий от kirill_rrr

Я последнее ядро собрал с новым LRU, например, но буквально ещё даже не перезагружался для тестирования, лол.

Я вообще считаю, что тюнинг это хорошо и мне лично интересно, но статья вообще не об этом - до относительно недавнего времени я долго мотался как слепой котёнок и даже не знал, что, где и как работает в принципе. Не знал даже, что у меня есть, что работает и что не работает.

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

Bfgeshka ★★★★★
() автор топика

сервис для runit:

conf

FRACTION=75    # % of total RAM
ALGORITHM=lz4

run

#!/bin/sh

[ -r ./conf ] && . ./conf

MEMORY_KB=$(awk '/MemTotal/{print $2}' /proc/meminfo)
MEMORY_TOTAL=$((MEMORY_KB * 1024))
CPUS=$(nproc)
SIZE=$((MEMORY_TOTAL * FRACTION / 100 / CPUS))

modprobe zram num_devices=$CPUS

for n in $(seq $CPUS)
do
        i=$((n - 1))
        echo $ALGORITHM > /sys/block/zram$i/comp_algorithm
        echo $SIZE > /sys/block/zram$i/disksize
        mkswap /dev/zram$i
        swapon /dev/zram$i --priority 10
done

exec chpst -b zram pause

finish

#!/bin/sh

CPUS=$(nproc)

for n in $(seq $CPUS)
do
        i=$((n - 1))
        swapoff /dev/zram$i && echo "zram: disabled disk $n of $CPUS" &
done

wait
sleep .5
modprobe --remove zram
jfs
()
Ответ на: комментарий от Bfgeshka

Если ты в одном месте конфиг поменял, то в другом менять не нужно. Отсюда «либо».

В каком «одном»? ты разве можешь просто конфиг редактором поправить? В любом случае придётся использовать или menuconfig или какой-нибудь другой *config. мне больше нравится nconfig.

teod0r ★★★★★
()

Необходимо включить zram в ядре

Сразу нет. Ядро собирают только красноглазики. Если я откажусь от дефолтного ядра, то придётся приседать с dkms, а мне это нахрен не нужно.

ox55ff ★★★★★
()
Ответ на: комментарий от ox55ff

Сразу нет. Ядро собирают только красноглазики.

Думаю, в 2025 это уже везде дефолт. Я про включение «zram в ядре».

krasnh ★★★★
()

Форумчанин @kirill_rrr произвёл бенчмарк разных наборов конфигураций zram, swap и zswap в 2023.

Посмотрел оп-пост, что-то там не видно прям существенного прироста. В каких случаях использование этого будет прям сильно влиять (скажем, на 50% быстрее чем простой своп)?

micronekodesu ★★★
()

У всего свои плюсы и минусы. За эти zram и zswap придётся платить уменьшением быстродействия. В то время как можно докупить планку памяти и не жертвовать скоростью.

saahriktu ★★★★★
()
Ответ на: комментарий от saahriktu

За эти zram и zswap придётся платить уменьшением быстродействия.

«Уменьшением быстродействия», которое можно увидеть только на бечмарке, а человеческому глазу не заметно. А вот «докупать планку памяти» не придется, особенно, если некуда ставить. )

Так что, мизерный процент «Уменьшение быстродействия» против в полтора/два раза «софтового увеличения объема ram».

krasnh ★★★★
()
Ответ на: комментарий от saahriktu

Для современных процессоров расходы очень маленькие. Если же человек пытается выжать допрлнительную память из старичка, то да, там прийдётся терпеть.

mamina_radost
()
Ответ на: комментарий от mamina_radost

Это если один раз положить данные, а потом один раз взять. А если, например, какой-то процесс активно обращается к файлу в /tmp, при этом не целиком его читает, а каждый раз отдельные куски? И как заранее предугадать сколько таких процессов может быть у юзера?

saahriktu ★★★★★
()
Ответ на: комментарий от micronekodesu

Тотальный прирост имеется если свопиться на hdd. Оказалось современные ssd, если не упираются в шину, то свопятся близко к скорости сжатия zswap/zram.

Но прирост всё таки есть, и он больше чем кажется на первый взгляд: я писал что в моём тестовом скрипте присутстьвовал суммарный sleep на 6:04 чтобы растянуть нагрузку на цпу и не давать ему захлебнуться с 10 вкладками на ядро.

А ещё сжатие памяти сильно снижает i/o, что не только будет экономить ресурс, но и поднимет производительность когда всё упрётся в i/o.

kirill_rrr ★★★★★
()
Ответ на: комментарий от saahriktu

Как раз на примере компиляции в tmpfs среднестатистически это даст больше производительности. А там и умножение свопинга на страницу взял/страницу положил, и нагрузка от компрессии-декомпрессии, но по итогу время компиляции снижается.

kirill_rrr ★★★★★
()
Ответ на: комментарий от greenman

видно альтовца

в alt кстати этот самый zram предлагается реализовать при помощи скрипта котрый дергает юнит https://www.altlinux.org/ZRAM/ZSWAP - хорошее решение вопроса я так считаю.

amd_amd ★★★★★
()
Последнее исправление: amd_amd (всего исправлений: 1)
Ответ на: комментарий от amd_amd
$ sudo -e /etc/system/system/zram-swap.service
[Unit]
Description=Enable ZRAM swap
After=multi-user.target

[Service]
Type=oneshot
ExecStart=/usr/bin/zramctl --size 8G --algorithm zstd /dev/zram0
ExecStart=/sbin/mkswap /dev/zram0
ExecStart=/sbin/swapon /dev/zram0
RemainAfterExit=true

[Install]
WantedBy=multi-user.target

$ sudo systemctl enable --now zram-swap

$ sudo -e /etc/sysctl.d/99-swappiness.conf 
vm.swappiness = 180
vm.watermark_boost_factor = 0
vm.watermark_scale_factor = 125
vm.page-cluster = 0

# Применим
$ sudo sysctl --sys
rtxtxtrx ★★★
()
Последнее исправление: rtxtxtrx (всего исправлений: 2)
Ответ на: комментарий от amd_amd

При его переполнении вновь выгружаемые страницы будут попадать в следующие по очереди, более медленные разделы на физических устройствах, в результате чего растёт вероятность возникновения LRU-инверсии.

Таким образом, использование zram-устройства в качестве свопа имеет смысл в основном при отсутствии разделов подкачки других типов в системе.

greenman ★★★★★
()
Ответ на: комментарий от saahriktu

можно докупить планку памяти

Щас практически у каждого есть мини-ноутбук или одноплатник, где ОЗУ - впаяно навечно. Так что во многих случаях - нельзя.

somemong
()
Ответ на: комментарий от amd_amd

Странные обсуждения. zswap вообщемонжо настроить опциями ядра при загрузке, а в любом дистре независимо от системы инициации - передачей параметров в /sys. В каждой же системе цинициации и дисрибутиве есть стандартный способ выполнить скрипт при запуске.

А от юнита, который дёрнет zramctl вместо прямой настройки я вообще фигею!

kirill_rrr ★★★★★
()
Последнее исправление: kirill_rrr (всего исправлений: 2)
Для того чтобы оставить комментарий войдите или зарегистрируйтесь.