dot 未来的速度将出现在您所在的城市。

加入我们在 Redis 发布会

深入无冲突复制数据类型 (CRDT)

主动-主动地理分布 允许您将 Redis 数据库集群实例和 数据 中心放置在靠近您的用户的位置,无论他们身在何处。将只读副本放置在靠近您的用户的位置是实现实时响应的正确方法。对于写入密集型应用程序,这还不够。那么如何开发主动-主动地理分布式集群呢?

介绍 无冲突复制 数据 类型 (CRDT)

无冲突复制数据类型 (CRDT)(也称为收敛复制 数据类型交换式复制 数据类型)是一系列复制数据类型,它们具有共同的属性集,这些属性使操作能够始终收敛到所有副本之间一致的最终状态。为了确保冲突永远不会发生(没有冲突解决的概念)并在您的应用程序中引起问题,对CRDT 数据类型的操作必须遵守特定的一组代数属性。

CRDT 在您创建启用 CRDT 的数据库时在Redis 企业版 中工作,因为标准命令将被等效的 CRDT实现 替换。让我们看看一个具有 CRDT 等效项的 Redis 数据结构以及主动-主动地理分布式复制带来的细微差别。

Redis 中的集合

Redis 集合类似于您最喜欢的编程语言在标准库中提供的集合,提供专门的操作来添加和删除元素、检查元素是否为集合的一部分,以及执行集合交集、并集和差集。以下是如何调用实际 Redis 命令的示例

// 创建一个集合
> SADD fruits apple pear banana
3

// 测试它是否包含 apple
> SISMEMBER fruits apple
1

// 删除一个水果
> SREM fruits banana
1

// 测试它是否仍然存在:
> SISMEMBER fruits banana
0

在启用 CRDT 的 Redis 企业版数据库中运行相同的命令将显示相同的行为,但幕后发生的事情完全不同。

CRDT 数据库中,所有副本 节点都可以独立地对“fruits”键进行更改。这使您能够真正编写地理分布式应用程序。缺点是,在写入时,也会遇到“复制延迟”。这种方法为地理分布式应用程序和实现数据 一致性提供了显著的优势。

CRDT 集合 & Redis 企业版

在启用 CRDT 的 Redis 企业版数据库中,集合操作在以下几个附加规则下工作,其中最重要的两个规则在合并来自不同节点的操作时应用

  1. 添加优于删除。
  2. 删除仅对执行命令的副本已看到的元素有效。

第二条规则有时被称为“观察删除”规则,这意味着您只能删除在发出命令时观察到的项目。

关于复制延迟和一致性模型的说明

虽然最终所有副本节点将收敛到相同的最终状态,但在短期内,例如,发送到 ReplicaEU 的命令可能尚未传播到 ReplicaUS。这种情况,虽然通常很短,但这就是 CRDT 数据结构必须硬编码冲突解决策略的原因。同一 CRDT 数据库中的所有副本将不断同步其状态,以尽可能提供一致的数据集视图,但请记住,CRDT 也可用于确保高可用性,以防网络分区。

这意味着,为了在您的系统中实现更好的弹性,您需要考虑系统尚未完全同步的可能性。这使得 CRDT 成为最终一致性的一种形式。这通常被称为强最终一致性,因为它比基于仲裁配额的更常见的复制类型更有效。(有关更多信息,请参阅关于主动-主动地理分布的 Redis 页面。)

为什么要使用 CRDT?

CRDT 将复制 作为交换操作执行。对于分布式系统来说,这具有理想的特性,即复制的顺序无关紧要。以任意顺序进行复制 从根本上重新构建了许多分布式系统竞态条件,并且随着异步性(例如,分布式)的增加,其有用性也会增加。在许多系统中,需要将某些数据的副本存储在副本上。此类系统的示例包括

  • 在本地设备上存储数据并需要将该数据同步到属于同一用户的其他设备(例如日历、笔记、联系人或提醒)的移动应用程序;
  • 分布式数据库,它维护数据的多个副本(在同一数据中心或不同位置),以便即使某些副本离线,系统也能继续正常工作;
  • 协作软件,例如 Google Docs、Trello、Figma 或许多其他软件,多个用户可以同时对同一文件或数据进行更改;
  • 复制数据以实现全局可扩展性的大规模数据存储和处理系统。
  • CRDT 的用例包括
    • 分布式缓存
    • 共享会话
    • 多区域物联网 数据 摄取

