Эффективно ли ehcache вызывает LoaderWriter при работе с параллельными запросами?
(Контекст) Мне нужно создать кеш, который загружает информацию из базы данных и делает ее доступной для приложения. Эти данные не будут изменены в этом приложении и будут активно использоваться (извлекаться) многими потоками. Данные могут быть (редко) изменены из другого приложения. Обновление каждые 1 час более чем достаточно. Думаю, Ehcache подойдет, создав кэш для чтения.
Мысль о каком-то кеше вроде этого:
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("preConfigured",
CacheConfigurationBuilder.newCacheConfigurationBuilder(Integer.class, String.class, ResourcePoolsBuilder.heap(100))
.withExpiry(ExpiryPolicyBuilder.timeToLiveExpiration(Duration.ofHours(1)))
.withLoaderWriter(new CacheDataProvider())).build();
cacheManager.init();
Cache<Integer, String> myCache = cacheManager.getCache("preConfigured", Integer.class, String.class);
Представьте, что срок действия кэша истек (через 1 час), и поток запрашивает запись с ключом 1, а вскоре после того, как другой поток запрашивает ту же запись 1. Когда 1-й поток запрашивает запись 1, кэш проверит, что он истек, и запросит LoaderWriter. загрузить запись 1.
Мой вопрос таков: пока LoaderWriter загружает запись 1 для первого запроса, будет ли кэш помещать второй поток в "ожидание", пока не загрузится запись 1, или же второй запрос может инициировать (почти) одновременную загрузку для записи 1 снова. То есть в результате одна и та же запись загружается дважды из LoaderWriter?
1 ответ
Ehcache 3 в режиме сквозного кеширования блокирует весь доступ к данному ключу во время выполнения загрузчика. Это также указывает на то, что производительность загрузчика важна.
В вашем сценарии это означает, что один запрос будет отправлен в базу данных, и когда запись находится в кэше, после того, как первый поток завершит ее загрузку, второй поток сможет прочитать ее из кэша.
Обратите внимание, что эта система не относится к безопасности потоков, ваш загрузчик должен по-прежнему быть потокобезопасным для разных ключей, а к эффективному использованию ресурсов. Предполагается, что загрузка из БД намного медленнее, чем попадание в кэш.