Ограничить размер буферного кеша в Linux


25

Есть ли способ указать ядру Linux использовать только определенный процент памяти для буферного кэша? Я знаю, что /proc/sys/vm/drop_cachesможно использовать для временной очистки кэша, но есть ли какие-либо постоянные настройки, которые препятствуют его росту до, например, более 50% основной памяти?

Причина, по которой я хочу это сделать, заключается в том, что у меня есть сервер с OSD Ceph, который постоянно обслуживает данные с диска и в течение нескольких часов может использовать всю физическую память в качестве буферного кеша. В то же время мне нужно запускать приложения, которые будут выделять большой объем (несколько десятков ГБ) физической памяти. Вопреки распространенному мнению (см. Советы, данные почти по всем вопросам, касающимся кеш-буфера), автоматическое освобождение памяти путем удаления записей чистого кеша не происходит мгновенно: запуск моего приложения может занять до минуты, когда кеш-буфер заполнен ( *), хотя после очистки кеша (использования echo 3 > /proc/sys/vm/drop_caches) одно и то же приложение запускается практически мгновенно.

(*) В течение этой минуты запуска приложения происходит сбой в новой памяти, но он тратит 100% своего времени в ядре, согласно Vtune в вызываемой функции pageblock_pfn_to_page. Эта функция, похоже, связана с уплотнением памяти, необходимым для поиска больших страниц, что заставляет меня поверить, что проблема заключается в фрагментации.


1
Существует то, что называется многоуровневым кэшированием. ceph osd pool set {cachepool} hit_set_count 1 ceph osd pool set {cachepool} hit_set_period 3600 ceph osd pool set {cachepool} target_max_bytes 1000000000000 в качестве примера см. пример. docs.ceph.com/docs/master/rados/operations/cache-tiering
Майкл Д.

2
Поскольку эта проблема, по-видимому, влияет только на запуск приложений, интенсивно использующих память, возможно, вы могли бы запускать приложения с помощью сценария, который очищает кэш перед тем, как запускать их. Может быть, это запускает их быстрее, оставляя управление кэшем ядру, пока они работают.
Таун

Ответы:


14

Если вы не хотите абсолютного ограничения, а просто заставляете ядро ​​быстрее очищать буферы, вы должны посмотреть на vm.vfs_cache_pressure

Эта переменная контролирует тенденцию ядра восстанавливать память, которая используется для кэширования VFS-кэшей, в отличие от pagecache и swap. Увеличение этого значения увеличивает скорость восстановления кэшей VFS.

Диапазон от 0 до 200. Переместите его к 200 для более высокого давления. По умолчанию установлено значение 100. Вы также можете проанализировать использование памяти с помощью slabtopкоманды. В вашем случае, dentryи *_inode_cacheзначение должно быть высоким.

Если вы хотите абсолютный предел, вы должны посмотреть вверх cgroups. Поместите сервер OSD Ceph в cgroup и ограничьте максимальный объем памяти, который он может использовать, установив memory.limit_in_bytesпараметр для cgroup.

memory.memsw.limit_in_bytesустанавливает максимальный объем суммы памяти и использования подкачки. Если никакие единицы не указаны, значение интерпретируется как байты. Тем не менее, можно использовать суффиксы для представления более крупных единиц измерения - k или K для килобайт, m или M для мегабайт и g или G для гигабайт.

Ссылки:

[1] - Настройка ядра GlusterFS Linux

[2] - Руководство по управлению ресурсами RHEL 6


1
limit_in_bytesКажется, это делает cgroup с множеством. Благодарность!
Вим

4
Я думаю, что vfs_cache_pressureочищает только кэш-память и иноды и не имеет ничего общего с буферным кешем.
kawing-

Увеличение vfs_cache_pressureвыше 100может помочь, если у вас недостаточно оперативной памяти для вашей рабочей нагрузки. Это уменьшит использование оперативной памяти, но приведет к снижению производительности ввода-вывода в целом.
Микко Ранталайнен

3

Я не знаю об A%, но вы можете установить ограничение по времени, чтобы оно сбрасывалось через x минут.

Сначала в терминале

sync && echo 3 | sudo tee /proc/sys/vm/drop_caches

Очистить текущие кэши.

Сделайте это cron-job нажатием Alt-F2, напечатайте gksudo gedit /etc/crontab, затем добавьте эту строку внизу.

 */15 *    * * *   root    sync && echo 3 > /proc/sys/vm/drop_caches

Это очищает каждые 15 минут. Вы можете установить 1 или 5 минут, если действительно хотите, изменив первый параметр на * или * / 5 вместо * / 15.

Чтобы увидеть вашу свободную оперативную память, кроме кеша:

free -m | sed -n -e '3p' | grep -Po "\d+$

Я чувствую здесь немного избыточности. Насколько я знаю, 3 > drop_cachesвключает в себя поведениеsync
andras.tim

