缓存: Memcached和terracotta

缓存是最重要的一个方面,以提高应用程序性能的存储对象的缓存(内存)减少数据库负载。

缓存在群集环境中,需要分布式缓存解决方案,可以支持故障切换情景和数据的可靠性。 Memcached和terracotta兵马俑的分布式缓存解决方案。

Memcached是一个高性能的分布式对象缓存系统, 客户端的API为的Perl , PHP中,python, Ruby和Java语言。 以下是一些其能力和局限性(使用Java客户端API ) :

要求对象是可序列化
对象标识是不保留
支持高速缓存到期
不处理故障情景
对于一个特定对象选择一个服务器从池缓存服务器基于Hash的关键
容易配置(通过SockIOPool级)

terracotta秦始皇是一个开源基于Java的JVM集群解决方案。 分布式缓存可以实现使用兵马俑terracotta使用java.util.HashMap或开放源码的缓存解决方案,如EHCache , OSCache和JBoss TreeCache 。

保护对象的身份
通过有效地管理虚拟内存堆
声明要求锁定支持
简单的配置文件与Eclipse工具支持
良好的文件,支持和积极发展
不需要类是可序列化
容易配置并开始!


有一个老外网友使用terracotta后(见下面连接),发现CPU高负荷和GC时间暂停导致的应用响应时间延迟是其关键问题。而是要Memcached后,虽然 get/set有些慢(远程),但是相对数据库操作,memcached和ehcache差别可以忽略。

最后,他提出:可以使用ehcache作为本地in-process缓存,而memcached作为远程缓存。(对象状态第一次访问memcached获取后,缓存在本地ehcache中,以后就无需访问远程memcached,这样方案比较优化)。

兵马俑公司首席技术官阿里Zilka 认为:Memcached是因为使用非Java编写,所以没有GC,但他认为Memcached存在下面问题:
1. memcache分区是非常静态的(除非你改变它,或自定义) 。 这可能是一个大问题,因为您的网站成长 、
2. memcache分区会丢失数据。 如果您重新启动memcache服务器,数据丢失 。

http://hankliblog.blogspot.com/2008/01/bye-bye-terracotta-other-java-caches.html

当然,terracotta或ehcache可以通过JVM参数微调来实现响应时间延迟和高吞吐量的平衡。见twitter的JVM性能优化

关于ehcache vs. memcached的2011年9月一文的最新讨论,主要是从memcached分布式缓存与ehcache代表数据网格之间区别方面讨论:
http://www.infoq.com/news/2011/09/java-memcached-rise
[该贴被admin于2011-11-25 07:52修改过]

memcached是一个非常简单的解决方案,分布式数据缓存。它提供了一个地图一样的API ,而不是基于Java (尽管它有一个的Java API ) 。 因此,它会永远需要您的Java代码能够与一个单独的进程( memcached守护程序) 。

GigaSpaces和兵马俑都是纯Java的解决方案,提供的,远远不止缓存,虽然采取了不同的办法了。

Terracotta 是在JVM级别集群你的应用,可以只花一点点代码变化就能将应用运行在多个JVM上。这样你能得到分布式缓存(Terracotta guys call it Network Attached Memory) 和分布式进程. 这种方式很干净。

GigaSpaces产品为您提供全面的运行平台,实施高度可扩展的分布式应用。这样的做法是制定您的应用程序上的一个可扩展的平台从第1天,而不是集群它特设更多的可扩展性。
该产品集成了非常丰富的分布式缓存执行,信息功能和独特的SLA驱动,自我愈合的部署平台,让您的企业应用都需要加以电网启用。
http://www.gigaspaces.com/os_downloads.html.

有人做过测试,如果目标是20K tps, TC兵马俑之需要32 服务器而竞争对手的缓存需要160台服务器. (This is my recollection, at least)
http://forum.springsource.org/showpost.php?s=4473cedb3ff6bb0ac39b624b04ac5922&p=168447&postcount=10

Memcached属于一种集中式的分布式结构,当某一台服务器宕掉以后,宕掉的这台服务器缓存内容就丢失。Terractto不知道是怎么做的?缓存内容在多个JVM中重复保存?还是配对复制,还是其它的?

terracotta采取的是内存矩阵,通过对JVM的Heap进行复制实现共享,可以认为是一种分布式JVM,不存在单点风险,是真正的集群式的分布式缓存,常用于云计算之中。

