Могу ли я сказать Linux не выгружать память определенных процессов?

Есть ли способ сказать Linux, что он не должен выгружать память определенных процессов на диск?

Это приложение Java, поэтому в идеале я надеюсь, что это можно сделать из командной строки.

Я знаю, что вы можете установить глобальную подкачку на 0, но разумно ли это?

Ответов (7)

Решение

You can do this via the mlockall(2) system call under Linux; this will work for the whole process, but do read about the argument you need to pass.

Do you really need to pull the whole thing in-core? If it's a java app, you would presumably lock the whole JVM in-core. I don't know of a command-line method for doing this, but you could write a trivial program to call fork, call mlockall, then exec .

You might also look to see if one of the access pattern notifications in madvise(2) meets your needs. Advising the VM subsystem about a better paging strategy might work out better if it's applicable for you.

Note that a long time ago now under SunOS, there was a mechanism similar to madvise called vadvise(2).

Если вы хотите изменить подкачку для процесса, добавьте его в контрольную группу и установите значение для этой контрольной группы:

https://unix.stackexchange.com/questions/10214/per-process-swapiness-for-linux#10227

Существует класс приложений, в которых вы никогда не захотите их менять местами. Один из таких классов - база данных. Базы данных будут использовать память в качестве кешей и буферов для своих дисковых областей, и совершенно не имеет смысла помещать их в свопинг. В конкретной памяти могут храниться некоторые важные данные, которые не нужны в течение недели до тех пор, пока клиент не попросит об этом в один прекрасный день. Без кэширования / подкачки база данных просто нашла бы соответствующую запись на диске, что было бы довольно быстро; но при подкачке ваш сервис может быстро реагировать на запросы.

mysqld включает код для использования OS / системного вызова memlock . В Linux, начиная с версии 2.6.9, этот системный вызов будет работать для некорневых процессов, у которых есть 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, отмечаю следующее:

  • Наибольший вклад в обмен происходит из сегмента стека! 437 МБ и колеблется. Это представляет очевидные проблемы с производительностью. Это также указывает на утечку памяти на основе стека.
  • Нет заблокированных страниц . Это указывает на то, что memlockопция в MySQL (или Linux) не работает. В этом случае это не имело бы большого значения, потому что MySQL не может использовать стек блокировки памяти.

Как суперпользователь вы можете «настроить» его на самый высокий уровень приоритета -20 и надеяться, что этого достаточно, чтобы его не заменили. Обычно это так. Положительные числа понижают приоритет планирования. Нормальные пользователи не могут хорошо подниматься вверх (отрицательные номера).

Вы можете сделать это с помощью семейства системных вызовов mlock . Однако я не уверен, можно ли это сделать для другого процесса.

За исключением крайне необычных обстоятельств, этот вопрос означает, что вы делаете это неправильно (tm).

Серьезно, если Linux хочет поменять местами, а вы пытаетесь сохранить свой процесс в памяти, вы предъявляете необоснованные требования к ОС. Если ваше приложение так важно, то 1) купите больше памяти, 2) удалите с машины другие приложения / демоны или выделите машину для вашего приложения, и / или 3) инвестируйте в действительно быструю дисковую подсистему. Эти шаги разумны для важного приложения. Если вы не можете их оправдать, вы, вероятно, не сможете оправдать подключение памяти и голодание других процессов.

почему ты хочешь сделать это?
Если вы пытаетесь повысить производительность этого приложения, вы, вероятно, ошиблись. ОС заменит процесс, чтобы увеличить память для дискового кеша - даже если есть свободная оперативная память, ядро ​​знает лучше (на самом деле ребята из Samrt, которые написали планировщик, лучше всех знают).
Если у вас есть процесс, которому требуется отзывчивость (он заменяется, когда не используется, и вам нужно, чтобы он перезапускался быстро), тогда может помочь установить высокий приоритет, mlock или использование ядра реального времени.