关于hibernate二级缓存与memcached学习的总结与咨询
为什么要将二级缓存同memcached结合起来,主要是考虑到web服务器集群条件下,当缓存更新时造成的各个集群的缓存更新性能问题。通过google提供的hibernate-memcached可以很好解决这个问题,而且可以通过其存放结构化数据如java对象(备注:稍微看过hibernate-memcached-1.2.2.jar的源码,其调用了开源包spymemcached.jar里面的方法,估计是将结构化数据通过一定的算法转为字符串存放到memcached,在取得时候,根据算法将字符串转化为结构化数据,目前的hibernate-memcached-1.2.2.jar与spymemcached2.8.4.jar的兼容性有问题,目前根据负责该开源包的项目经理提供的补丁已经解决)参考http://code.
最近我在研究hibernate,边学边做demo
实验结论如下:
1.一级缓存和二级缓存都是缓存实体对象,二级缓存只是生命周期大于一级缓存。(注意默认情况下query.list()只写不读)
2.二级缓存与查询缓存都是将数据写入memcached.(为什么要研究,主要看当web服务器的负载均衡策略为按照时间片轮训或加权轮训,使用查询缓存会不会取到数据?实验证实是可以取到数据的)
3.针对查询缓存:
3.1).当hql是查询对象时如“from User”,先将所有的实体对象存入二级缓存,key:className()+id value:实体对象。然后将sql条件存入查询缓存,key:sql ,value:实体对象的id组合。
当下次执行同样的sql语句时,根据sql到查询缓存拿到id组合,在逐个遍历id,根据id到二级缓存读取数据。
目前我手工将memcached的其中的1个实体对象删除或二级缓存的有效期<查询缓存,导致N+1 问题产生:即先可以拿到查询缓存,但是根据id取不到实体数据,会针对每个id到数据库进行sql查询。
不知道怎么设置二级缓存的有效期>查询缓存?请支招,查了半天资料,没有找到。
3.2)当hql是查询对象属性时“slect a.id from User a”,将所有的属性结果集存入查询缓存,key:sql value:属性结果集 ,当hql为多个表关联查询时,如果其中1个表进行了修改,那么查询缓存如何更新? 已经解决:google的hibernate-memcache已经提供了解决方案,根据时间戳缓存解决,即当其中1个表更新了数据,则将缓存搞成失效,下次到数据库查询。