dot Redis 8 来了 - 而且是开源的

了解更多

介绍 RedisRaft,一种新的强一致性部署选项

RedisRaft (正在开发中) 是一个用于开源 Redis 的新模块,它使得将多个 Redis 服务器作为单个容错、强一致性集群运行成为可能。顾名思义,它基于 Raft 共识算法 和一个 实现它的开源 C 库

RedisRaft 为 Redis 和 Redis 生态系统带来了一种新的 具有严格序列化的强一致性 部署选项。 通过新的模块,Redis 及其现有的客户端、库和数据类型可以用于超出缓存的场景,并且这些场景需要高水平的可靠性和一致性。

RedisRaft 的起源

RedisRaft 最初是在 Redis 5 发布前不久的一个实验性“副项目”。 Redis 模块 API 在 Redis 4 中引入,主要用于支持实现新数据类型和命令的模块。 我们想探索可以扩展 API 的程度,并使用模块以更彻底的方式扩展 Redis。 但我们也希望最终得到一些有用的东西——Redis 的强一致性部署选项。

RedisRaft 集群提供与可靠的、知名的数据存储(如 ZooKeeper 或 Etcd)所期望的相同级别的一致性和可靠性。 简而言之,在 RedisRaft 中

  • 确认的写入保证会被提交并且永远不会丢失。
  • 读取总是返回最新的已提交写入。

正如提供这种级别一致性的可靠数据存储所期望的那样,这种保证带来了性能和可用性方面的权衡。 在 RedisRaft 中

  • 客户端操作取决于集群节点交换消息,因此它们会受到网络延迟的限制。
  • 写入必须先刷新到磁盘才能完成,因此它们会受到磁盘 I/O 延迟的限制。
  • 只有当大多数节点启动、健康且能够相互通信时,集群才可用。

RedisRaft 的工作原理

一旦 RedisRaft 模块被加载到 Redis 中,它就会接管集群节点之间的通信、Raft 日志或快照的复制、持久性等等。 Redis 核心仍然不知道这一点,就它而言,它正在作为没有集群、持久性或复制的独立服务器运行。

设置一个三节点 RedisRaft 集群就像启动三个 Redis 服务器一样简单,如下所示

redis-server --loadmodule /path/to/redisraft.so

这是连接到第一台服务器并创建 Raft 集群的方法

10.0.0.1:6379> RAFT.CLUSTER INIT
OK 989645460313dd2ddb051f033c791222

然后,连接到其他两台服务器并将它们加入到集群

10.0.0.2:6379> RAFT.CLUSTER JOIN 10.0.0.1:6379
OK
10.0.0.3:6379> RAFT.CLUSTER JOIN 10.0.0.1:6379
OK

访问集群

设置好 RedisRaft 后,我们可以将数据写入集群

10.0.0.1:6379> INCR counter:1
(integer) 1

收到回复表明我们的写入已复制到至少大多数集群节点(在我们的例子中是 2 个节点),并已提交到它们的持久存储。

Raft 基于强领导者概念,这意味着所有客户端操作都应发送到领导者节点并从该节点启动。 在这种情况下,我们的客户端确实连接到了领导者,但集群领导者是动态的,客户端可能不一定知道谁是领导者。

在追随者(非领导者)节点上尝试相同的操作会创建此响应

10.0.0.3:6379> INCR counter:1
(error) MOVED 10.0.0.1:6379

因此,作为客户端,我们现在可以捕获此错误,重新建立与指定的领导者节点的连接,然后重试我们的命令。

但是,如果我们不想修改现有的应用程序怎么办? 幸运的是,RedisRaft 也可以配置为自动为我们处理此问题。 通过启用追随者代理模式,我们可以让集群节点自动将我们的请求转发给领导者并在可用时提供回复:

10.0.0.3:6379> RAFT.CONFIG SET follower-proxy yes
OK
10.0.0.3:6379> INCR counter:1
(integer) 2

当然,这要简单得多,但会影响延迟和网络负载,因为命中非领导者节点会产生额外的网络跳数。

集群变更

在设置我们的集群时,我们实际上执行了三个不同的操作

  1. 在一个节点上创建集群。
  2. 添加第二个节点。
  3. 添加第三个节点。

RedisRaft 集群配置不是静态的,在集群创建后且处于活动状态时,可以添加或删除其他节点。

例如,我们可能需要更换第三个节点。 首先,我们加入一个将要替换它的新节点。 请注意,我们采用“先添加再删除”而不是“先删除再添加”的方式,以避免在转换期间使集群和我们宝贵的数据处于降级的冗余状态

10.0.0.4:6379> RAFT.CLUSTER JOIN 10.0.0.1:6379
OK

接下来,我们查找随机分配给第三个节点的 ID

redis-cli -h 10.0.0.1 --raw RAFT.INFO | grep 10.0.0.3
node2:id=1739451728,state=connected,voting=yes,addr=10.0.0.3,port=6379,
last_conn_secs=3537,conn_errors=0,conn_oks=1

然后我们删除它

10.0.0.1:6379> RAFT.NODE REMOVE 1739451728
OK

RedisRaft 发布状态

作为 RedisRaft 开发工作的一部分,我们一直在与 Kyle Kingsbury (又名 Aphyr) 合作,以使用 Jepsen(一个用于测试分布式系统的安全性和正确性的著名框架)来分析和测试 RedisRaft。 到目前为止,这项合作已产生 此已发布的分析

虽然仍在开发中,但 RedisRaft 的大多数基本功能都已到位。 我们目前正在努力开发第一个预览版本,预计将在几个月内推出。 在普遍可用时,RedisRaft 将在双重许可下发布,GNU AGPLv3 或 Redis Source Available License (RSAL)。