NO “NO SQL” (一)

糜宜民
2023-12-01

很久没写blog了,一个原因是因为前段时间一直很忙,还一个原因是很多blog我写到一半就写不下去了。写着写着就发现似乎这个问题自己还没搞懂,所以又搁置下来然后再查资料。哎,我整理知识的速度永远跟不上学习的速度。

这篇blog我准备了很长时间,希望能把整个系列都写完,写好。


前言

但凡一个关注当前技术趋势的人,都应该知道NO-SQL。NO-SQL现在很火,每天都有无数的blog在阐述它,在热议它,在实践它。包括我自己,之前也或原创或转载了几篇和key-value store,non-relational database有关的blog,去年也做了很多这方面的工作。
但在这篇文章里,我尝试站在NO-SQL的对立面来看待这个问题,或者说,我希望能够批判它。原因有二:
1 这是一个自我的反思:从第一次接触到Dynamo,CouchDB时候的兴奋,到现在的冷眼旁观,我想在这个过程我还是有所得的;
2 这是对现实的一个批判:中国有个很不好的现象,所有人都不喜欢创造而只愿意跟随,都不喜欢原创而只喜欢抄袭。做产品的抄(看看现在火热的团购),做技术的也抄(看看火热的NO-SQL)。多少人随便拿着国外某技术会议的PPT上的两句话放在自己的blog里面就能装专家(没啥不好意思的,这事俺也干过)
也正是基于以上这两点,在这篇文章中,我希望能做到严谨和权威。我会尝试只引用一些比较正规的说明(比如wiki)和大牛的paper或者blog,而不是随意的道听途说。

言归正传。回到NO-SQL。
NO-SQL的定义我这里就不说了。事实上,现在为止也没有一个明确的定义。但是NO-SQL这个movement(no-sql wiki 中将NO-SQL定义成了一个movement)是确实存在的。之所以采用NO-SQL而不是采用RDBMS(比如Oracle,MySQL,DB2等),原因我分析大致有二:
1 RDBMS在scalability上存在问题;
2 RDBMS所采用的relational data model在一些场景下不适用;

接下来,我分别对这两个原因进行论述。

 

什么是CAP

在谈到RDBMS在scalability上的缺陷时,NO-SQL的支持者们都会提到一个“理论”,就是CAP,同时,很多的NO-SQL system在设计的时候也受到了CAP的影响(这从一些相关的open source project的文档中可以看出来)。所以,可以认为,CAP成为了NO-SQL一个非常核心的理论支柱。
那么,什么是CAP?
这个问题可真是不好回答。CAP最早是在2000年PODC的一个invited talk上,由Eric Brewer(我前面有篇blog 专门介绍过他)提出的。(很有意思的是,CAP在当年提出来的时候并没有太大的影响,反而是现在…)。但是除此以外,Eric Brewer没有在他自己的任何一篇paper中再介绍过,所以,目前为止来自于其原创者Brewer的关于CAP的唯一解释只有那次talk上的一个PPT【1】。在这个PPT上,CAP是这样定义的:
    C -> Consistency;
    A -> Availability;
    P -> Tolerance to network Partitions;
    You can have at most two of these properties for any shared-data system.
坦率的说,这个定义比较直观,但非常的含糊,特别是C,A,P字母分别表示的含义,在这里很难真正理解。
一个更加详细,并且现在看来也是最靠谱的一个解释来源于Prof. Lynch在2002中的paper【2】,这篇paper详细阐述和论证了CAP(prove this conjecture in the asynchronous network model)。我采用这篇paper作为CAP最权威的解释,主要是因为,首先,这是一篇关于CAP的正式的学术性论文,所以应该比较严谨,其次,作者Lynch可以说在分布式领域鼎鼎大名,她的书“Distributed Algorithms”是分布式领域的bible,她的paper当然可信度要高些。
OK,来看看Lynch的paper说了些什么。

 

Consistency
按照Lynch的说法,CAP中的C指的是Atomic Consistency,就是说,并发的操作看起来应该就像是有顺序的串行执行。“Atomic consistency is the condition expected by most web services today. Under this consistency guarantee, there must exist a total order on all operations such that each operation looks as if it were completed at a single instant”。
需要说明的是,CAP中的consistency指的是一个system的consistency,和ACID中的consistency并不是一个概念(ACID中的consistency的对象是transaction)。按照Lynch的说法,CAP中的consistency对应于ACID中的atomic和consistency。“…as it subsumes the database notions of both Atomic and Consistent”。
其实抛开这些理论的东西不谈,consistency也是CAP中最容易理解的一个概念,并不容易产生太大的混淆。

 

Availability
Lynch的说法,“For a distributed system to be continuously available, every request received by a non-failing node in the system must result in a response”。这个说法有两个比较有趣的地方。一个是non-failing node,也就是说,如果request被一个正常的node接收了,那么必须产生一个response,但是,如果发起一个request而系统根本就不接收呢,这样算不算unavailable?另一个有意思的词是“must”。“must”的意思是一定会返回一个response,但是,却不对response time做任何的限制,那么这就很困惑了,如果一个系统接受到request后一年才返回结果,那么它算是availablility吗?
当然,如果不考虑这些非常“狡猾”的地方,availablity可以直观的理解成,就是系统能够24*7的稳定运行并生成response。

 

Partition Tolerance
这是一个非常奇怪的表述,也是之前我最困惑的地方。按照字面的理解就是“容忍分割”。这里牵扯到两个问题:什么叫做“分割”,怎么样才算是“tolerance”。
在Lynch的paper中,有明确的partition定义:“when a network is partitioned, all messages sent from nodes in one component of the partition to nodes in another component are lost”。就是说,你的system中的node如果构成了一个network,这个network被分成了两个部分,一个部分中的node发出的message另一个部分的node是收不到的,这样我们就能够说这个system被partition了。
tolerance的意思则是指当一个system处于partition的状态,但是这个system仍然能够满足Consistency或者Availablity的要求 。
当然,这里也有个问题,就是Partition的程度并没有被定义。一个系统,如果一台机器fail了,可以说这个系统处于partition的状态,如果一个机柜的网络断了,也可以说是partition,而这两种partition显然是有区别的。

 

综上所述,我个人的看法,Consistency和Availability可以看做是system的属性,而Partition Tolerance是一个限制条件或者状况。举例来说,如果一个系统在partition的状态下能够满足Consistency但是做不到Availability,那么这个系统就满足C和P。而如果一个系统在平时能够满足Consistency和Availability,但是在Partition状态的时候都满足不了,那么这个系统就满足C和A。而一个系统无论是否在Partition状态的时候,都能够满足Consistency和Availability,那么这个系统就满足C,A和P。当然,根据CAP理论,这是不可能的。

 

下一篇会谈到对于CAP的“批判”。

 

 

Reference

1 http://www.cs.berkeley.edu/~brewer/cs262b-2004/PODC-keynote.pdf

2 http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.20.1495&rep=rep1&type=pdf


 

 

 

 

 类似资料: