转载自http://www.csdn.net/article/2010-11-29/282698
我的团队近来正在忙于一个全新的产品——即将发布的网络游戏www.FightMyMonster.com。这让我们得以奢侈地去构建一个全新的NOSQL数据库,也就是说,我们可以把恐怖的MySQL sharding和昂贵的可伸缩性抛在脑后了。最近有很多人一直在问,为什么我们要把注意力从HBase上转移到Cassandra上去。我确认,确实有这样的变化,实际上我们基本上已经把代码移植到了Cassandra上了,这里我将给出解释。
为了那些不熟悉NOSQL的读者,后面的其他文章中,我会介绍为什么我们将会在未来几年中看到地震式的从SQL到NOSQL的迁移,这正和向云计算的迁移一样重要。后面的文章还会尝试解释为什么我认为NOSQL可能会是贵公司的正确选择。不过本文我只是解释我们选择Cassandra作为我们的NOSQL解决方案的选择。
免责声明——如果你正在寻找一个捷径来决定你的系统选择,你必须要明白,这可不是一个详尽而严格的比较,它只是概述了另一个初创团队在有限时间和资源的情况下的逻辑。
Cassandra的血统是否预言了它的未来
我最喜欢的一个工程师们用来找bug的谒语是“广度优先而非深度优先”。这可以可能对那些解决技术细节的人来说很恼人,因为它暗示着如果他们只是看看的话,解决方法就会简单很多(忠告:只对那些能够原谅你的同事说这个)。我造出这个谒语的原因在于,我发现,软件问题中,如果我们强迫我们自己在进入某行代码的细节层面之前,先去看看那些高层次的考虑的话,可以节省大量时间。
所以,在谈论技术之前,我在做HBase和Cassandra之间的选择问题上先应用一下我的箴言。我们选择切换的技术结论可能已经可以预测了:Hbase和Cassandra有着迥异的血统和基因,而我认为这会影响到他们对我们的业务的适用性。
严格的说,Hbase 和它的支持系统源于著名的Google BigTable和Google文件系统设计(GFS的论文发于2003年,BigTable的论文发于2006年)。而 Cassandra 则是最近Facebook的数据库系统的开源分支,她在实现了BigTable的数据模型的同时,使用了基于Amazon的Dynamo的系统架构来存储数据(实际上,Cassandra的最初开发工作就是由两位从Amazon跳槽到Facebook的Dynamo工程师完成的)。
在我看来,这些不同的历史也导致Hbase更加适合于数据仓库、大型数据的处理和分析(如进行Web页面的索引等),而Cassandra则更适合于实时事务处理和提供交互型数据。要进行系统研究来证明这个观点超出了本文的范畴,但我相信你在考虑数据库的时候总能发现这个差异的存在。
注意:如果你在寻找一个简单的证明,你可以通过主要committer的关注点来进行验证:大部分HBase的committer都为Bing工作(M$去年收购了他们的搜索公司,并允许他们在数月之后继续提交开源代码)。与之对应,Cassandra的主要committer来自Rackspace,用来可以自由获得的支持先进的通用的NOSQL的解决方案,用来和Google, Yahoo, Amazon EC2等提供的那些锁定在专有的NOSQL系统的方案相抗衡。
Malcolm Gladwell会说只是根据这些背景的不同就可以简单地选择了Cassandra。不过这是小马过河的问题。但当然,闭着眼睛就进行一个商业选择是相当困难的......
哪个 NOSQL数据库风头更劲?
另一个说服我们转向Cassandra的原因是我们社区中的大风向。如你所知,软件平台行业里,大者恒大——那些被普遍看好的平台,会有更多人聚集在这个平台周围,于是,从长远看,你可以得到更好的生态系统的支持(也就是说,大部分支持的软件可以从社区中获得,也有更多的开发者可以雇佣)。
如果从HBase开始时,我的印象就是它后面有巨大的社区力量,但我现在相信,Cassandra更加强大。最初的印象部分来源于StumpleUpon和Streamy的两位CTO的两个非常有说服力的出色的讲演,他们是Web行业中两个在Cassandra成为一个可选系统之前的HBase的两个重要的贡献者,同时也部分来源于快速阅读了一篇名为“HBase vs Cassandra:NoSQL战役!”的文章(大部分内容都被广泛证实了)。
势头是很难确证的,你不得不自己进行研究,不过我可以找到的一个重要的标志是IRC上的开发者动向。如果你在 freenode.org 上比较#hbase和#cassandra的开发这频道,你会发现Cassandra差不多在任何时候都有两倍的开发者在线。
如果你用考虑HBase一般的时间来考察Cassandra,你就能发现Cassandra的背后确实有非常明显的加速势头。你可能还会发现那些逐渐出现的鼎鼎大名,如 Twitter,他们也计划广泛使用Cassandra(这里)。
注:Cassandra的网站看起来比HBase的好看多了,但认真的说,这可能不仅是市场的趋势。继续吧。
深入到技术部分:CAP和CA与AP的神话
对于分布式系统,有个非常重要的理论(这里我们在讨论分布式数据库,我相信你注意到了)。这个理论被称为CAP理论,由Inktomi的联合创始人兼首席科学家Eric Brewer博士提出。
这个理论说明,分布式(或共享数据)系统的设计中,至多只能够提供三个重要特性中的两个——一致性、可用性和容忍网络分区。简单的说,一致性指如果一个人向数据库写了一个值,那么其他用户能够立刻读取这个值,可用性意味着如果一些节点失效了,集群中的分布式系统仍然能继续工作,而容忍分区意味着,如果节点被分割成两组无法互相通信的节点,系统仍然能够继续工作。
Brewer教授是一个杰出的人物,许多开发者,包括HBase社区的很多人,都把此理论牢记在心,并用于他们的设计当中。事实上,如果你搜索线上的关于HBase和Cassandra比较的文章,你通常会发现,HBase社区解释他们选择了CP,而Cassandra选择了AP——毫无疑问,大多数开发者需要某种程度的一致性(C)。
不过,我需要请你注意,事实上这些生命基于一个不完全的推论。CAP理论仅仅适用于一个分布式算法(我希望Brewer教授可以统一)。但没有说明你不能设计一个系统,在其中的各种操作的底层算法选择上进行这种。所以,在一个系统中,确实一个操作职能提供这些特性中的两个,但被忽视的问题是在系统设计中,实际是可以允许调用者来选择他们的某个操作时需要哪些特性的。不仅如此,现实世界并不简单的划分为黑白两色,所有这些特性都可以以某种程度来提供。这就是Cassandra。
这点非常重要,我重申:Cassandra的优点在于你可以根据具体情况来选择一个最佳的折衷,来满足特定操作的需求。Cassandra证明,你可以超越通常的CAP理论的解读,而世界仍然在转动。
我们来看看两种不同的极端。比如我必须从数据库中读取一个要求具有很高一致性的值,也就是说,我必须100%保证能够读取到先前写入的最新的内容。在这种情况下,我可以通过指定一致性水平为“ALL”来从Cassandra读取数据,这时要求所有节点都有数据的一致的副本。这里我们不具有对任何节点失效和网络分裂的容错性。在另一个极端的方面,如果我不特别关心一致性,或仅仅就是希望最佳性能,我可以使用一致性级别“ONE”来访问数据。在这种情况下,从任意一个保存有这个副本的节点获取数据都可以——即使数据有三个副本,也并不在意其他两个有副本的节点是否失效或是否有不同,当然,这种情况下我们读到的数据可能不是最新的。
不仅如此,你不必被迫生活在黑白世界中。比如,在我们的一个特定的应用中,重要的读写操作通常使用“QUORUM”一致性级别,这意味着大部分存有此数据的节点上的副本是一致的——我这里是个简要描述,具体写你的Cassandra程序之前最好还是仔细研究一下。从我们的视角看,这这提供了一个合理的节点失效与网络分裂的耐受性,同时也提供了很高的一致性。而在一般情况下,我们使用前面提到的“ONE”一致性级别,者可以提供最高的性能。就是这样。
对我们来说,这是Cassandra的一个巨大的加分项目。我们不仅能轻易地调整我们的系统,也可以设计它。比如,当一定数量的节点失效或出现网络连接故障时,我们的大部分服务仍然可以继续工作,只有那些需要数据一致性的服务会失效。HBase并没有这么灵活,它单纯地追求系统的一个方面(CP),这让我再次看到了SQL开发者和查询优化人员们之间的那道隔阂——有些事情最好能够超越它,HBase!
In our project then, Cassandra has proven by far the most flexible system, although you may find your brain at first loses consistency when considering your QUORUMs.在我们的项目之后,卡桑德拉已被证明是迄今为止最灵活的系统,虽然你可能发现一致性第一失去你的大脑在考虑您的法定人数。
在我们的项目中,Cassandra 已经证明了它是有史以来最灵活的系统,虽然你可能在对这个问题进行投票(QUORUM)的时候发现的大脑失去了一致性。
什么时候单体会比模块化强?
Cassandra和HBase的一个重要区别是,Cassandra 在每个节点是是一个单Java进程,而完整的HBase解决方案却由不同部分组成:有数据库进程本身,它可能会运行在多个模式;一个配置好的Hadoop HDFS分布式文件系统,以及一个Zookeeper系统来协调不同的HBase进程。那么,这是否意味着HBase有更好的模块化结构呢?
虽然 HBase的这种架构可能确实可以平衡不同开发团队的利益,在系统管理方面,模块化的HBase却无法视为一个加分项目。事实上,特别是对于一些小的初创公司,模块化倒是一个很大的负面因素。
HBase的下层相当复杂,任何对此有疑惑的人应该读读Google的GFS和BigTable的论文。即使是在一个单一节点的伪分布式模式下来架设HBase也很困难——事实上,我曾经费力写过一篇快速入门的教程(如果你要试试HBase的话看看这里)。在这个指南里你可以看到,设置好HBase并启动它实际包含了两个不同系统的手工设置:首先是Hadoop HDFS,然后才是HBase本身。
然后,HBase的配置文件本身就是个怪兽,而你的设置可能和缺省的网络配置有极大的不同(在文章里我写了两个不同的Ubuntu的缺省网络设置,以及EC2 里易变的Elastic IP和内部分配的域名)。当系统工作不正常的时候,你需要查看大量的日志。所有的需要修复的东西的信息都在日志里,而如果你是一个经验丰富的管理员的话,就能发现并处理问题。
但是,如果是在生产过程中出现问题,而你又没有时间耐心查找问题呢?如果你和我们一样,只有一个小的开发团队却有远大的目标,没有经历去7*24的进行系统监控管理会怎么样呢?
严肃地说,如果你是一个希望学习NoSQL系统的高级DB管理员的话,那么选择HBase。这个系统超级复杂,有灵巧双手的管理员肯定能拿到高薪。
但是如果你们是一个向我们一样尽力去发现隧道尽头的小团队的话,还是等着听听别的闲话吧
胜在 Gossip!
Cassandra是一个完全对称的系统。也就是说,没有主节点或像HBase里的region server这样的东西——每个节点的角色是完全一样的。不会有任何特定的节点或其他实体来充当协调者的角色,集群中的节点使用称为“Cossip”的纯P2P通信协议来协调他们的行为。
对Gossip的详细描述和使用Gossip的模型超过了本文的内容,但Cassandra所采用的P2P通信模型都是论证过的,比如发现节点失效的消息传播到整个系统的时间,或是一个客户应用的请求被路由到保存数据的节点的时间,所有这些过程所消耗的时间都毫无疑问的非常的短。我个人相信,Cassandra代表了当今最振奋的一种P2P技术,当然,这和你的NOSQL数据库的选择无关。
那么,这个基于Gossip的架构究竟给Cassandra用户带来什么显示的好处呢。首先,继续我们的系统管理主体,系统管理变得简单多了。比如,增加一个新节点到系统中就是启动一个Cassandra进程并告诉它一个种子节点(一个已知的在集群中的节点)这么简单。试想当你的分布式集群可能运行在上百个节点的规模上的时候,如此轻易地增加新节点简直是难以置信。更进一步,当有什么出错的时候,你不需要考虑是哪种节点出了问题——所有节点都是一样的,这让调试成为了一个更加易于进行且可重复的过程。
第二,我可以得出结论,Cassandra的P2P架构给了它更好的性能和可用性。这样的系统中,负载可以被均衡地三步倒各个节点上,来最大化潜在的并行性,这个能力让系统面临网络分裂和节点失效的时候都能更加的无缝,并且节点的对称性防止了HBase中发现的那种在节点加入和删除时的暂时性的性能都懂(Cassandra 启动非常迅速,并且性能可以随着节点的加入而平滑扩展)。
如果你想寻找更多更多的证据,你会对一个原来一直关注Hadoop的小组(应该对 HBase 更加偏爱)的报告很感兴趣......
一份报告胜过千言万语。我是指图表
Yahoo!进行的第一个NOSQL系统的完整评测。研究似乎证实了Cassandra所享有的性能优势,从图表上看,非常倾向于Cassandra。
目前这些论文还是草稿,你可以从这里找到这些论文:
http://www.brianfrankcooper.net/pubs/ycsb-v4.pdf
http://www.brianfrankcooper.net/pubs/ycsb.pdf
注意:这份报告中HBase仅在对一个范围的记录进行扫描这一项上优于Cassandra。虽然Cassandra团队相信他们可以很快达到HBase的时间,但还是值得指出,在通常的Cassandra配置中,区间扫描几乎是不可能的。我建议你可以无视这一点,因为实际上你应该在Cassandra上面来实现你自己的索引,而非使用区间扫描。如果你对区间扫描和在Cassandra中存储索引相关问题有兴趣,可以看我的这篇文章。
最后一点:这篇文章背后的Yahoo!研究团队正尝试让它们的评测应用通过法律部门的评估,并将它发布给社区。如果他们成功的话,我当然希望他们成功,我们将能够看到一个持续的竞争场面,不论HBase还是Cassandra无疑都会进一步提高他们的性能。
锁和有用的模块性
毫无疑问,你会从HBase阵营听到这样的声音:HBase的复杂结构让它可以提供Cassandra的P2P架构无法提供的东西。其中一个例子可能就是Hbase提供给开发者行锁机制,而Cassandra则没有(在HBase中,因为数据副本发生在hadoop底层,行锁可以由region server控制,而在Cassandra的P2P架构中,所有节点都是平等的,所以也就没有节点可以像一个网管囊样负责锁定有副本的数据)。
不够,我还是把这个问题返回到关于模块化的争论中,这实际是对Cassandra有理的。Cassandra通过在对称节点上分布式存储数据来实现了BigTable的数据模型。它完整地实现了这些功能,而且是以最灵活和高性能的方式实现的。但如果你需要锁、事务和其它功能的话,这些可以以模块的方式添加到你的系统之中——比如,我们发现我们可以使用Zookeeper和相关的工具来很简单地为我们的应用提供可扩展的锁功能(对于这个功能,Hazelcast等系统可能也可以实现这个功能,虽然我们没有进行研究)。
通过为一个窄领域目的来最小化它的功能,对我来说,Cassandra的设计达到了它的目的——比如前面指出可配置的CAP的折衷。这种模块性意味着你可以依据你的需求来构建一个系统——需要锁,那么拿来Zookeeper,需要存储全文索引,拿来Lucandra ,等等。对于我们这样的开发者来说,这意味着我们不必部署复杂度超出我们实际需要的系统,给我们提供了更加灵活的构建我们需要的应用的终极道路。
MapReduce,别提MapReduce!
Cassandra做的还不够好的一件事情就是MapReduce!对于不精通此项技术同学简单的解释一句,这是一个用于并行处理大量数据的系统,比如从上百万从网络上抓取的页面提取统计信息。MapReduce和相关系统,比如Pig和Hive可以和HBase一起良好协作,因为它使用HDFS来存储数据,这些系统也是设计用来使用HDFS的。如果你需要进行这样的数据处理和分析的话,HBase可能是你目前的最佳选择。
记住,这就像小马过河!
因此,我停止了对Cassandra的优点的赞美,实际上,HBase和Cassandra并不一定是一对完全的竞争对手。虽然它们常常可以用于同样的用途,和MySQL和PostgreSQL类似,我相信在将来它们将会成为不同应用的首选解决方案。比如,据我所知StumbleUpon使用了HBase和hadoop MapReduce技术,来处理其业务的大量数据。Twitter现在使用Cassandra来存储实时交互的社区发言,可能你已经在某种程度上使用它了。
作为一个有争议的临别赠言,下面我们进入下一个话题。
注意:在继续下一个小节之前,我要指出,Cassandra在0.6 版本会有hadoop支持,所以MapReduce 整合能获得更好的支持。
兄弟,我不能失去数据......
作为先前CAP理论争议的一个可能结果,可能有这样的印象,HBase的数据似乎比Cassandra中的数据更安全。这是我希望揭露的最后一个关于Cassandra的秘密,当你写入新数据的时候,它实际上立刻将它写入一个将要存储副本的仲裁节点的commit log当中了,也被复制到了节点们的内存中。这意味着如果你完全让你的集群掉电,只可能会损失极少数据。更进一步,在系统中,通过使用Merkle tree来组织数据的过分不一致(数据熵),更加增加了数据的安全性
事实上,我对HBase的情况并不是非常确切——如果能有更细节的情况,我回尽快更新这里的内容的——但现在我的理解是,因为hadoop还不支持append,HBase不能有效地将修改的块信息刷入HDFS (新的对数据变化会被复制为多个副本并永久化保存)。这意味着会有一个更大的缺口,你最新的更改是不可见的(如果我错了,可能是这样,请告诉我,我回修正本文)。
所以,尽管希腊神话中的Cassandra非常不幸(译注:Cassandra是希腊神话里,特洛伊的那个可怜的女先知的名字,如果你不知道详情的话,可以参考wiki),但你的Cassandra中的数据不会有危险。