在使用hibernate开发过程中,让我一直感到奇怪的是为什么缓存是如此的让人不顺心。对于update操作频繁的项目更是噩梦。这和我对缓存的理解有很大的出入。
我的想法有2点:
1、数据库是大海,缓存是池塘。如果我抓了4条鱼到池塘里面去,为什么我一直要做这么一件事情:把鱼抓到池塘里面过一段时间又放回大海,过一段时间又抓到池塘里面去。这样真傻。还有一个诡异的问题,鱼被抓到池塘里面了,大海里面的鱼是哪来的?
2、如果我要抓所有的鲶鱼,难道我只去池塘抓?如果我怎么才能知道池塘的鱼是不是就是所有的鲶鱼了,这个时候必须去大海里面再捞一捞。必须去大海里面一次又一次的捞?要池塘又是干嘛的?
freyja的做法:
1、在freyja里面鱼只有一条,要么在池塘要么在海里面。freyja用hashMap来管理缓存(ehcache)
2、get方式获取到的都是优先缓存内的值,取不到才会去发送sql并且放入cache中。
find()方法会发送sql去查找id,然后遍历缓存,如果缓存中存在者返回缓存中的值,否则取数据库中的。
executeUpdate()方法会直接update数据库,并且会select id 找出涉及到的表的id然后用el工具更新缓存中的值。来维护缓存。
将要实现的cache能力:
3、第一次发送sql会查询出一个记录集,第二次发送sql着直接取缓存中的内容。难点是,如果其中一条记录的条件变化,如何完成这个处理?我的想法是一条记录保存所有缓存他得key,一旦update操作则让其缓存失效(这个是简单做法,复杂做法是根据条件再次判断是否让缓存失效。)
4、(这是我最喜欢的一个功能)no update。
这个功能的特点就是在update(user)的时候不会去发送sql update数据库。也就是第一点所说的,鱼在池塘就不去理会大海。这个功能的思路大概有了,正在施工中。但是工作量很大,而且效率怎么样不得而之。总之,这是自寻死路。
对于现在的freyja来说不支持分布式,也许以后会去考虑,一旦支持了分布式那么我的第一个理念就有出入了。
其实还有最大的一个问题:事务
http://freyja.iteye.com/blog/1178182
事务的特性就是为了让一个人不要在看书的时候听音乐。因为同时做2件事的时候容易出问题。事务还是很有存在的必要的,但是freyja的结构让事务失去了作用。只有一个对象的freyja可以在事物里面的数据被事物外的数据修改。
freyja对事物的处理是,在get()实体的时候根据事物的id为key把结果集放入一个map作为副本,在出错的时候”回滚“,事物结束的时候remove key。这部分还在完善中。
在简单的测试中,hibernate一级缓存情况下的select update 操作freyja和hibernate效率相当。(因为freyja本身就是一个大的一级缓存)。但是到了重要的二级缓存里面hibernate和freyja没有可比性了。
如这么一个测试:@Test
public void testFind() {
long l1 = System.currentTimeMillis();
for (int i = 0; i < 2000; i++) {
userService.testFind();
}
long l2 = System.currentTimeMillis();
System.out.println("freyja find() 5000个对象耗时:" + (l2 - l1) / 1000);
}
public void testFind() {
for (int i = 0; i < 10; i++) {
List<User> list = baseDAO.find(User.class, "level < ?", i);
}
}
模拟二级缓存环境,数据源用的是同一个,hibernate的二级缓存开启查询缓存关闭(难道开启会好点?)
hibernate find() 5000个对象耗时:11 (500*10)
hibernate find() 5000个对象耗时:20 (1000*10)
hibernate find() 5000个对象耗时:40 (2000*10)
freyja find() 5000个对象耗时:7 (500*10)
freyja find() 5000个对象耗时:13 (1000*10)
freyja find() 5000个对象耗时:25 (2000*10)
分别是2000调用、1000次调用和500次调用。User表里面有5000条记录,level为1-5000;
这个差距大概体现在hibernate每次从缓存中提取结果需要序列化的原因。
还是等完全施工完毕再全面的系统测试一次比较好。
那个时候hibernate有它的一套完备的体系,freyja则有自己的原生sql+cache支持。
分享到:
相关推荐
Maven坐标:javax.cache:cache-api:1.1.1; 标签:javax、cache、api、中文文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码和...
Lab #8: Cache
Maven坐标:javax.cache:cache-api:1.1.1; 标签:javax、cache、api、中英对照文档、jar包、java; 使用方法:解压翻译后的API文档,用浏览器打开“index.html”文件,即可纵览文档内容。 人性化翻译,文档中的代码...
计算机系统结构:模拟实验三:Cache性能分析.ppt
详细介绍存储器系统,包括cache,dram以及磁盘。英文版
存储器系统(Memory Systems:Cache.DRAM.Disk)[英文版].pdf
3) 改变Cache容量(*2,*4,*8,*64),运行程序(指明所选的测试程序),统计各种失效的次数,并分析Cache容量对Cache性能的影响; 4) 改变Cache的相联度(1路,2路,4路,8路,64路),运行程序(指明所选的测试...
存储系统――缓存.DRAM.磁盘.(Memory.Systems-Cache.DRAM.Disk).Bruce.Jacob pdf文档)
File::Cache 是一个 perl 模块,它允许通过文件系统跨进程共享对象数据。 现在不鼓励使用 File::Cache,而是支持 http://sourceforge.net/projects/perl-cache/ 上的新 Cache::Cache 项目。
Memory Systems: Cache, DRAM, Disk is the fi rst book that takes on the whole hierarchy in a way that is consistent, covers the complete memory hierarchy, and treats each aspect in signifi cant detail....
等待事件row cache lock,latch row cache objects处理过程
CacheDB
实验五: 虚拟Cache与伪相联Cache 及实验过程。
[Ruby_on_Rails][中文][Rails_5.x]__12._Assets___Cache介紹與圖片標籤image_t
cache-jdbc
一、硬件知识 1、计算机系统的组成包括硬件系统和软件系统 ...Cache的基本结构:Cache由存储体、地址映像和替换机构组成。 4、通道是一种通过执行通道程序管理I/O操作的控制器,它使CPU与I/O操作达到更高的并行度。
。。。
postgres_cache_store:Cache :: Store实现由数据库通过crystal-pg支持
Laravel开发-laravel-image-cache 想象中的Laravel图像缓存
Redis Store为现代Ruby框架提供了全套存储( Cache , I18n , Session , HTTP Cache ),例如: Ruby on Rails , Sinatra , Rack , Rack :: Cache和I18n 。 它支持对象编组,超时,单个或多个节点以及名称空间...