Ho un sito Web ad alto traffico e utilizzo la sospensione. Uso anche ehcache per memorizzare alcune entità e query necessarie per generare le pagine.Evitare ripopolazioni multiple della stessa area della cache (a causa della concorrenza)
Il problema è "cache cache misses" e la spiegazione lunga è che quando l'applicazione si avvia e le regioni della cache sono fredde ogni area della cache viene popolata molte volte (anziché solo una volta) da thread diversi perché il sito è in fase di elaborazione colpito da molti utenti allo stesso tempo. Inoltre, quando qualche regione della cache invalida, viene ripopolata molte volte a causa della stessa ragione. Come posso evitare questo?
Sono riuscito a convert 1 entity and 1 query cache to a BlockingCache fornendo la mia implementazione a hibernate.cache.provider_class ma la semantica di BlockingCache non sembra funzionare. Ancora peggiori a volte i deadlock di BlockingCache (blocchi) e l'applicazione si blocca completamente. Il dump del thread mostra che l'elaborazione è bloccata sul mutex di BlockingCache su un'operazione get.
Quindi, la domanda è: Hibernate supporta questo tipo di utilizzo?
E se no, come risolvere questo problema sulla produzione?
Edit: Il hibernate.cache.provider_class punti al mio fornitore di cache personalizzato, che è un copia incolla da SingletonEhCacheProvider e alla fine del metodo start() (dopo la linea 136) che faccio:
Ehcache cache = manager.getEhcache("foo");
if (!(cache instanceof BlockingCache)) {
manager.replaceCacheWithDecoratedCache(cache, new BlockingCache(cache));
}
In questo modo, dopo l'inizializzazione, e prima che qualcun altro tocchi la cache denominata "foo", la decoro con BlockingCache. "foo" è una cache di query e "bar" (lo stesso codice ma omesso) è una cache di entità per un pojo.
Modifica 2: "Non sembra funzionare" significa che il problema iniziale esiste ancora. La cache "pippo" viene ancora reinserita molte volte con gli stessi dati, a causa della concorrenza. Convalido questo stressando il sito con JMeter con 10 thread. Mi aspetterei che i 9 thread blocchino fino a quando il primo che ha richiesto i dati da "foo" per finire il suo lavoro (eseguire query, memorizzare i dati nella cache), e quindi ottenere i dati direttamente dalla cache.
Modifica 3: Un'altra spiegazione di questo problema può essere vista allo https://forum.hibernate.org/viewtopic.php?f=1&t=964391&start=0 ma senza una risposta definita.
Uno sviluppo interessante che può aiutare a mitigare questo problema è che ora ehcache (dal 2.1) supporta la strategia di concorrenza della cache transazionale per la sospensione: http://stackoverflow.com/questions/3472613/does-ehcache-2-1-support -the-transactional-cache-concurrency-strategy-in-hibernat/3474011 # 3474011 – cherouvim