Что такое vm.min_free_kbytes и как его настроить?

What Is Vm Min_free_kbytes



Что такое sysctl vm.min_free_kbytes, настраиваемый для ядра Linux, и какое значение должно быть установлено? В этой статье мы изучим этот параметр и его влияние на работающую систему Linux. Мы проверим его влияние на кэш страниц ОС и на маллоки, а также на то, что показывает команда system free при установке этого параметра. Мы сделаем несколько обоснованных предположений об идеальных значениях для этой настраиваемой переменной и покажем, как установить vm.min_free_kbytes навсегда, чтобы выжить после перезагрузки. Итак, начнем.

Как работает vm.min_free_kbytes

Выделение памяти может потребоваться системе для обеспечения правильного функционирования самой системы. Если ядро ​​позволяет выделить всю память, оно может столкнуться с трудностями при потребности в памяти для регулярных операций, чтобы обеспечить бесперебойную работу ОС. Вот почему ядро ​​предоставляет настраиваемый vm.min_free_kbytes. Настраиваемый параметр заставит диспетчер памяти ядра сохранить не менее X объема свободной памяти. Вот официальное определение от документация ядра Linux : Это используется, чтобы заставить виртуальную машину Linux сохранять минимальное количество килобайт свободным. ВМ использует это число для вычисления значения водяного знака [WMARK_MIN] для каждой зоны lowmem в системе. Каждая зона lowmem получает количество зарезервированных бесплатных страниц, пропорциональное ее размеру. Некоторый минимальный объем памяти необходим для распределения PF_MEMALLOC; если вы установите это значение ниже 1024 КБ, ваша система станет незаметно сломанной и склонной к тупиковой ситуации при высоких нагрузках. Установка слишком высокого значения мгновенно отключит вашу машину.







Проверка vm.min_free_kbytes Работает

Чтобы проверить, что настройка min_free_kbytes работает так, как задумано, я создал виртуальный экземпляр Linux только с 3,75 ГБ ОЗУ. Используйте бесплатную команду ниже для анализа системы:



#бесплатно



Рассмотрим приведенную выше утилиту для получения свободной памяти с использованием флага -m для вывода значений в МБ. Общий объем памяти составляет от 3,5 до 3,75 ГБ. Используется 121 МБ памяти, свободно 3,3 ГБ, буферный кеш занимает 251 МБ. И доступно 3,3 ГБ памяти.





Теперь мы собираемся изменить значение vm.min_free_kbytes и посмотреть, как это повлияет на системную память. Мы выведем новое значение в виртуальную файловую систему proc, чтобы изменить значение параметра ядра, как показано ниже:

# эхо 1500000> / proc / sys / vm / min_free_kbytes
# sysctl vm.min_free_kbytes



Вы можете видеть, что параметр был изменен примерно на 1,5 ГБ и вступил в силу. Теперь давайте воспользуемся бесплатно команду еще раз, чтобы увидеть любые изменения, обнаруженные системой.

#бесплатно

Свободная память и буферный кеш не изменяются командой, но объем памяти отображается как доступный уменьшено с 3327 до 1222 МБ. Что примерно соответствует уменьшению изменения параметра до 1,5 ГБ мин свободной памяти.

Теперь давайте создадим файл данных размером 2 ГБ и посмотрим, как чтение этого файла в буферный кеш влияет на значения. Вот как создать файл данных размером 2 ГБ в двух строках сценария bash ниже. Сценарий сгенерирует случайный файл размером 35 МБ с помощью команды dd, а затем скопирует его 70 раз в новый файл данных выход:

# dd if = / dev / random of = / root / d1.txt count = 1000000
# для i в `seq 1 70`; do echo $ i; cat /root/d1.txt >> / root / data_file; сделано

Давайте прочитаем файл и проигнорируем его содержимое, прочитав и перенаправив файл в / dev / null, как показано ниже:

#Котфайл данных> /разработчик/нулевой

Хорошо, что случилось с нашей системной памятью с помощью этого набора маневров, давайте теперь проверим это:

#бесплатно

Анализируем результаты выше. У нас все еще есть 1,8 ГБ свободной памяти, поэтому ядро ​​защитило большой кусок памяти как зарезервированный из-за нашей настройки min_free_kbytes. Буферный кеш использовал 1691 МБ, что меньше, чем общий размер нашего файла данных, который составляет 2,3 ГБ. Видимо весь файл данных не может быть сохранен в кеше из-за нехватки доступной памяти для использования в буферном кеше. Мы можем проверить, что весь файл не хранится в кеше, но рассчитываем время повторных попыток чтения файла. Если он был кэширован, чтение файла заняло бы долю секунды. Давай попробуем.