1
@ andras.tim no - sync записывает грязные страницы на диск, 3 в drop_caches только освобождает / освобождает память, используемую чистыми страницами и другими кешами. вам не нужно запускать синхронизацию, но если вы это сделаете, больше памяти будет чистым, а не грязным, и больше памяти будет освобождено, когда вы сбрасываете кеши
Даниэль С. Стерлинг,

2

Я думаю, что ваша догадка в самом конце вашего вопроса на правильном пути. Я подозреваю, что A, NUMA-осведомленное распределение памяти перемещает страницы между процессорами, или B, более вероятно, код дефрагментации прозрачных огромных страниц, пытающихся найти смежные, выровненные области.

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

Это помогло бы узнать, какое ядро ​​вы используете, содержимое / proc / meminfo (или, по крайней мере, значения HugePages_ *.), И, если возможно, больше из графа vtune profiler, ссылающегося на pageblock_pfn_to_page ().

Также, если вы потворствуете моим догадкам, попробуйте отключить дефрагментацию огромный страницы с помощью:

echo 'never'> / sys / kernel / mm / transparent_hugepage / defrag

(это может быть вместо этого, в зависимости от вашего ядра :)

echo 'never'> / sys / kernel / mm / redhat_transparent_hugepage / defrag

Наконец, это приложение использует много десятков гигабайт оперативной памяти, что вы написали? Какой язык?

Поскольку вы использовали термин «сбой в страницах памяти», я полагаю, вы достаточно знакомы с рабочим дизайном и виртуальной памятью. Я изо всех сил пытаюсь представить себе ситуацию / приложение, которое будет работать так агрессивно, что не будет читать при большом количестве операций ввода-вывода - почти всегда из буферного кэша, который вы пытаетесь ограничить.

(Если вам интересно, посмотрите флаги mmap (2), такие как MAP_ANONYMOUS, MAP_POPULATE и mincore (2), которые можно использовать, чтобы увидеть, какие виртуальные страницы на самом деле имеют отображенную физическую страницу.)

Удачи!


2

Если Ceph OSD - это отдельный процесс, вы можете использовать cgroups для управления ресурсами, используемыми процессом:

Создайте cgroup с именем наподобие group1 с ограничением памяти (например, 50 ГБ, поддерживаются другие ограничения, например, CPU, в примере также упоминается CPU):

cgcreate -g memory,cpu:group1

cgset -r memory.limit_in_bytes=$((50*1024*1024*1024)) group1

Затем, если ваше приложение уже запущено, перенесите приложение в эту группу:

cgclassify -g memory,cpu:group1 $(pidof your_app_name)

Или запустите ваше приложение в этой группе:

cgexec -g memory,cpu:group1 your_app_name

0

tuned - это динамический адаптивный демон настройки системы, который динамически настраивает параметры системы в зависимости от использования.

 $ man tuned

Смотрите соответствующую документацию и файлы конфигурации.

 /etc/tuned
 /etc/tuned/*.conf
 /usr/share/doc/tuned-2.4.1
 /usr/share/doc/tuned-2.4.1/TIPS.txt

This parameter may be useful for you.

** Set flushing to once per 5 minutes
** echo "3000" > /proc/sys/vm/dirty_writeback_centisecs

Дополнительная информация

Команда sync очищает буфер, т. Е. Принудительно записывает все неписанные данные на диск, и может использоваться, когда кто-то хочет быть уверен, что все записано безопасно. В традиционных системах UNIX в фоновом режиме выполняется программа обновления, которая выполняет синхронизацию каждые 30 секунд, поэтому обычно нет необходимости использовать синхронизацию. В Linux есть дополнительный демон bdflush , который чаще выполняет несовершенную синхронизацию, чтобы избежать внезапного зависания из-за интенсивного дискового ввода-вывода, который иногда вызывает синхронизация .

Под Linux bdflush запускается обновлением. Обычно нет причин для беспокойства, но если по какой-то причине bdflush умрет, ядро ​​предупредит об этом, и вы должны запустить его вручную ( / sbin / update ).


1
Разве это не только для грязных записей? Я не думаю, что это проблема моей системы, поскольку все они чистые - задержка заключается не в записи грязных страниц, а в дефрагментации пространства, оставшегося после удаления чистых.
Вим

Да, это для грязных страниц, я думаю, вы также можете исправить другие проблемы с производительностью, настроив настроенный на динамический режим.
Иджаз Ахмад Хан

«Начиная с Linux 2.6, системный вызов [bdflush] устарел и ничего не делает. Скорее всего, он исчезнет в следующем выпуске ядра. В настоящее время задача, выполняемая bdflush (), обрабатывается потоком ядра pdflush». man7.org/linux/man-pages/man2/bdflush.2.html
sourcejedi
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.