Экономия оперативной памяти с KSM

KSM (Kernel SamePage Merging, также: Kernel Shared Memory, Memory Merging) — технология ядра, позволяющая объединять одинаковые страницы памяти между различными процессами в одну для совместного использования. Эта возможность позволяет снизить общее использование памяти виртуальными гостевыми системами при использовании KVM. Модуль ядра ksmd запускает сканирование памяти с заданным интервалом времени (настройка sleep_millisecs). Идентичные блоки объединяются в одну, а освободившиеся дубликаты удаляются. При этом, общая на несколько процессов страница помечается флагом «copy-on-write» и будет разделена ядром при следующем изменении каким либо из процессов. KSM поддерживается ядром Linux, начиная с версии 2.6.32, и доступно в QEMU с версии 0.12.

К плюсам данной технологии относится выделение превышающих физическое значение ресурсов памяти без использования файлов подкачки. Например, можно раздать 52 раза по 1GB виртуальным машинам с одинаковой Windows XP на борту и занять при этом физически всего 16GB реальной памяти хоста (эксперименты Red Hat). Из минусов — расходуется процессорное время, поэтому на машинах со слабым CPU включение KSM может больше навредить.

Чтобы начать использовать KSM, нужно собрать ядро с параметром CONFIG_KSM=y и включить ksm в системе через /sys/kernel/mm/ksm

echo 1 > /sys/kernel/mm/ksm/run

Для управления и сбора статистики доступны следующие ключи:

  • run — текущее состояние KSM (0 — остановлено, но объединенные ранее сохраняют состояние; 1 — запущено; 2 — полностью отключено)
  • full_scans — количество выполненных операций сканирования
  • sleep_millisecs — пауза между сканированиями памяти
  • pages_to_scan — количество страниц, анализируемое для потенциального объединения за один проход
  • pages_shared — количество объединенных страниц, если умножить значение на размер страницы (getconf PAGESIZE), получим общий объем памяти, который использует KSM
  • pages_sharing — количество повторов одних и тех же страниц (случайные или шифрованные данные, а также пустые блоки) в объединенном пуле. Эффективность KSM можно оценить по величине (pages_sharing)/(pages_shared)
  • (больше значит лучше)

  • pages_unshared — количество гостевых уникальных страниц, которые невозможно объединить сейчас, но будут проверены позже. Чем ниже (pages_unshared)/(pages_sharing), тем меньше усилий затрачивает KSM.
  • pages_volatile — количество страниц, содержимое которых меняется слишком часто для того, чтобы включать их в дедупликацию. Чем выше это значение, тем ниже эффективность KSM на сервере.

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

Ну, а чтобы не смотреть на эти параметры вручную, можно добавить графики эффективности в Zabbix. Пример темплейта представлен по ссылке: ksm_stats.xml. Добавляет график по четырем последним метрикам, а также коэффициенты пользы и затрат в виде отдельного графика. Помимо всего прочего добавлен триггер проверки, что модуль ksm запущен.

ksm

Скрипт сбора данных /etc/zabbix/scripts/ksm.sh выглядит следующим образом:

#!/bin/bash

case "${1}" in
	"run") value=$(cat /sys/kernel/mm/ksm/run);;
	"full_scans") value=$(cat /sys/kernel/mm/ksm/full_scans);;
	"pages_shared") value=$(cat /sys/kernel/mm/ksm/pages_shared);;
	"pages_sharing") value=$(cat /sys/kernel/mm/ksm/pages_sharing);;
	"pages_to_scan") value=$(cat /sys/kernel/mm/ksm/pages_to_scan);;
	"pages_unshared") value=$(cat /sys/kernel/mm/ksm/pages_unshared);;
	"pages_volatile") value=$(cat /sys/kernel/mm/ksm/pages_volatile);;
	"sleep_millisecs") value=$(cat /sys/kernel/mm/ksm/sleep_millisecs);;
	"profit") value=$(echo "scale=2;$(cat /sys/kernel/mm/ksm/pages_sharing) / $(cat /sys/kernel/mm/ksm/pages_shared)"|bc);;
	"effort") value=$(echo "scale=2;$(cat /sys/kernel/mm/ksm/pages_unshared) / $(cat /sys/kernel/mm/ksm/pages_sharing)"|bc);;
esac
echo $value

exit 0

Он подключается в конфигурации /etc/zabbix/zabbix_agentd.conf так:

UserParameter=ksm[*], /etc/zabbix/scripts/ksm.sh $1

Ссылки: