Как поручить Linux не менять горячие страницы mmaped файлов?

У меня есть сервер, на котором я запускаю рабочие процессы, которые представляют собой довольно большие "словарные" файлы "только для чтения" (всего ~8 ГБ). Тесты показали, что они активно получают доступ к страницам в этих файлах только на ~1 ГБ. На том же сервере я запускаю другой процесс, который последовательно читает огромный файл, объединяет некоторые обновления и записывает результат в новую версию этого огромного файла. На этом сервере нет никакой другой важной деятельности, кроме этого процесса слияния и рабочих процессов. Поэтому обычно рабочие должны быть связаны с процессором, а слияние должно быть связано с диском. Но я вижу, что рабочие постоянно задыхаются от крупных ошибок на странице. Слияние использует около 20 ГБ RSS, а машина имеет 48 ГБ. Есть 4 рабочих. Они имеют 2 ГБ RSS каждый и только 600 МБ общего доступа (вместо ожидаемого 1 ГБ горячих страниц). Каким-то образом остальная часть памяти в основном используется кешем fs. Есть ли способ "расставить приоритеты" горячих страниц моих mmaped файлов в памяти? Я попробовал Madvise(MADV_WILLNEED), но это не помогло. Может быть, есть решение с cgroups или sysctls?

$ бесплатно
             общее количество использованных свободных общих буферов в кеше
Mem:      49324064   48863392     460672          0      22520   25409896
-/+ буферы / кэш:   23430976   25893088
Обмен: 0 0 0

$ uname -a
Linux dev-kiwi02 3.2.0-25-сервер #40-Ubuntu SMP пт 25 мая 13:12:35 UTC 2012 x86_64 GNU / Linux

PS Об этом уже спрашивали в StackOverflow, но, похоже, ServerFault более уместен.

1 ответ

Что вам, вероятно, нужно, это mlock(), а не madvise(). Madvise слишком "слаб"; mlock блокирует память в ядре. Предполагая, что у вас достаточно ОЗУ и заблокированы только "горячие" страницы (не все 8 ГБ), что не должно быть проблемой для вашей установки.

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

Другие вопросы по тегам