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