Могу ли я сказать Linux, чтобы не менять память определенных процессов?
Есть ли способ сказать Linux, что он не должен заменять память определенных процессов на диск?
Это приложение Java, поэтому в идеале я надеюсь на способ сделать это из командной строки.
Я знаю, что вы можете установить глобальную swappiness на 0, но является ли это мудрым?
Ответы
Ответ 1
Вы можете сделать это через системный вызов mlockall (2) под Linux; это будет работать на весь процесс, но прочитайте о аргументе, который вам нужно передать.
Вам действительно нужно вытащить все это в ядре? Если это приложение java, вы, вероятно, заблокируете всю JVM в ядре. Я не знаю метода командной строки для этого, но вы можете написать тривиальную программу для вызова fork
, вызвать mlockall
, затем exec
.
Вы также можете посмотреть, соответствует ли одно из уведомлений шаблона доступа в madvise (2) вашим потребностям. Консультирование подсистемы VM о лучшей стратегии поискового вызова может работать лучше, если она применима для вас.
Обратите внимание, что давным-давно в SunOS появился механизм, похожий на madvise, называемый vadvise (2).
Ответ 2
Если вы хотите изменить swappiness для процесса, добавьте его в cgroup и установите для этой группы значение:
https://unix.stackexchange.com/questions/10214/per-process-swapiness-for-linux#10227
Ответ 3
Вы можете сделать это с помощью mlock семейства системных вызовов. Я не уверен, однако, если вы можете сделать это для другого процесса.
Ответ 4
В качестве суперпользователя вы можете "смириться" с уровнем наивысшего приоритета -20 и надеяться, что этого достаточно, чтобы его не заменили. Обычно это так. Положительные номера имеют более низкий приоритет планирования. Обычные пользователи не могут смириться вверх (отрицательные номера)
Ответ 5
За исключением чрезвычайно необычных обстоятельств, задание этого вопроса означает, что вы делаете это неправильно (tm).
Серьезно, если Linux хочет поменять местами, и вы пытаетесь сохранить свой процесс в памяти, тогда вы ставите необоснованный спрос на ОС. Если ваше приложение так важно, то 1) купите больше памяти, 2) удалите другие приложения/демоны с компьютера или посвятите машину вашему приложению и/или 3) инвестируйте в действительно быструю дисковую подсистему. Эти шаги являются разумными для важного приложения. Если вы не можете их оправдать, вы, вероятно, не сможете оправдать электропроводку и голодать другие процессы.
Ответ 6
Существует класс приложений, в котором вы никогда не захотите их менять. Одним из таких классов является база данных. Базы данных будут использовать память как кеши и буферы для своих дисковых областей, и совершенно не имеет смысла, что они когда-либо заменяются. В конкретной памяти могут храниться некоторые релевантные данные, которые не нужны в течение недели, до одного дня, когда клиент запрашивает ее. Без кэширования/замены база данных просто найдет соответствующую запись на диске, которая будет довольно быстрой; но с заменой, ваше обслуживание может внезапно занять много времени, чтобы ответить.
mysqld
содержит код для использования системного вызова memlock
. В Linux, как минимум, 2.6.9, этот системный вызов будет работать для процессов без полномочий root, которые имеют возможность CAP_IPC_LOCK
[1]. При использовании memlock()
процесс должен работать в пределах предела LimitMEMLOCK
. [2]. Одна из (немногих) хороших вещей о systemd
заключается в том, что вы можете предоставить mysqld
эти возможности, не требуя специальной программы. Если также можно установить rlimits, как вы ожидаете, с помощью ulimit
. Вот файл override
для mysqld
, который выполняет требуемые шаги, в том числе несколько других, которые могут потребоваться для процесса, такого как база данных:
[Service]
# Prevent mysql from swapping
CapabilityBoundingSet=CAP_IPC_LOCK
# Let mysqld lock all memory to core (don't swap)
LimitMEMLOCK=-1
# do not kills this process if low on memory
OOMScoreAdjust=-900
# Use higher io scheduling
IOSchedulingClass=realtime
Type=simple
ExecStart=
ExecStart=/usr/sbin/mysqld --memlock $MYSQLD_OPTS
Примечание Стандартное сообщество mysql в настоящее время поставляется с Type=forking
и добавляет --daemonize
в параметр службы в строке ExecStart
. Это по своей сути менее устойчиво, чем вышеупомянутый метод.
ОБНОВЛЕНИЕ Я не на 100% доволен этим решением. После нескольких дней работы я заметил, что процесс по-прежнему имел огромное количество свопов! Изучая /proc/XXXX/smaps
, я отмечаю следующее:
- Самый большой вкладчик swap - из сегмента стека! 437 МБ и колебания. Это создает очевидные проблемы с производительностью. Он также указывает на утечку памяти на основе стека.
- Есть ноль заблокированных страниц. Это означает, что параметр
memlock
в MySQL (или Linux) не работает. В этом случае это не имеет большого значения, потому что MySQL не может блокировать стек.
Ответ 7
Почему вы хотите это сделать?
Если вы пытаетесь увеличить производительность этого приложения, вы, вероятно, ошибетесь. ОС поменяет процесс увеличения объема памяти для дискового кэша - даже если есть свободная оперативная память, ядро лучше знает (по-разному, ребята samrt, которые писали планировщик, знают лучше).
Если у вас есть процесс, который требует отклика (он поменяется, пока он не используется, и вам нужно его быстро перезапустить), то с ним справится высокий приоритет, mlock или использование ядра реального времени.