更多 CRDT 数据结构

要查看 Redis Enterprise 支持的所有 CRDT 数据结构的完整列表,请查看官方文档

为 CRDT 开发

开发主动-主动应用程序的实际要求是什么?

让我们看看可能引发疑问的主要开发方面。

用于 CRDT 数据库的客户端库

一个问题是您是否需要一种特殊类型的 Redis 客户端来与 CRDT 数据库交互。答案是否定的 - 任何普通的 Redis 客户端都可以连接到 CRDT 数据库并直接执行命令。如前所述,命令没有改变,是底层机制发生了变化。客户端没有开箱即用的唯一功能是能够连接到不同的地理分布式副本,以防最靠近服务实例的副本不可用。我们正在处理这个问题,但在此期间,在发生网络拆分的情况下,您必须在应用程序级别决定何时适当地连接到另一个区域的副本。

CRDT 应用程序架构

主动-主动地理分布的优势是能够在全球分布的服务实例之间共享一些状态,同时在操作该状态时体验本地延迟。为了充分利用此功能,您的服务需要尽可能依赖 CRDT 的语义,并因此避免保持在发生故障时会丢失(或无法合并)的内部状态。即使分布式数据库副本无法交换 数据,也可以使用基于 CRDT 的数据库。

CRDT 无法解决所有问题,因为它们硬编码了可能不适合您特定问题的特定合并规则。计数器是典型的 示例: CRDT 计数器 很棒,但它们不能用于模拟银行账户余额,因为合并可能会导致 计数器 变为负数 - 而且在应用程序级别无法阻止这种情况发生。换句话说,CRDT 是一种有效但细致入微的 最终 一致性 形式,它不适用于本质上是事务性的问题。

测试主动-主动地理分布式 CRDT 应用程序

测试主动-主动地理分布式应用程序似乎比测试普通的单主应用程序复杂得多。虽然 CRDT 当然是你 数据 模型的复杂组成部分,但它们的行为在结果方面是完全确定的。您需要考虑集群被分区时的主要情况。如上所述,继续向已断开与集群其他部分连接的 副本 发送更新是可以的,因为当连接重新建立时,更新最终将成功合并。您需要确保您的服务在断开与整个主动-主动地理分布式 CRDT 数据库集群时仍然可以正常运行。

换句话说,您方面唯一需要额外的非显而易见的测试应该是关于应用程序在发生网络分区时如何表现。

对全球用户的本地延迟

CRDT 允许您创建地理分布式应用程序,这些应用程序可以为您的整个用户群提供本地延迟,同时使您的整个应用程序更能抵御故障。虽然 CRDT 无法解决所有问题,但对于大多数公司来说,它们可以带来巨大的改进空间。例如,请查看Kyle Davis 最近的这篇博文,他在文中展示了如何使用排序集实现排行榜 - 并暗示了 CRDT 版本的好处。

要了解有关使用 Redis Enterprise 编写主动-主动应用程序的更多信息,请查看我们的深入了解:CRDT 白皮书和官方文档

如何将 最终 一致性 一致性 进行比较? 

一致性 是将任何 更新 传播到 数据 的所有副本。在最简单的情况下,对 数据 的一系列更新来自单个来源,并且所有其他持有 数据 副本的实体都保证以相同的顺序接收这些更新。

当需要同时更新 数据 的多个副本时,需要有一种方法来就 数据 的正确版本达成一致。使用 一致性,一旦一个实体进行任何更新,所有其他副本就会被锁定,以消除对 冲突 解决 的需要,直到它们被更新到同一个新版本。真相来源以相同的顺序将更新推送到所有实体,以使它们“保持一致”。 

一致性 中使用的锁定机制与实时性能的需求不一致。这就是 最终 一致性 和 CRDT 发挥作用的地方。每个集群或节点都可以潜在地进行和接收更新,因此无法确保每个 副本 都能获得相同的更新序列。 最终 一致性 是一种属性,无论到达每个 副本更新 事件的顺序如何,最终都会协调 数据 的状态。CRDT 可以解决在去中心化环境中存在的副本上的 并发更新并发插入 造成的 复制 冲突。