和上一篇博文同样,此次咱们依旧以 Riak 为案例,来分析 CAP
理论在一个实际的分布式数据库中的做用。html
若是你还不熟悉 CAP
,能够参考我以前的两篇博客 理解 CAP 理论, 最终一致性.html)。node
此次咱们来看看,在 Riak 这样的分布式key-value数据库中,CAP
理论是怎么起做用的。数据库
首先仍是让咱们来明确几个概念。服务器
N odes分布式
须要"最终"包含正确的值的服务器节点总数(正确的冗余数据拷贝数)。性能
W ritesspa
每次写操做,咱们须要确保最少有多少节点被更新。也就是说,咱们在执行写操做的时候,不须要等待 N 个节点都成功被写入,
而只须要 W 个节点成功写入,此次写操做就返回成功,而其余节点是在后台进行同步。code
R eadshtm
每次读操做,咱们须要确保最少读到几份冗余数据。也就是说,咱们在执行读操做的时候,须要读到 R 个节点的数据才算读成功,不然读取失败。ip
为何要这三个变量?其实这三个变量直接关系到了 Riak 的 CAP 特性。下面咱们就来一一说明:
以下图所示:假设咱们的 N=3, 设置 W + R <= N(例如:R=2, W=1)。这样咱们的系统能够相对保证读写性能。
由于写操做只须要一个节点写入就返回成功。
然而这里有机率发生这样的状况:就像图中所示,我写入的是node1(versionB),而后进行了一次读操做。
刚好这时候新数据还没有同步到node2, node3,而读操做又是从node2,node3取的值。因为这两个节点的值都是 version A,
因此获得的值即是 version A。
不过随着时间的推移,node1 中的 versionB 会被同步到 node2 以及 node3 中。
这时候,再有读操做,获得的值即是最新值(versionB)了。
这就是所谓的 Eventual Consistency。整个系统有着较高的读写性能,但一致性有所牺牲。
若是咱们须要增强一致性,能够经过调整 W, R, N 来实现。
接下来咱们会讨论如何调整 W,R,N 的关系来平衡读写性能和一致性(即 A 和 C 的平衡)。
一种极端作法(下图所示),咱们能够设 W=N, R=1。其实这就是关系型数据库的作法。
经过确保每次写操做时,全部相关节点都被成功写入,来确保一致性。这样能够保证一致性,可是牺牲了写操做的性能。
还有一种极端作法,咱们能够设W=1, R=N。这样,不管你向哪一个node写入了数据,都会被读到。
而后你读到的N个值也可能包含旧的值,只要有办法分辨出哪一个是最新的值就能够了
(Riak 是用一直叫向量钟(Vector Clock)的技术来判断的,咱们会在后面的博客中作介绍)
这样能够保证一致性,可是牺牲了读操做的性能。
最后再给出一种被称做 quorum
的作法。以下图所示,能够设置 W + R > N (例如 W=2, R=2)。这样一样能够保证一致性。
然而性能的损失由写操做和读操做共同承担。这种作法叫作 quorum
。