缓存的目的就是为了提高响应速度,尤其是并发访问的速度,降低数据库服务器的压力,在同等硬件配置的情况下,提供更高的系统性能。
总的来说,请指导原则就是:尽量用低开销的计算代替高开销的计算。比如直接从数据库查询的开销要远高于内存中的计算返回,网络请求要远高于本地(同一VM中)请求。
如果单从这一点上来分析的话,现在很多关于Ehcache(local)与memcached(client/server)性能PK的讨论是可以比较简单的得出一个结论的。
(老实说,我对memcached的了解只是一知半解。不过国内比较知名的阿里巴巴的系统就是用的memcached,AliSoft有个哥们也在这方面有比较深的研究。详细请参见:http://blog.csdn.net/cenwenchu79)
下面图是国外一个哥们做的对比,按照Greg的测试,Ehcache的性能不memcached真的高很多,不过其试验的详细过程并没有资料,所以公证性也受到很多人的怀疑。
因为在Liferay框架中使用了Ehcache, 对这个缓存框架,我倒是做了一些research, 下面简单的罗列一下Ehcache在分布式缓存方面的知识点。
Ehcache的分布式缓存
——在分布式情况下,一个节点的缓存发生变动,需要通过广播通知其他节点。Ehcache有两种通知策略:copy和invalidate。一个是没有就拷贝过来,比较自然;另外一个是如果没有,那就反过来连自己也取消,这样就必须重新到数据库中查询,网络负载低。
——发现机制。也就是发现其他节点的机制,有两种,一种是利用RFC1112进行广播,好处是可以动态增减节点,另外一种是维护一个静态列表(IP)。
——传递机制。(Delivery Mechanism) 支持JMS, RMI, TCP, UDP, 广播,JXTA, JGroups。 缺省是RMI。
——复制的缺陷和Ehcache的解决办法
☆ 碎嘴的通讯协议(Chatty Protocal)
因为是一个网状拓扑,一个节点的每个变化需要通知其他N-1个其他节点,造成网络较大的负载。
可以通过批量异步操作来降低负载。加快对客户端的响应。
☆ 冗余的通知
发起通知的不应该收到并处理通知。(因为是广播,所以会收到)
可以通过为每个Cache创建一个GUID来标明身份,这样如果发起的Cache GUID与自身相同,则不用处理。
☆ 潜在的数据不一致
这是一个比较大的问题。只要是分布式存储,就一定会遇到这个问题。造成这个问题的原因有很多,比如对同一Cache的同一数据进行并行更新等;
解决的办法是通过:同步传递。客户端请求先处于挂起状态,在同步传递并在所有缓存中数据都同步之后再返回。
☆ 使缓存数据失效以实现更新(Update via Invalidate)
默认的方式是一个缓存的数据被更新之后,就将新数据复制给其他所有缓存。
另外的方式是,如果缓存数据被更新,则清除所有节点缓存中对应的数据,重新到数据库中查询。并重新加载到所有的节点缓存中。(Liferay就是采用了这种方式)
另外的一种保证数据一致的方式就是:设置TTL值(time to live), 到期之后重新从数据库中更新;
自己的一些设想
在研究关于分布式缓存的时候,我不由得想起来分布式数据库存储来。这两者有很多相似的地方,最核心的问题就是保持数据的一致性问题。
当前,在数据的分布式存储方面的解决方案已经有很多,很多产品、技术都很成熟,是否有一些东西可以借鉴在这里呢?比如说,内存数据库,数据库锁,消息中间件等等。
巧的是,上面那个做对比的哥们Greg就这个问题有不同的看法。
My point is that caches are not meant to have full database-like semantics. It is usually acceptable for the data to be dirty or stale to some extent. That extent depends on the app. |
确实,确保每个缓存中的数据完全的一致是不可能的,总会存在这样那样的问题,即使像memcached,也因为没有commit机制,可能出现一个node上先放入cache,而最后transaction回滚,但其他的cache node已经为其他用户提供了这个数据。
所以,分布式缓存还只能是具体问题具体分析了。
另外,简单地总结一下memcached的features如下:
1、请求由client端进行处理,client端维护着一个memcached服务器列表,根据用户的请求将响应指向不同的memcached服务器;(也就是说,每个缓冲值,在所有服务器中只保持着一份copy,不像ehcache每个服务器中都有)
2、memcached对CPU的要求不高,但对内存要求较高,因此可以与webapp server安装在一起,互补(web app server是CPU要求高,内存要求低)
3、可以动态地,甚至无限地增加memcached服务器的数量