Redis 进阶 07:复制、Sentinel 与 Cluster

实验基线:Redis 7.4.11,先完成环境准备。除标注为宿主机终端的代码外,Redis 命令在该课指定的 redis-cli 中执行;不复制输出结果作为命令。

学习目标#

区分复制、自动切换与分片,通过独立网络验证主从复制及 Cluster 路由,明确异步复制的数据安全限制。

原理:三个机制解决不同问题#

主从复制把主节点写入异步传给副本。副本读可能陈旧,主节点响应写入成功时并不意味着副本已经持久保存。WAIT 可以等待指定数量副本确认此前写入,但不会把系统变成强一致存储。

Sentinel 监视主从拓扑,执行故障判断与主节点选举;它不分片。生产通常部署至少三个 Sentinel 于独立故障域,配置 quorum 并使用支持 Sentinel 的客户端发现主节点。quorum 达成用于判断故障,故障切换还需要获得多数 Sentinel 授权。

Cluster 把键映射到 16384 个槽,实现多主分片与故障切换。不是每个节点都保存全量数据;生产通常为每个主节点配置副本。本课最小三主实验没有副本,仅验证分片,不能抵御节点故障。

实验:主从复制#

在宿主机创建本课专用网络,不开放外部端口:

docker network create redis-learning-ha
docker run -d --name redis-primary --network redis-learning-ha redis:7.4.11 redis-server --save "" --appendonly no
docker run -d --name redis-replica --network redis-learning-ha redis:7.4.11 redis-server --replicaof redis-primary 6379 --save "" --appendonly no
docker exec redis-primary redis-cli SET learn:ha:message hello
docker exec redis-primary redis-cli INFO replication
docker exec redis-replica redis-cli INFO replication
docker exec redis-replica redis-cli GET learn:ha:message

等待副本 INFO replication 中 master_link_status 为 up,GET 返回 hello。若仍为空,检查同步状态后重试,不能把异步延迟当作命令一定失效。

WAIT 返回 1 表示在最多 2000 毫秒内收到一个副本确认。它追踪当前连接此前的写入;分开的 docker exec 会建立不同连接,不能用于证明前一次 SET 的复制确认。进入同一个交互连接后按顺序执行:

docker exec -it redis-primary redis-cli
SET learn:ha:message confirmed
WAIT 1 2000
QUIT

最后 WAIT 应返回 1;返回 0 时写入仍可能已经发生,要按业务定义超时后的处理。

Sentinel 配置与验收#

以下为 sentinel.conf 最小示意,地址应替换为实际主节点在所有 Sentinel 与客户端均可到达的地址:

port 26379
sentinel monitor learning-primary <可达主节点地址> 6379 2
sentinel down-after-milliseconds learning-primary 5000
sentinel failover-timeout learning-primary 60000
sentinel parallel-syncs learning-primary 1

三台 Sentinel 运行 redis-server sentinel.conf --sentinel,配置文件必须可写;还需按部署情况配置认证和地址宣告。不要直接把占位符配置用于启动。

隔离演练验收:停主节点,观察 Sentinel 达到故障判断并选举新主,支持 Sentinel 的客户端重新连接并写入;原主恢复后跟随新主。记录中断时间和缺失写入。容器 NAT 与主机名解析可能影响可达地址,不能只检查“进程已启动”。

实验:最小 Cluster#

仍在宿主机执行,先退出任何 redis-cli:

docker run -d --name redis-cluster-1 --network redis-learning-ha redis:7.4.11 redis-server --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --save "" --appendonly no
docker run -d --name redis-cluster-2 --network redis-learning-ha redis:7.4.11 redis-server --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --save "" --appendonly no
docker run -d --name redis-cluster-3 --network redis-learning-ha redis:7.4.11 redis-server --cluster-enabled yes --cluster-config-file nodes.conf --cluster-node-timeout 5000 --save "" --appendonly no
docker exec redis-cluster-1 redis-cli --cluster create redis-cluster-1:6379 redis-cluster-2:6379 redis-cluster-3:6379 --cluster-replicas 0 --cluster-yes
docker exec redis-cluster-1 redis-cli CLUSTER INFO
docker exec -it redis-cluster-1 redis-cli -c

等待 cluster_state,再在 -c 连接中执行:

SET learn:cluster:{order42}:status paid
SET learn:cluster:{order42}:owner alice
MGET learn:cluster:{order42}:status learn:cluster:{order42}:owner
CLUSTER KEYSLOT learn:cluster:{order42}:status
CLUSTER KEYSLOT learn:cluster:{order42}:owner

预期 MGET 为 paid、alice,两次 KEYSLOT 相同。花括号中的 order42 是 hash tag,保证同槽;跨槽多键命令可能报 CROSSSLOT。-c 支持跟随 MOVED/ASK 路由,普通连接不会自动追随。

常见错误#

  • 把副本当作永不丢数据的备份:误删会同步,故障切换也可能丢未复制写入。
  • 给每个键使用同一个 hash tag:会把数据集中在一个槽,失去分片收益。
  • Cluster 连接只放通 6379:节点间还需要 cluster bus 通信,地址也必须互相可达。
  • 生产使用无副本三主实验结构:一个主节点故障可能影响集群可用性。

练习与参考答案#

计算 learn:cluster:{order99} 的槽,与 order42 比较。它不保证与 order42 同槽,设计按订单 ID 分组有利于同订单原子操作,但跨订单交易需要另外协调。

清理#

先 QUIT,再在宿主机删除本课创建的资源;容器只用于实验,不含业务数据:

docker stop redis-primary redis-replica redis-cluster-1 redis-cluster-2 redis-cluster-3
docker rm redis-primary redis-replica redis-cluster-1 redis-cluster-2 redis-cluster-3
docker network rm redis-learning-ha

官方参考#

复制 · WAIT · Sentinel · Cluster

学习导航#

上一课:Redis 进阶 06:Pub/Sub 与 Streams · 学习目录 · 下一课:Redis 进阶 08:排障、安全与毕业实战

Redis 进阶 07:复制、Sentinel 与 Cluster
作者:LcooYa
CC BY-NC-SA 4.0
相关文章
随机文章