# time cat файл_данных> / dev / null
# time cat файл_данных> / dev / null

Чтение файла заняло почти 20 секунд, что означает, что он почти наверняка не кэшируется.

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

# echo 67584> / proc / sys / vm / min_free_kbytes
# time cat файл_данных> / dev / null
# time cat файл_данных> / dev / null

С дополнительной памятью, доступной для кеширования, время чтения файла упало с 20 секунд до 0,364 секунды, когда все это было в кеше.

Мне любопытно провести еще один эксперимент. Что происходит с вызовами malloc для выделения памяти из программы на языке C при очень высоком значении vm.min_free_kbytes. Будет ли он вывести из строя malloc? Система умрет? Сначала сбросьте параметр vm.min_free_kbytes на действительно высокое значение, чтобы возобновить наши эксперименты:

#выбросил 1500000 > /процентов/sys/vm/min_free_kbytes

Давайте еще раз посмотрим на нашу свободную память:

Теоретически у нас 1,9 ГБ свободно, а доступно 515 МБ. Давайте воспользуемся программой стресс-теста под названием stress-ng, чтобы задействовать немного памяти и посмотреть, где мы потерпим неудачу. Мы воспользуемся vm-тестером и попробуем выделить 1 ГБ памяти. Поскольку мы зарезервировали только 1,5 ГБ в системе 3,75 ГБ, я думаю, это должно сработать.

# stress-ng --vm 1 --vm-bytes 1G --timeout 60 с
стресс: информация:[17537]отправка свиней:1vm
стресс: информация:[17537]выделение кеша: размер кеша по умолчанию: 46080K
стресс: информация:[17537]успешный запуск завершенв60,09 с(1мин,0,09сухой)
# stress-ng --vm 2 --vm-bytes 1G --timeout 60 с
# stress-ng --vm 3 --vm-bytes 1G --timeout 60 с

Давайте попробуем еще раз с большим количеством воркеров, мы можем попробовать 1, 2, 3, 4 воркера, и в какой-то момент он должен потерпеть неудачу. В моем тесте он прошел с 1 и 2 рабочими, но не прошел с 3 рабочими.

Давайте сбросим vm.min_free_kbytes на меньшее значение и посмотрим, поможет ли это нам запустить 3 фактора стресса памяти по 1 ГБ каждый в системе 3,75 ГБ.

# echo 67584> / proc / sys / vm / min_free_kbytes
# stress-ng --vm 3 --vm-bytes 1G --timeout 60 с

На этот раз все прошло успешно, без ошибок, я пробовал два раза без проблем. Таким образом, я могу сделать вывод, что существует различие в поведении, когда для malloc доступно больше памяти, когда для параметра vm.min_free_kbytes установлено более низкое значение.

Настройка по умолчанию для vm.min_free_kbytes

Значение по умолчанию для параметра в моей системе - 67584, что составляет около 1,8% ОЗУ в системе или 64 МБ. По соображениям безопасности на сильно загруженной системе я бы увеличил его немного, возможно, до 128 МБ, чтобы обеспечить больше зарезервированной свободной памяти, однако для среднего использования значение по умолчанию кажется достаточно разумным. Официальная документация предупреждает о завышении значения. Установка этого параметра на 5 или 10% системной ОЗУ, вероятно, не является предполагаемым использованием параметра и слишком высока.

Настройка vm.min_free_kbytes, чтобы выжить после перезагрузки

Чтобы гарантировать, что параметр может выдерживать перезагрузку и не восстанавливается до значений по умолчанию при перезагрузке, обязательно сделайте параметр sysctl постоянным, поместив желаемое новое значение в файл /etc/sysctl.conf.

Заключение

Мы видели, что настраиваемый параметр ядра Linux vm.min_free_kbytes может быть изменен и может резервировать память в системе, чтобы обеспечить более стабильную работу системы, особенно при интенсивном использовании и интенсивном распределении памяти. Настройки по умолчанию могут быть слишком низкими, особенно в системах с большим объемом памяти, и их следует тщательно увеличивать. Мы видели, что память, зарезервированная этим параметром, не позволяет кешу ОС использовать всю память, а также предотвращает использование всей памяти некоторыми операциями malloc.