此内容是在 Redis 命名约定更改之前编写的——Redis Enterprise 现在是我们所有产品的名称。
如今,Redis 应用可以利用几种类型的复制——
在即将发布的 Redis Enterprise 5.0 版本中,我们将推出一种专为广域网构建的全新灵活多主复制技术。这项新功能利用 CRDT(无冲突复制数据类型)的魔力,实现了主动-主动的地理分布式 Redis 部署。CRDT 简化了主动-主动系统的开发,并自动解决冲突写入。结合 Redis 数据类型,CRDT 提供了一种机制,可以轻松帮助您开发能够智能处理冲突写入的主动-主动地理分布式系统。
如果您想了解更多关于 Redis CRDT 的信息,请访问“使用 CRDT 在地理分布式部署中弯曲 CAP 定理“
我们将在此演示中重点介绍 CRDT 的实验,但如果您想更深入地了解 CRDT,可以从 Eric Brewer 的这篇文章开始:在最初的 CAP 定理发表 12 年后,Eric Brewer 在这篇出色的文章中解释了 CRDT 如何改变 CAP 的平衡。要亲身体验 CRDT 并进行尝试,您可以注册 Redis Enterprise 5.0 的预览计划。您可以在此处找到说明。
我们将搭建一个规模精简的地理分布式部署,并演示在 Redis Enterprise 下主动-主动访问是如何工作的。以下是四个步骤:
运行 2 个容器。我们将使用每个容器模拟一个 Redis Enterprise 集群。
注意:在运行容器之前,请前往 Docker 设置并将每个容器的 RAM 调整为 6GB。在某些操作系统下,除非调整了每个容器的 RAM,否则可能无法启动 Redis Enterprise Pack 容器。
docker run -d --cap-add sys_resource -h rp1 --name rp1 -p 8443:8443 -p 8080:8080 -p 12000:12000 redis/redis docker run -d --cap-add sys_resource -h rp2 --name rp2 -p 8444:8443 -p 8081:8080 -p 12001:12000 redis/redis
重要的是要注意 -p 选项:每个容器将其 Web UI 端口 (8443)、REST API 端口 (8080) 和数据库访问端口 (12000) 映射到唯一的宿主机端口,以确保可以从运行容器的宿主操作系统访问所有容器。这将有助于您从宿主机以及容器本身连接到每个集群。
让我们设置两个集群。
对于集群 1,在宿主机上将浏览器指向 https://:8443 以查看 Redise Pack 管理控制台。只需点击页面上的“Setup”按钮即可开始。
注意:根据您的浏览器,您可能会看到证书错误。只需选择继续访问网站即可进入设置屏幕。
在节点配置页面上,选择您的默认设置并提供集群的 FQDN:cluster1.local。然后只需点击“Next”按钮。
如果您没有许可证密钥,点击“Next”按钮即可试用产品。
在下一个屏幕上,使用电子邮件作为登录名并设置密码,创建一个集群管理员账户。
您已在 cluster1.local 上完成设置。
对集群 2 重复相同的操作。首先,将浏览器指向 https://:8444。步骤完全相同,但这次将 FQDN 指定为 cluster2.local。
完成后,我们就有了两个 FQDN 分别为 cluster1.local 和 cluster2.local 的 Redis Pack 集群。
我们将使用 REST API 创建数据库。以下操作将创建一个类型为 CRDB(无冲突复制数据库)的 Redis 数据库。CRDB 有一些特别之处
下面的 REST API 调用将在 cluster1.local 和 cluster2.local 上分别创建一个 CRDB 实例。在每个集群上,CRDB 实例的端点端口都是 12000,并且两个数据库都命名为“sample-crdb”。
在发出以下调用之前,请将您在上述设置过程中指定的 <admin-email> 和 <admin-password> 替换。
在“Databases”选项卡下,选择部署类型设置为“Geo-Distributed”的 Redis 数据库。
在创建数据库页面上,点击 show advanced option 链接,然后在数据库名称中输入 database1,端点端口号中输入 12000。确保将 http://cluster1.local:8080 和 http://cluster2.local:8080 都添加到参与集群列表中。
激活数据库后,您将在每个参与的集群上拥有可连接的 CRDB 实例。
创建好 Redis 数据库 (CRDB) 后,您就可以连接到您的数据库了。您可以使用以下方法之一来测试数据库连接
请记住,我们有两个可用于连接和并发读写的 CRDB 实例。CRDB 实例使用双向复制来同步全局 CRDB。
使用 redis-cli 连接
redis-cli 是一个用于与 Redis 数据库交互的简单命令行工具。在本例中,我们将使用“docker exec”在每个容器下使用 redis-cli。使用“docker exec”将您的上下文切换到 cluster1.local 中名为 rp1 的 Redis Pack 容器节点。
docker exec -it rp1 bash
运行位于“/opt/redis/bin”目录下的 redis-cli,连接到端口 12000,并在数据库中存储和检索 key1。
/opt/redis/bin/redis-cli -p 12000 127.0.0.1:12000> set key1 123 OK 127.0.0.1:12000> get key1 "123"
让我们看看对 key1 的写入如何复制到集群 2。在另一个终端窗口中,使用“docker exec”将您的上下文切换到集群 2 的 Redis Pack 容器节点。
docker exec -it rp2 bash /opt/redis/bin/redis-cli -p 12000 127.0.0.1:12000> get key1 "123"
您现在拥有一个可用的 CRDB 部署。让我们看看当您对数据进行并发分布式写入时,CRDB 如何简化开发。
这里有一个简单的测试。让我们看看在 cluster1 和 cluster2 上的两个 CRDB 实例中对 k1 执行 INCR 操作如何同步以确保最终值的准确性。t1 到 t5 表示事件顺序。在 cluster1.local 下的操作在 rp1 容器上执行,在 cluster2.local 下的操作在 rp2 容器上执行。
模拟网络故障:集群之间的同步速度很快。对于一些高级测试,您还会发现模拟 cluster1 和 cluster2 之间的网络故障很有用,这样您就可以观察每种数据类型中的 CRDT 如何工作。
在 docker 中模拟网络分区很容易。要创建网络分区,请查找 cluster1 上的 IP 地址。我得到的是 10.0.0.2
docker exec -it rp1 ifconfig | grep 0.0.0.0 | cut -d":" -f 2 | cut -d" " -f 1
10.0.0.2
要中断 cluster1.local 和 cluster2.local 这两个集群之间的网络连接,请在 cluster2.local (rp2 容器) 上运行以下命令。
docker exec --privileged rp2 iptables -A INPUT --source 10.0.0.2 -j DROP docker exec --privileged rp2 iptables -A OUTPUT --dst 10.0.0.2 -j DROP
此时,cluster1 和 cluster2 无法通过主动-主动复制进行通信。在某个时候,您会希望恢复网络连接。一旦恢复集群之间的网络通信,CRDB 将自动重新开始同步。方法如下;
docker exec --privileged rp2 iptables -F
这里还有一个可以尝试的例子。这次我们将在操作之间模拟网络故障以观察问题。在这种情况下,我们将看到 Redis SET 如何与 CRDT 配合工作。我们将创建一个集合并让它在集群之间同步。然后,我们将中断网络,并在每个集群中私下向 SET 添加一个新成员。一旦通信恢复,您将看到 CRDT 如何解决冲突写入并合并这两个集合。
我们只是对 Redis 中的 CRDT 进行了初步介绍。您可以注册私人预览版,以获取更多关于这些功能的详细信息和文档。只需按照此处的说明操作即可。