Как мониторить и сплашивать метрики кэша
Что проверяют
Работали ли вы с кэшем в проде или только ставили @Cacheable. Интервьюеру важно, знаете ли вы, какие метрики у кэша есть, откуда они берутся в Java-стеке и как по ним понять, что кэш не помогает. Следом часто спрашивают: «Hit rate 95%, а база всё равно под нагрузкой. Что смотреть?».
Как отвечать
Сначала назовите, что мерить:
- hit rate и miss rate: главное, но считать за окно, а не с момента старта;
- evictions: рост вытеснений при стабильном трафике значит, что
maximumSizeмал; - размер: сколько записей занято относительно лимита;
- время загрузки при промахе: от него зависит цена каждого miss;
- ошибки загрузки: промах, закончившийся исключением, выглядит для клиента как отказ сервиса.
Дальше откуда берутся цифры. У Caffeine статистика по умолчанию выключена, её включают recordStats() в билдере или recordStats в spring.cache.caffeine.spec, после чего cache.stats() отдаёт CacheStats с hitRate(), evictionCount(), averageLoadPenalty(). В Spring Boot с Actuator кэши из CacheManager, известные на старте, Micrometer регистрирует сам: появляются cache.gets с тегом result (hit или miss), cache.puts, cache.evictions, cache.size. Кэши, созданные позже, привязывают вручную через CacheMetricsRegistrar. С micrometer-registry-prometheus метрики уходят на /actuator/prometheus, а доля попаданий в Grafana считается как отношение rate(cache_gets_total{result="hit"}[5m]) к rate(cache_gets_total[5m]). Для Redis смотрят keyspace_hits, keyspace_misses и evicted_keys из INFO stats через экспортер, для JCache есть CacheStatisticsMXBean в JMX.
Алерты ставят на падение доли попаданий и рост времени загрузки, а не на абсолютные счётчики.
Где спотыкаются
Не включают статистику и удивляются нулям на дашборде. Для Caffeine без recordStats метрики есть, но пустые.
Смотрят на накопленный hit rate с момента старта. За неделю аптайма он почти не двигается, и деградация за последний час в нём не видна.
Кладут ключ кэша в тег метрики. Это взрыв кардинальности в Prometheus: тегом должно быть имя кэша, а не конкретная запись.