2010-06-29 17 views
6

Actualmente estoy tratando de hibernar trabajando con el proveedor de almacenamiento en caché que viene con Hibernate.Hibernar El segundo nivel de almacenamiento en caché no parece funcionar

net.sf.ehcache.hibernate.SingletonEhCacheProvider 

que tienen un caché por defecto y una memoria caché de clase específica habilitada en el ecache.xml la que se hace referencia en mi archivo hibernate.cfg.xml. El caché específico del archivo clase/mapeo se define para manejar hasta 20000 objetos.

Sin embargo, no veo ganancias de rendimiento desde que activé la asignación de caché en uno de los archivos de asignación con los que estoy probando esto.

Mi prueba es la siguiente.

Cargue 10000 objetos del archivo de mapeo en particular im testing (esto debería golpear el DB y ser un cuello de botella). A continuación voy a cargar los mismos 10000 objetos, ya que en este punto esperaría que se golpeara la memoria caché y ver ganancias de rendimiento significativas. He intentado usar la asignación de caché "solo lectura" y "lectura-escritura" en el archivo xml de asignación de hibernación Estoy probando con.

Me pregunto qué es lo que tengo que hacer para asegurarme de que la memoria caché esté siendo procesada antes del DB al cargar objetos.

Observe como parte del análisis de prueba a través de estos 10000 registros usando algo similar a lo que se muestra a continuación (paginación de 1000 registros a la vez).

Criteria crit = HibernateUtil.getSession() .createCriteria(persistentClass); 
     crit.setFirstResult(startIndex); 
     crit.setFetchSize(fetchSize); 
     return crit.list(); 

visto que los criterios tiene un regulador de modo de almacenamiento en caché (setCacheMode()) Entonces, ¿hay algo que debería hacer con eso ??

noto con el siguiente código estadísticas que theres 10000 objetos (así hiberante onjects deshidratados Imagino ??) en la memoria pero por alguna razón estoy consiguiendo 0 hits y es más preocupante 0 pierde lo que parece que esto no va a la caché en absoluto cuando está haciendo una búsqueda a pesar de que el código de estadísticas parece estar diciéndome que hay 10000 objetos en la memoria.

¿Alguna idea de qué estoy haciendo worng? Considero que el hecho de que me equivoquen es bueno, ya que significa que se está utilizando el caché, pero no puedo entender por qué no recibo ningún golpe de caché. ¿Es por el hecho de que estoy usando setFirstResult() y setFetchSize() con criterios?

System.out.println("Cache Misses = " + stats.getSecondLevelCacheMissCount()); 
System.out.println("Cache Hits Count = " + stats.getSecondLevelCacheHitCount()); 

System.out.println("2nd level elements in mem "+ stats.getSecondLevelCacheStatistics("com.SomeTestEntity").getElementCountInMemory()); 

Respuesta

13

El segundo nivel de caché funciona para "buscar por clave principal". Para otras consultas, es necesario caché de la consulta (siempre que el caché de consultas está habilitada), en su caso utilizando Criteria#setCacheable(boolean):

Criteria crit = HibernateUtil.getSession().createCriteria(persistentClass); 
crit.setFirstResult(startIndex); 
crit.setFetchSize(fetchSize); 
crit.setCachable(true); // Enable caching of this query result 
return crit.list(); 

sugiero leer:


Si guardo en caché la consulta, son un ¿Hibernan las entidades de la consulta y luego están disponibles en la memoria caché de segundo nivel?

Sí lo harán.Esto se explica negro sobre blanco en el enlace que mencioné: "Tenga en cuenta que el caché de consultas no almacena en caché el estado de las entidades reales en el conjunto de resultados; almacena en caché solo valores de identificadores y resultados del tipo de valor. se usará junto con el caché de segundo nivel ". ¿Lo leíste?

Dado que tenía la impresión de que el uso de la caché de consultas era completamente diferente al uso de la memoria caché de segundo nivel de hibernación.

Es diferente (la "clave" utilizada para la (s) entrie (s) de caché es diferente). Pero las cachés de consulta se basan en la memoria caché L2.

De su respuesta parece que está sugiriendo que la memoria caché de consulta y la memoria caché de segundo nivel son las mismas, y para generar aciertos de caché necesito usar "buscar por clave principal".

Solo digo que necesita almacenar en caché la consulta ya que no está "buscando por clave principal". No entiendo lo que no está claro. ¿Intentó llamar al setCacheable(true) en su consulta u objeto de criterio? Perdón por insistir pero, ¿has leído el enlace que publiqué?

+0

Por lo tanto, para borrar el segundo nivel de caché nunca se puede utilizar a menos que se utiliza con "buscar por clave principal"? Does the crit.list(); (si la memoria caché está habilitada para la entidad is), rellene la memoria caché de segundo nivel en el código de ejemplo? si lo hace, entonces solo puedo acceder al caché cuando utilizo el equivalente de hiberanet de "buscar por clave principal" ?? – John

+0

@John Como escribí en mi respuesta, debe almacenar en caché la consulta. Lo que no está claro con eso? –

+0

Todavía estoy un poco confundido. Si guardo en caché la consulta, ¿todas las entidades hiberante de la consulta están disponibles en la memoria caché de segundo nivel? Como tenía la impresión de que usar el caché de consultas era completamente diferente que usar el caché de segundo nivel de hibernación. A partir de su respuesta, parece sugerir que la memoria caché de consulta y la memoria caché de segundo nivel son las mismas, y para generar aciertos de caché, necesito usar la tecla "buscar por clave primaria". – John

Cuestiones relacionadas