NO “NO SQL” (二)

来源:互联网 发布:pc6软件下载中心 编辑:程序博客网 时间:2022/08/16 17:55

批判"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