何时使用基于CRDT的数据库

Kumar是Redis Labs的高级产品经理 。
CAP定理所描述的保持一致性和可用性对地理分布应用程序的设计师来说是一个巨大的挑战 。网络分区是不可避免的 。数据中心之间的高延迟总是导致数据中心之间在短时间内断开连接 。因此,用于地理分布应用程序的传统体系结构被设计为放弃数据一致性或严重影响可用性 。
不幸的是,您不能牺牲牺牲交互式用户应用程序的可用性 。在最近的时间里,建筑师对一致性进行了测试,并接受了最终的一致性模型 。在此模型中,应用程序依赖于数据库管理系统来合并数据的所有本地副本,以使其最终保持一致 。
[您应该使用哪个NoSQL数据库? 让成为您的指南 。NoSQL怨恨匹配: 和 相互吸引。? NoSQL杰出之处:最佳键值数据库。? NoSQL杰出之处:最佳的文档数据库。| 通过大数据和分析报告时事通讯深入了解分析和大数据 。]
最终的一致性模型使一切看起来都很好,直到出现数据冲突为止 。一些最终的一致性模型有望尽最大努力来解决冲突,但不能保证强大的一致性 。好消息是,围绕无冲突复制数据类型(CRDT)构建的模型提供了强大的最终一致性 。
CRDT通过一组预定的冲突解决规则和语义来实现强大的最终一致性 。必须在基于CRDT的数据库之上构建应用程序,以适应冲突解决语义 。在本文中,我们将探讨如何使用基于CRDT的数据库设计,开发和测试地理分布的应用程序 。我们还将研究四个示例用例:计数器,分布式缓存,共享会话和多区域数据提取 。
我的雇主Redis Labs最近宣布在Redis 中提供CRDT支持,将无冲突的复制数据类型加入到丰富的数据结构组合中,包括字符串,哈希,列表,集合,排序集合,位域,Geo,超日志和流 。我们的数据库产品 。但是,以下讨论不仅适用于Redis,而且适用于所有基于CRDT的数据库 。
地理分布的应用程序数据库
对于地理分布的应用程序,通常在客户端本地运行服务 。这样可以减少网络流量和往返带来的延迟 。在许多情况下,架构师会设计服务以连接到本地数据库 。接下来是如何在所有数据库中维护一致数据的问题 。一种选择是在应用程序级别进行处理-您可以编写一个定期的作业过程来同步所有数据库 。或者,您可以依赖数据库,该数据库将在数据库之间同步数据 。
对于本文的其余部分,我们假定您将使用第二个选项-让数据库完成工作 。如下图1所示,您的地理分布的应用程序在多个区域中运行服务,每个服务都连接到本地数据库 。底层数据库管理系统在跨区域部署的数据库之间同步数据 。

何时使用基于CRDT的数据库

文章插图
Redis实验室
图1.使用主动/主动数据库的地理分布式应用程序的示例体系结构 。
数据一致性模型
一致性模型是分布式数据库和应用程序之间的契约,它定义了写操作和读操作之间数据的干净程度 。
例如,在强一致性模型中,数据库保证应用程序将始终读取最后一次写入 。通过顺序一致性,数据库可确保您读取的数据顺序与将其写入数据库的顺序一致 。在最终的一致性模型中,分布式数据库承诺在后台对数据库副本之间的数据进行同步和合并 。因此,如果将数据写入一个数据库副本并从另一个数据库副本读取数据,则可能不会读取数据的最新副本 。
强一致性
两阶段提交是一种实现强一致性的常用技术 。在这里,对于本地数据库节点上的每个写操作(添加,更新,删除),数据库节点会将更改传播到所有数据库节点,并等待所有节点确认 。然后,本地节点将提交发送到所有节点,并等待另一个确认 。该应用程序仅在第二次提交后才能读取数据 。当网络断开数据库之间的连接时,分布式数据库将无法进行写操作 。
最终一致性
最终一致性模型的主要优点是,即使分布式数据库副本之间的网络连接中断,您也可以使用该数据库执行写入操作 。通常,此模型避免了两阶段提交引起的往返时间,因此与其他模型相比,每秒支持的写操作要多得多 。最终一致性必须解决的一个问题是冲突-在两个不同位置同时写入同一项目 。基于它们如何避免或解决冲突,最终一致的数据库可进一步分为以下几类:
最后一位作家获胜(LWW) 。在这种策略中,分布式数据库依赖于服务器之间的时间戳同步 。数据库交换每个写操作的时间戳以及数据本身 。如果存在冲突,则以最新时间戳记的写操作为准 。
何时使用基于CRDT的数据库

