DBAtlas · Атлас эксплуатации баз данных

Низкий коэффициент попаданий в кэш (buffer/cache hit)

Коэффициент попаданий в кэш низкий; данные постоянно читаются с диска (или из источника). Определите, в чём проблема — в буферном/общем кэше БД или в кэше Redis/приложения, затем измерьте и устраните её.

У какого кэша низкий коэффициент попаданий?

Измерьте коэффициент попаданий и локализуйте проблему: низкий ли он у буферного/общего кэша базы данных (много физических чтений), или в кэше Redis/приложения много промахов и вытеснений?

SELECT ROUND((1-(pr.value/(dbg.value+cg.value)))*100,2) AS buffer_hit_pct
FROM v$sysstat pr, v$sysstat dbg, v$sysstat cg
WHERE pr.name='physical reads' AND dbg.name='db block gets' AND cg.name='consistent gets';
  • Низкий коэффициент попаданий в буферный/общий кэш БД
  • Много промахов / вытеснений в кэше Redis/приложения

Почему чтение идёт с диска: размер или паттерн сканирования?

Есть две типичные причины низкого коэффициента попаданий в буфер: часто используемые данные (working set) не помещаются в память (кэш слишком мал) или большие полные сканирования таблиц засоряют кэш одноразовыми блоками и вытесняют полезные страницы.

SELECT component, current_size/1024/1024 AS mb FROM v$sga_dynamic_components WHERE component LIKE '%buffer cache%';
SELECT sql_id, disk_reads, executions FROM v$sql ORDER BY disk_reads DESC FETCH FIRST 10 ROWS ONLY;
  • Working set не помещается в RAM (кэш слишком мал)
  • Полные сканирования таблиц засоряют кэш

Почему промахи в Redis: вытеснение по maxmemory или управление TTL/ключами?

Если коэффициент попаданий Redis низкий, либо память достигла maxmemory и ключи вытесняются, либо управление TTL/паттерн кэширования ключей слабые (холодные ключи, низкое повторное использование).

INFO memory
# used_memory, maxmemory, maxmemory_policy, evicted_keys
CONFIG GET maxmemory-policy
INFO keyspace
# Key count and expires (keys with TTL) ratio per db
  • maxmemory заполнен, сильное вытеснение
  • Слабый паттерн TTL/ключей (низкое повторное использование)

Первопричина: кэш слишком мал для working set

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

Первопричина: паттерн сканирования засоряет кэш

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

Первопричина: вытеснение по maxmemory в Redis

Память Redis достигла лимита maxmemory; старые ключи вытесняются, освобождая место для новых (evicted_keys продолжает расти). При этом теряются ещё нужные записи и снижается коэффициент попаданий.

Первопричина: слабый паттерн TTL / кэширования

Либо ключи вообще не получают TTL, и память заполняется холодными данными, либо паттерн кэширования имеет низкое повторное использование, и большинство запросов заканчиваются промахами.

Открыть в DBAtlas →