唯一所谓缺点就是用Java编制,但这也不是缺点,你做一个Java接口就可以,因为memcached面向应用也是一个接口。

昨天一篇文章:FACEBOOK'S MEMCACHED MULTIGET HOLE: MORE MACHINES != MORE CAPACITY
提出:Facebook在2008年已经有超过800台memcached服务器,他们已经发现了memcached存在的一些问题,他们称为Multiget Hole。

出乎意料之外的是,增加memcached服务器并不能增加处理容量。这就象在一个洞里,通过简单增加服务器并不能把你挖出来。

解决multiget hole一个方式就是复制,因为本质是缺少CPU处理能力,需要更多CPU来处理,创造两组服务器,每组有两个memcached,前面再加一个负载平衡器,每个服务器只能得到一半的请求,这样就只做一半工作。
[该贴被banq于2009-10-27 09:39修改过]

CTO Ari Zilka Says Terracotta is Fast

Ari Zilka, the CTO of Terracotta, 自己宣布在和市场上 Memcache, JBoss cache, 和来自大型公司比如 Oracle 和 IBM比较和,Terracotta的性能是最好的。他说:比他们每一个都提高3到10倍速度,如果使用3.2版本则大概比当前Terracotta要快4倍。

这个测试是基于Spring PetClinic 应用做出的,但是好像没有看到准确测试报告,Java领域最好单机缓存EHCache被Terracotta收购后,将于1.7版本推出整合了Terracotta的分布式缓存。

感觉还是memcached比较成熟一点,
因为是用C写的,所以效率也比java高不少。而且提供的java api调用起来也非常容易。

2009年10月27日 09:22 "banq"的内容
解决multiget hole一个方式就是复制,因为本质是缺少CPU处理能力,需要更多CPU来处理,创造两组服务器,每组有两个memcached,前面再加一个负载平衡器,每个服务器只能得到一半的请求,这样就只做一半工作。

系统中的操作一般分为2中:IO 密集型和CPU密集型,采用Cache可以大大的提高IO密集型操作的效率,对于CPU密集型的操作,又可以采用多种方式来提升性能,比如传统的垂直伸缩性,以及map-reduce,通过便宜的机器,将计算分发到不同的机器上计算等等。总之,我觉得在架构和设计系统的时候,一定要分清楚,那些事IO密集型的,那些是CPU密集型,划分清楚以后,采用不同的策略来点对点解决,精确制导效果才好嘛呵呵。

请问一下bang大哥,象Memcached和terracotta这种大型的缓存服务器 我们在开发程序的时候对缓存的更新的策略应该是怎么样的啊

2010年01月12日 15:32 "cmzx3444"的内容
象Memcached和terracotta这种大型的缓存服务器 我们在开发程序的时候对缓存的更新的策略应该是怎么样的啊

采取CQRS命令和查询分离策略,Memcached和terracotta在读query架构中,当有命令command进来改变模型状态时,发出事件通过事件总线更新读架构中缓存。

如果你无法进行清晰的读写分离,直接使用Key-value存储,因为象Tokyo Cabinet 和Tyrant 这些产品,内部已经考虑了如何进行分布式环境一致性更新的问题,不用应用者考虑,很方便。

这个对我来说有点高深,我想知道的是 缓存服务器里是不是主要存着聚合根,而我们查询的时候就根据Id去找那个聚合根?

2010年01月12日 15:55 "cmzx3444"的内容
是 缓存服务器里是不是主要存着聚合根,而我们查询的时候就根据Id去找那个聚合根

是的,保存的是聚合根,根据ID找那个聚合根实体对象即可。

因为是聚合根,必然聚合了很多其他子对象,不能将整个聚合对象群都在分布式服务器之间拷贝,这和关系数据库带有关系数据复制就类似了,效率差,terracotta的更新策略就比较智能,而memcache则没有提供智能更新策略,它的使用策略是,将数据库数据都装进来,反正没有资源限制。

Memcached使用上主要考虑如下问题:
1、脏数据更新,几乎所有应用了缓存的场合都需要考虑这个问题
2、down掉一台机后,命中率问题

1的话各有各的解决办法,2尽量采用圆周算法

2010年01月21日 10:52 "itworker"的内容
圆周算法

是的,就是Hash算法,有一致Hash等几个,减小影响面,但肯定不能失败恢复的,但是对于只读影响也没关系。