Этот может быть хорошим примером использования для EhCache и Hibernate кеш запросов . Вот основная архитектура. Сначала включите кэш второго уровня для объекта Position
. Я думаю, что оно пропускает поле asset
, которое представляет отношение один-ко-многим, но это не имеет значения.
Я предполагаю, что клиенты выполняют запрос, подобный этому:
SELECT p
FROM Position p
WHERE timestamp >= :timestamp
AND asset = :assert
Параметр :timestamp
представляет последние 24 часа (текущее время - 24 часа). Вам необходимо включить подсказку запроса cacheable
для этого запроса.
Вот что происходит: клиент выполняет этот запрос косвенно с парой (asset, timestamp)
параметров. Hibernate пытается найти результат запроса в кеше запросов для этой пары, которая (упрощенно) составляет ключ кеша запросов.
Если результат запроса отсутствует, он запускает запрос и помещает результаты в кэш запроса. Но он размещает только идентификаторы совпадающих Position
экземпляров, а не сами экземпляры. В следующий раз, когда какой-нибудь клиент запросит ту же пару (asset, timestamp)
, Hibernate найдет результаты в кеше запросов. Затем, имея только идентификаторы, он будет искать Position
экземпляров в кэше второго уровня.
Как видите, этот сценарий довольно сложный, и на общий успех повлияют несколько факторов:
- сколько существует различных пар
(asset, timestamp)
? Грубо:
.
86400 (number of different seconds in a day) times
number of different assets
ключи и значения должны помещаться в кэш. Помните, что каждое значение является списком Position
идентификаторов. Это много памяти. Вы, вероятно, можете сократить это, ограничив количество различных временных меток. Важны ли последние 24 часа? Может ли это быть между 23 и 24 часами или около того? Таким образом, вы можете округлять временные метки и уменьшать размер пространства ключей (размер кэша).
Все Position
ссылки на экземпляры по идентификатору из кеша запросов должны помещаться в кеш. Это может быть огромным. Но в противном случае вы столкнетесь с проблемой N + 1
, так как при отсутствии сущности Position
в кэше L2 при извлечении из кэша запросов Hibernate будет выполнять неявный запрос по идентификатору из базы данных.
Аннулирование кэша выполняется Hibernate. Однако помните, что каждая вставка в таблицу Position
делает кеш запросов недействительным. В ваших обстоятельствах полный разогрев кеша может оказаться невозможным.
При этом вам следует попробовать запросить кеширование в Hibernate. Однако кэш запросов очень сложен и требует много настроек для правильной реализации.
Совет: если вам не хватает памяти, попробуйте переполнить EhCache на диск. Никогда не пробовал, но я верю, что выборочные значения кеша с локального диска (особенно при использовании SSD) могут быть намного быстрее, чем пропадание кеша и запрос к базе данных.