欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

NO “NO SQL” (二) 博客分类: Storage SQLNoSQLC#CC++ 

程序员文章站 2024-03-23 17:16:58
...

本文出自:http://blog.csdn.net/historyasamirror/archive/2010/08/01/5781245.aspx

 

批判"CAP"

NOSQL社区专门建立了一个http://nosql-database.org 的网站,在这里 ,有着各式各样的关于NOSQL的新闻和评论,自然也就包含了各式各样关于CAP的解释和看法。但是我并不想从中随意找两篇反对NOSQL的文章来论证我的观点。这是因为很多NOSQL的文章只是来自于作者的经验和感觉,而这往往是一个公说公有理,婆说婆有理的事情。

我找到的批判CAP的佐证来自于Reference【1】【2】。这两篇虽然也只是blog,但是作者都是学术界的大牛:
【1】的作者Michael Stonebraker是Database领域的元老级人物,有名的PostgreSQL就是他的作品,对于他,实在是不需要介绍太多,用大牛这个词形容都有点委屈他了。
【2】的作者Daniel Abadi目前是yale的副教授,也是Database领域很有名气的家伙。我了解他是因为看过一篇他的关于column store的paper,他在这方面可以说是执牛耳者。另外,从他的blog中可以看出,yahoo的几个大规模系统也有他的参与。
两位大牛很巧合的在差不多同一时间(2010.4)各写了一篇关于CAP的文章,可能也是认为NO SQL在现在有些火过头了(当然,不排除含有学术界瞧不上技术社区的心理)。
以下我的表述可能和原文相比很多地方都不够精确,所以有精力的还是推荐看原文。

在【1】中,Stonebraker质疑了NOSQL社区的一个观点:
在NOSQL社区中,CAP被当做一个理论用于解释为什么系统要放弃Consistency。因为大部分的NOSQL系统都不允许挎多个节点的transaction,所以唯一还可能需要维护Consistency性质的就是数据副本之间(一般来说,NOSQL系统对同一个数据都会有多个副本放置在不同的节点上)。而根据CAP的理论,为了满足P和A,所以设计系统的时候就必须要放弃C,就是数据副本之间的Consistency,而采用诸如“eventually consisteny”的方式。这样,系统就能够保证A和P了。
Stonebraker则认为,并不是牺牲掉C就能够实现A和P。他列举了在一个Database中可能发生的错误:
    1. Application errors -- 程序的错误;
    2. Repeatable DBMS errors – 可重现的DBMS的错误,比如DBMS有bug;
    3. Unrepeatable DBMS errors – 不可重现的DBMS错误;
    4. Operating system errors – 操作系统错误,比如“蓝屏”;
    5. A hardware failure in a local cluster – local cluster的硬件错误,比如操作memory出错;
    6. A network partition in a local cluster – LAN出错了,某些节点不能和其它通信了;
    7. A disaster – 灾难,比如地震;
    8. A network failure in the WAN connecting clusters together – WAN出错了,cluster之间不能够通信;

Stonebraker基于这些错误,分别作了解释:
对于错误1和2,一旦发生,DBMS就处于错误的状态,Availability肯定达不到(there is no way to keep going; i.e., availability is impossible to achieve. Also, replica consistency is meaningless; the current DBMS state is simply wrong)。对于错误7,一旦发生,所谓的“eventually consistency”也很难保证,所以这种情况下,丢失数据是一个更好的选择,因为如果要做到在这种情况下仍然避免丢失数据,代价会很大(designer chooses to suffer data loss when a rare event (such as a disaster) occurs, because the performance penalty for avoiding it is too high)。所以,在错误1,2,7的情况下,CAP根本不适用,因为不论你是否牺牲C,也还是很难得到A和P。
再来看看CAP可能用到的情况。错误3,4,5,6是导致一个节点(node)挂掉的主要因素,而Stonebraker将一个node的fail看做是degenerate case of a network partition(退化的partition),因此CAP是可以适用在这里的。但是,Stonebraker说,“Considering local failures (3, 4, 5, and 6), the overwhelming majority cause a single node to fail, which is a degenerate case of a network partition that is easily survived by lots of algorithms. Hence, in my opinion, one is much better off giving up P rather than sacrificing C.”即,在所谓的“退化”partition的情况下,其实有很多的算法能够很容易的“survived”,所以,一个更好的选择是放弃P而不是放弃C。(这里其实我也没有看太懂,比如到底是那些算法,所以我不是完全同意这个观点)。
接着,Stonebraker还解释了其它的几种错误的解决办法,我就不一一解释了,还是那句话,尽量读原文吧。Stonebraker在整篇文章中的观点是,NOSQL的人们太轻易的将C给放弃了(throw out the C so quickly)。在实际的系统设计中,有很多的场景CAP并不适用,而在很多适用的场景中,放弃C也并不是一个好的选择。

