两级缓存框架 J2Cache 的简单实验
今天对 J2Cache 做了最基本的测试,代码已经开放出来,地址是 http://git.oschina.net/ld/J2Cache
补充为什么要做这个框架:
说实话,OSC 现在还是单个 Tomcat,只不过我们做了一些分流措施将爬虫的请求独立运行了。我一直跟人说 OSC 的扩展很容易,只需要加多几个 Tomcat 就搞定了。如果是纯浏览的网站的确是这样的,但事实上并非如此。要让应用工作在集群里,首先 OSC 没用到 session ,这点是满足要求的。但是 OSC 目前使用 Ehcache 作为缓存框架,这是一个进程内的缓存框架,如果集群的话会导致缓存数据不同步。
缓存数据不同步有两个解决办法:
1. 集中式缓存,直接将 Ehcache 换成 Redis 这类产品。如果访问量不大是没问题,访问量大,大量的缓存数据访问使得应用服务器和缓存服务器之间的网络I/O成为瓶颈,这点我有切身之痛。
2. Ehcache 的分布式(我以前专门写过一篇文章),节点间大量的数据复制带来额外的开销,在节点多的情况下此问题越发严重
因此才有了今天的 J2Cache,引入集中式缓存 Redis ,通过进程内的 Ehcache 缓存来缓解网络 I/O 瓶颈。同时也降低集中式缓存服务器的压力。
要对该框架做实验很简单,需要下面几步:
1. 安装个Redis 服务器
2. 从 http://git.oschina.net/ld/J2Cache 上获取整个项目源码
3. 修改 src/redis.properties 文件中的 host 和 port 项,值为你的 Redis 服务器的 IP 和 Redis 端口号
4. 执行 build.sh(bat) 命令进行编译
5. 也可直接在 Eclipse 中导入该项目并按第 3 步修改 src/redis.properties 配置
6. 打开控制台窗口,执行 runtest.sh(bat) 启动测试客户端
在我机器上执行第 6 步的结果如下:
7. 打开另外一个终端窗口,重复执行第 6 步
你要愿意的话,可以打开很多个终端窗口来启动一个测试的客户端。
接下来就可以对这个缓存框架进行测试,测试的命令包括 get/set/evict/quit,这几个命令的介绍如下:
set <region> <key> <value> 写入缓存数据 key=value 到 region 区域,例:
> set cache1 key1 oschina.net Jan 07, 2014 4:16:15 PM net.oschina.j2cache.ehcache.EhCacheProvider buildCache 警告: Could not find configuration [cache1]; using defaults. [cache1,key1]<=oschina.net
述输出提示中,已将字符串 oschina.net 写入到 cache1 的 key1 键中。
get <region> <key> 从区域<region>读取键为<key>的缓存数据,例:
> get cache1 key1 [cache1,key1,L1]=>oschina.net
上述命令执行结果显示从 cache1 中读取 key1 的值为 oschina.net,数据存放于 L1,也就是一级缓存 Ehcache 中。
这时候可以在其他的终端上再次执行 get 命令,结果就变成:
> get cache1 key1 Jan 07, 2014 4:19:14 PM net.oschina.j2cache.ehcache.EhCacheProvider buildCache 警告: Could not find configuration [cache1]; using defaults. [cache1,key1,L2]=>oschina.net
上述的 L2 表示数据来自于二级缓存 Redis,说明第二个测试客户端直接从 Redis 获取到数据。再次执行 get 命令 L2 就变成 L1,说明数据已经在一级缓存 Ehcache 中存在。
最后你也可以手工的清除某个缓存:
> evict cache1 key1 [cache1,key1]=>null
而你将在其他的测试客户端上看到如下输出信息:
Jan 07, 2014 4:22:55 PM net.oschina.j2cache.CacheChannel onDeleteCacheKey 信息: Received cache evict message, region=cache1,key=key1
要退出测试客户端,输入 quit 即可。
另外当 Ehcache 中的某个缓存数据应该时间长失效后,也会自动广播到组里所有节点,通知其清除缓存。
说明一下,Ehcache 本身是支持集群的,但如果缓存更新频繁的话,节点间传输的数据量也会很大。J2Cache 的节点间只传输 evict 命令,例如 A 节点通知 B 节点清除某个缓存数据,因此只需要传递 region 和 key 信息即可。