Сколько уровней кэша есть в базе данных
Что проверяют
Слышите ли вы за формулировкой контекст. На java-собеседовании «уровни кэша» почти всегда про Hibernate, но спросить могут и про кэши самой СУБД. Ждут, что вы уточните и разложите слои по назначению, а не назовёте число.
Как отвечать
Если речь про JPA и Hibernate, уровня два и рядом с ними третий механизм:
- первый уровень: контекст персистентности, живёт в пределах сессии или транзакции, включён всегда и отключить его нельзя. Повторный
findпо тому же идентификатору внутри транзакции в базу не пойдёт; - второй уровень: общий на фабрику сессий, то есть на приложение. Нужен провайдер вроде Ehcache, Infinispan или Caffeine, включается точечно аннотацией на сущности, хранит не готовые объекты, а их состояние по идентификатору;
- кэш запросов: отдельный переключатель, работает только вместе со вторым уровнем, хранит списки идентификаторов для текста запроса с параметрами и сбрасывается при любой записи в затронутые таблицы.
Выше по стеку есть кэш приложения (@Cacheable поверх Redis или Caffeine), ниже кэши самой базы: буферный пул страниц (shared_buffers в PostgreSQL), страничный кэш операционной системы, кэш планов и подготовленных запросов.
Где спотыкаются
Говорят, что база кэширует результаты запросов. В PostgreSQL кэша результатов нет вообще, в MySQL его выпилили. Кэшируются страницы и планы, а не готовые ответы, и путаница здесь стоит неверных выводов о производительности.
Второе: включают второй уровень и ждут ускорения, а получают рассинхрон. Если в таблицу пишет другой сервис или ваш же запрос мимо сессии, Hibernate об этом не узнает и продолжит отдавать устаревшее состояние.
Третье: считают первый уровень кэшем на всё приложение и удивляются, что в новой транзакции запрос снова идёт в базу. Он и не должен жить дольше сессии, иначе превратился бы в источник грязных данных для всех потоков сразу.