Как 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
Рассмотрим приведенную выше утилиту свободной памяти с использованием флага -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 ГБ примерно и вступило в силу. Теперь воспользуемся бесплатно команду еще раз, чтобы увидеть любые изменения, распознаваемые системой.
# бесплатно -m
Свободная память и буферный кеш не изменяются командой, но объем памяти отображается как имеется в наличии уменьшено с 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; кошка / корень / d1.txt >> / root / data_file; Выполнено
Давайте прочитаем файл и проигнорируем его содержимое, прочитав и перенаправив файл в / dev / null, как показано ниже:
# cat файл_данных> / dev / nullХорошо, что случилось с нашей системной памятью с помощью этого набора маневров, давайте теперь проверим это:
# бесплатно -m
Анализируя результаты выше. У нас еще есть 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 секунд до .364 секунды со всем этим в кеше.
Мне любопытно провести еще один эксперимент. Что происходит с вызовами malloc для выделения памяти из программы на C перед лицом действительно высокой vm.установка min_free_kbytes. Будет ли он терпеть неудачу? Система умрет? Сначала сбросьте виртуальную машину.min_free_kbytes на действительно высокое значение, чтобы возобновить наши эксперименты:
# эхо 1500000> / proc / 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] отправка свиней: 1 виртуальная машина
стресс-нг: информация: [17537] выделение кеша: размер кеша по умолчанию: 46080К
стресс-нг: информация: [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 рабочими.
Сбросим ВМ.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 файл.
Заключение
Мы видели, что vm.min_free_kbytes настраиваемый ядро Linux может быть изменен и может резервировать память в системе, чтобы обеспечить более стабильную работу системы, особенно во время интенсивного использования и интенсивного выделения памяти. Настройки по умолчанию могут быть слишком низкими, особенно в системах с высоким объемом памяти, и их следует тщательно увеличивать. Мы видели, что память, зарезервированная этим параметром, не позволяет кешу ОС использовать всю память, а также предотвращает использование всей памяти некоторыми операциями malloc.