再来看看第二篇文章【2】。
Abadi的角度和Stonebraker不太一样,他考虑的主要是这个问题:
CAP会使人们在做系统的时候将注意力放在Consistency和Availability之间的tradeoff上,这会很容易产生一个错觉:就是NOSQL的系统放弃Consistency的原因是为了Availability(my main problem with CAP is that it focuses everyone on a consistency/availability tradeoff, resulting in a perception that the reason why NoSQL systems give up consistency is to get availability)。
但是,这其实是不对的。他举了Yahoo PUNTS【3】的例子。如果按照CAP的定义的话,PUNTS系统同时放弃了C和A两个性质(Rather than giving up just one of consistency or availability, the system gives up both!)。这很有趣,因为CAP的说法是你只需要放弃其中的一个就可以了。
Abadi指出,PUNTS之所以会同时放弃两个,PUNTS之所以会违背CAP理论,原因在于CAP漏掉了一个很重要的性质:Latency(L,延迟)。PUNTS放弃Consistency并不是为了Availability,而是为了low latency(低延迟)。Abadi认为CAP很重要的一个问题就是没有将Latency考虑进来,所以,他基于此给出了一个CAP的扩展版本 – PACELC:
if there is a partition (P) how does the system tradeoff between availability and consistency (A and C); else (E) when the system is running as normal in the absence of partitions, how does the system tradeoff between latency (L) and consistency (C)?
意思是,如果系统中存在了partition,那么系统需要考虑Availability和consistency之间的tradeoff,而如果系统运行正常,那么它也需要在latency和consistency之间进行折衷。

(我个人很赞同Abadi本文中的观点。事实上,在前一篇blog中解释CAP的定义时,已经提到了Availability的学术定义其实并没有考虑到时间,也就是说如果一个请求在一年后返回结果也是允许的,但是,但在实际中,Latency却是一个系统最重要的性能指标之一。很多的tradeoff也是为了最大限度的降低latency。)

解释完了两篇blog,最后说说我个人的看法。
Stonebraker和Abadi在他们的文章中都表达了同一个观点,就是CAP被现在设计large-scale, distributed system的人过度使用了(I feel that it has become overrated as a tool for explaining the design of modern scalable, distributed systems -- Abadi)。这也是我写这篇blog想要表达的意思。
我显然还没有达到可以挑CAP中的“bug”的水平。但是,我也知道,一个真实环境下的分布式大系统的设计并不是一件容易的事,为了满足需求,设计的时候需要面临各式各样的tradeoff,这远远不是一个简单的CAP就能够解决的。回到前言中的关于使用NO SQL的第一个原因,RDBMS确实在scalability上存在问题,这点我完全认同,但同时,当NO SQL社区的人们在设计自己的scalable系统的时候,根据CAP理论粗暴简单的将Consistency放弃而认为因此可以获得Availability或者PartitionTolerance的想法也是不对的。其实CAP并没有绝对的对或者错,因为CAP本身就不是一个描述得很准确的理论(Brewer甚至从来都没有对CAP做过任何详细的定义),它甚至都不能称之为理论,它只是一个设计经验。可如果大家只是从字面上对于CAP做简单解读并以此做为设计系统时的尚方宝剑,就显得很滑稽了。

Reference:

【1】 Errors in Database Systems, Eventual Consistency, and the CAP Theorem

【2】 Problems with CAP, and Yahoo’s little known NoSQL system

【3】 PNUTS: Yahoo!'s hosted data serving platform