文章插图
该技术的缺点是它假定所有系统时钟都已同步 。实际上,同步所有系统时钟既困难又昂贵 。
基于仲裁的最终一致性:此技术类似于两阶段提交 。但是,本地数据库不会等待所有数据库的确认 。它只是等待大多数数据库的确认 。多数人的承认建立了法定人数 。如果存在冲突,则已建立仲裁的写操作将获胜 。
另一方面,该技术将网络延迟添加到写入操作中,这使应用程序的可伸缩性降低 。同样,如果本地数据库与拓扑中的其他数据库副本隔离,则将无法进行写入 。
合并复制:在关系数据库之间常见的这种传统方法中,集中式合并代理合并所有数据 。此方法在实现自己的规则以解决冲突时也提供了一定的灵活性 。
合并复制太慢,无法支持实时,吸引人的应用程序 。它还具有单点故障 。由于此方法不支持用于解决冲突的预设规则,因此通常会导致解决冲突的错误实现 。
无冲突的复制数据类型(CRDT):您将在接下来的几节中详细了解CRDT 。简而言之,基于CRDT的数据库支持可提供无冲突的最终一致性的数据类型和操作 。即使分布式数据库副本无法交换数据,基于CRDT的数据库仍然可用 。它们始终为读取和写入操作提供本地延迟 。
局限性? 并非所有的数据库用例都能从CRDT中受益 。此外,基于CRDT的数据库的冲突解决语义是预定义的,不能被覆盖 。什么是CRDT?
CRDT是特殊的数据类型,可聚合来自所有数据库副本的数据 。流行的CRDT是G计数器(仅增长计数器),PN计数器(正负计数器),寄存器,G集(仅增长集),2P集(两阶段集)或OR集(在后台,它们依靠以下数学属性来收敛数据:
交换性质: a☆b = b☆a关联属性: a☆(b☆c)=(a☆b)☆c幂等: a☆a = a
G计数器是合并操作的操作CRDT的完美示例 。在此,a + b = b + a和a +(b + c)=(a + b)+ c 。副本仅相互交换更新(添加) 。CRDT将通过合并更新来合并它们 。例如,G集应用幂等({a,b,c} U {c} = {a,b,c})合并所有元素 。幂等避免了添加到数据结构中的元素通过不同路径传播和聚合时的重复 。
CRDT数据类型及其冲突解决语义无冲突的数据结构:G计数器,PN计数器,G集
所有这些数据结构在设计上都是无冲突的 。下表显示了如何在数据库副本之间同步数据 。
何时使用基于CRDT的数据库

文章插图
Redis实验室
图2:显示PN计数器如何同步更新的示例 。
Redis实验室
图3:G-Set保证了独特的元素 。
G计数器和PN计数器在诸如全局轮询,流计数,活动跟踪等用例中很流行 。G集被大量用于实施区块链技术 。例如,比特币采用仅追加的区块链条目 。
寄存器:字符串,哈希
寄存器本质上并不是没有冲突的 。他们通常遵循LWW或基于仲裁的冲突解决策略 。图4显示了一个示例,该示例说明了如何通过遵循LWW策略来解决冲突 。
何时使用基于CRDT的数据库

文章插图
Redis实验室
图4:寄存器的LWW策略 。
寄存器主要用于存储缓存和会话数据,用户配置文件信息,产品目录等 。
2P套
两阶段集维护两组G集-一组用于添加的项,另一组用于删除的项 。副本在同步时交换G集添加 。当在两个集合中找到相同的元素时,就会发生冲突 。在某些基于CRDT的数据库(例如Redis )中,这由策略“添加胜于删除”来处理 。
何时使用基于CRDT的数据库

文章插图
Redis实验室
图5:对于2P集,赢胜于删除 。
2P集是用于存储共享会话数据(例如购物车,共享文档或电子表格)的良好数据结构 。
如何设计应用程序以使用基于CRDT的数据库
将应用程序连接到基于CRDT的数据库与将应用程序连接到任何其他数据库没有什么不同 。但是,由于最终的一致性策略,您的应用程序需要遵循一组规则以提供一致的用户体验 。三把钥匙:
使您的应用程序无状态 。无状态应用程序通常由API驱动 。每次调用API都会从头开始重建完整的消息 。这样可以确保您始终在任何时间点都提取干净的数据副本 。基于CRDT的数据库提供的低本地延迟使重建消息变得更快,更容易 。
选择适合您的用例的正确的CRDT 。计数器是最简单的CRDT 。它可以用于诸如全局投票,跟踪活动会话,计量等用例 。但是,如果要合并分布式对象的状态,则还必须考虑其他数据结构 。例如,对于允许用户编辑共享文档的应用程序,您可能不仅要保留编辑内容,还要保留执行顺序 。在那种情况下,将编辑保存在基于CRDT的列表或队列数据结构中比将它们存储在寄存器中是更好的解决方案 。了解由CRDT强制执行的冲突解决语义,并且解决方案符合规则也很重要 。CRDT并不是万能的解决方案 。尽管CRDT对于许多用例确实是一个很好的工具,但对于所有用例(例如ACID事务),它可能并不是最好的 。基于CRDT的数据库通常非常适合微服务体系结构,在该体系结构中,每个微服务都有专用的数据库 。
这里的主要收获是,您的应用程序应专注于逻辑并将数据管理和同步复杂性委托给基础数据库 。
使用分布式多主数据库测试应用程序
为了更快地推向市场,我们建议您进行一致的开发,测试,过渡和生产设置 。除其他外,这意味着您的开发和测试设置必须具有分布式数据库的小型化模型 。检查基于CRDT的数据库是否可用作容器或虚拟设备 。将数据库副本部署在不同的子网上,以便您可以模拟已连接和已断开的群集设置 。
使用分布式多主数据库测试应用程序可能听起来很复杂 。但是大多数时候,您将要测试的是两种情况下的数据一致性和应用程序可用性:连接分布式数据库时,以及数据库之间存在网络分区时 。
通过在开发环境中建立一个三节点分布式数据库,您可以涵盖(甚至自动化)单元测试中的大多数测试方案 。以下是测试应用程序的基本准则:
【何时使用基于CRDT的数据库】From: