У меня сайт с высоким трафиком и я использую hibernate. Я также использую ehcache для кэширования некоторых сущностей и запросов, которые необходимы для генерации страниц.
Проблема в том, что «параллельные кеши пропадают», и длинное объяснение состоит в том, что, когда приложение загружается, а области кеша холодные, каждая область кеша заполняется много раз (а не только один раз) разными потоками, потому что сайт попадает многими пользователями одновременно. Кроме того, когда некоторая область кэша делает недействительной, она многократно заполняется по той же причине.
Как я могу избежать этого?
Мне удалось преобразовать 1 сущность и 1 кэш запросов в BlockingCache , предоставив мою собственную реализацию hibernate.cache.provider_class, но семантика BlockingCache, похоже, не работает. Даже хуже, иногда BlockingCache блокируется (блокируется), и приложение полностью зависает. Дамп потока показывает, что обработка на мьютексе BlockingCache заблокирована при выполнении операции get.
Итак, вопрос в том, поддерживает ли Hibernate этот вид использования?
А если нет, то как решить эту проблему на производстве?
Редактировать : hibernate.cache.provider_class указывает на мой пользовательский поставщик кэша, который является копией вставки из SingletonEhCacheProvider и в конце запуска ( ) метод (после строки 136) я делаю:
Ehcache cache = manager.getEhcache("foo");
if (!(cache instanceof BlockingCache)) {
manager.replaceCacheWithDecoratedCache(cache, new BlockingCache(cache));
}
Таким образом, после инициализации, и прежде чем кто-либо еще коснется кеша с именем "foo", я украшаю его с помощью BlockingCache. «foo» - это кеш запросов, а «bar» (тот же код, но пропущен) - кеш сущностей для pojo.
Редактировать 2 : «Кажется, не работает» означает, что первоначальная проблема все еще существует. Из-за параллелизма кэш "foo" все еще много раз переполняется одними и теми же данными. Я подтверждаю это, подчеркивая сайт с JMeter с 10 потоков. Я ожидал, что 9 потоков будут блокироваться до тех пор, пока первый, который запросит данные у «foo», не завершит свою работу (выполнит запросы, сохранит данные в кеше), а затем получит данные непосредственно из кеша.
Редактировать 3 : Другое объяснение этой проблемы можно увидеть в https://forum.hibernate.org/viewtopic.php?f=1&t=964391&start=0, но без определенного ответа.