MongoDB 中的分布式一致性
MongoDB 没有规定具体的内存一致性模型,但默认支持强一致性。在某些情况下,MongoDB 可以并且配置为最终一致性。
在启用自动分片复制的集群的默认情况下,每个分片中都有一个主控。这种部署的内存一致性模型很强。但是,在其他一些情况下,您可以部署 MongoDB 以获得更大的可用性和分区容忍度。
Master 是所有写操作的节点,多个从节点用于读操作。如果从服务器与集群分离,仍然服务于客户机,那么它可能会提供过时的数据。在分区修复时,从服务器将接收所有更新并提供最终一致性。
CouchDB 数据库的最终一致性
CouchDB 的最终一致性模型依赖于两个重要特性:
-
多版本并发控制
-
同步复制
CouchDB 中的每个文档都进行了版本控制,对文档的所有更新都用唯一的版本号标记。CouchDB 是一个高度可用的分布式系统,它放松了一致性,有利于提高可用性。
在读取操作时,客户端(A)访问具有当前修订号的版本化文档。为了具体起见,我们假设文档名为 D,其当前版本或修订号为 v1。由于客户机 A 正忙于阅读并可能更新文档,客户机 B 访问同一文档 D,并且还了解到它的最新版本是 v1。接下来,客户机 B 准备在 A 返回之前更新文档。它更新 D 并将其版本号或修订号增加到 v2。当客户端 A 随后返回对文档 D 的更新时,它意识到文档已经更新,因为它在读取时访问了快照。
这会在提交时产生冲突的情况。可以使用版本号或修订号来解决冲突。
可以参考以下图片,获得刚刚说明的冲突更新用例的图形表示。
这种冲突通常可以通过客户机 A 在准备提交新更新之前重新读取 D 来解决。在重新读取时,如果 A 发现正在使用的快照版本(在本例中为 v1)过时,它可能会在最新读取时重新应用更新,然后提交更改。这种解决冲突的方法在版本控制软件中很常见。许多当前的版本控制软件产品,如 Git 和 Mercurial,都采用了 MIVCC 来管理数据保真度并避免提交冲突。
CouchDB 存储是可伸缩的分布式数据库,因此当 MVCC 在单个实例中解决冲突解决方案时,它不一定能解决保留数据库当前和最新的。这是复制接管的地方。
复制是用于同步任意两个数据存储单元的常用且公认的方法。最简单的档案同步程序 rsync 对文件系统单元(如文件夹或目录)也能达到同样的效果。
CouchDB 集群中的所有节点中的数据最终将与复制过程的帮助一致。CouchDB 中的复制既是增量的,也是容错的。因此,只有更改(或增量更新)在复制时被传播,如果进程失败,则在传输更改时可以正常恢复。CouchDB 复制具有状态感知能力,一旦出现故障,它会选择上次停止的位置。因此,避免了冗余重启,并将网络故障或节点不可用的固有趋势作为设计的一部分。CouchDB 的最终一致性模型既有效又高效。CouchDB 集群通常是主-主节点,因此每个节点都可以独立地为请求提供服务,从而增强可用性和响应性。
Cassandra 最终一致性
Cassandra 的目标是像谷歌 Bigtable 和亚马逊 Dynamo 那样。从 CAP 定理的观点来看,这意味着 Cassandra 为两种权衡选择做出了规定:
-
支持一致性和可用性—— Bigtable 模型,
-
有利于可用性和分区容忍性—— Dynamo 模型,
Cassandra 通过将最终的一致性配置留给开发人员来实现这一点。作为开发人员,您的选择如下:
-
设置 R + W > N 并实现一致性,其中 R、 W 和 N 分别为读副本节点数、写副本数和节点总数。
-
通过设置 R = W = 上限((N + 1)/2获得 Quorum 一致性。
您还可以在 W = N 的所有情况下设置写一致性,但是这样的配置可能比较棘手,因为失败会使整个应用程序不可用。
Membase 的一致性
Membase 是一个与 Memcached 协议兼容的分布式密钥/值存储,提供了高可用性和强一致性,但不支持分区容忍。Membase 是立即一致的。在分区的情况下,您可以使用外部工具将 Membase 存储从主副本复制到从副本,但这不是系统的一个特性。
此外,Membase 与 Memcached 一样,擅长保持时间敏感的缓存。在一个强大而直接的内存一致性模型中,清除超过规定时间间隔的数据很容易且可靠地得到支持。支持时间敏感数据的不一致窗口可能会带来其自身的挑战。
本文正在参加「金石计划 . 瓜分6万现金大奖」