行业资讯

redis高可用演练

发布时间:2026/7/23 7:54:39
redis高可用演练 redis高可用三种模式演练主从模式1.在WSL环境中基于docker搭建redis演练专用networkdockernetwork create redis-netdocker network create redis-net 是在创建一个“私有的局域网”让 Redis、Sentinel 这些容器在一个可控、稳定、可互相解析主机名的网络里通信而不是依赖宿主机的端口映射。如果不搭建该子网络后果是什么Docker 会给你一个默认的bridge网络容器之间可以通过 IP 通信但是不能用容器名当 hostnameIP 每次重启可能变Sentinel 配置里写死 IP → 容器一重启就炸。2.启动Master、slave1、slave2三个节点主节点dockerrun-d\--nameredis-master\--networkredis-net\-p6379:6379\redis:7\redis-server--port6379从节点slave1dockerrun-d\--nameredis-slave1\--networkredis-net\-p6380:6379\redis:7\redis-server\--port6379\--replicaofredis-master6379slave2–关键命令 replicationofdocker run -d \ --name redis-slave2 \ --network redis-net \ -p 6381:6379 \ redis:7 \ redis-server \ --port 6379 \ --replicaof redis-master 6379启动完成后可以使用docker ps 查看3个容器实例是否正确运行3 检查状态和测试3.1进入 Master检查Master状态docker exec -it redis-master redis-cli执行info replication重点看role:master connected_slaves:2下面应该有slave0: ip172.xx.xx.xx port6379 slave1: ip172.xx.xx.xx port6379说明Master | -- Slave1 | -- Slave2成功。3.2从Master写数据从节点查看Masterdocker exec -it redis-master redis-cli执行set username qians返回OKSlave1//需要先从主节点退出来再进入从节点查看,快捷键CtrlD,快速退出 docker exec -it redis-slave1 redis-cli执行get username应该qiansSlave2docker exec -it redis-slave2 redis-cli执行get username应该qians4.测试从节点写入限制先梳理清楚主从模式下redis主节点可读可写从节点只可以读这也说明了从节点只能作为数据备份提高redis集群的可用性但是在性能上仍然不足。并且主从模式只负责同步不负责故障转移也就意味着主节点宕机系统也就无法正常工作。后续的Sentinel和Cluster会补足这部分缺失并且进行更多的扩展。进入 slavedocker exec -it redis-slave1 redis-cli执行set age 18应该报(error) READONLY You cant write against a read only replica.说明数据同步成功主从角色正确5.观察复制偏移量-offset模拟Master宕机这是 Redis 主从复制的核心机制。Masterinfo replication关注三个节点的offsetmaster_repl_offset:12345这是非常重要的一步。现在停止 Masterdocker stop redis-master查看docker ps现在redis-master 停止 redis-slave1 运行 redis-slave2 运行进入 Slavedocker exec -it redis-slave1 redis-cli执行get username你应该还能看到qians说明数据仍然存在。但是执行set name test会失败READONLY You cant write against a read only replica因为当前结构❌ Master 6379 Slave1 Slave2 6380 6381Redis 不会自动提升。Sentinel-哨兵模式Sentinel 负责监控 Master 是否故障判断是否需要故障转移选举新的 Master1.创建Sentinel配置目录查看docker ps应该类似redis-master redis-slave1 redis-slave2如果之前关闭了 masterdocker start redis-master先恢复。创建mkdir ~/redis-sentinel cd ~/redis-sentinel创建三个配置mkdir sentinel1 sentinel2 sentinel3结构redis-sentinel ├── sentinel1 │ └── sentinel.conf │ ├── sentinel2 │ └── sentinel.conf │ └── sentinel3 └── sentinel.conf2.编写Sentinel配置进入nano sentinel1/sentinel.conf写入port 26379 sentinel monitor mymaster redis-master 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel failover-timeout mymaster 10000 sentinel parallel-syncs mymaster 1解释monitorsentinel monitor mymaster redis-master 6379 2含义监控名字: mymaster Master地址: redis-master:6379 2: 至少两个 Sentinel 认为挂了才执行故障转移down-after5000表示5秒没有响应认为主节点异常。复制配置cp sentinel1/sentinel.conf sentinel2/ cp sentinel1/sentinel.conf sentinel3/然后分别修改端口sentinel2nano sentinel2/sentinel.conf改port 26380sentinel3nano sentinel3/sentinel.conf改port 263813.启动Sentinel容器3.1启动Sentinel1docker run -d \ --name sentinel1 \ --network redis-net \ -p 26379:26379 \ -v ~/redis-sentinel/sentinel1/sentinel.conf:/etc/redis/sentinel.conf \ redis:7 \ redis-server /etc/redis/sentinel.conf --sentinelSentinel2docker run -d \ --name sentinel2 \ --network redis-net \ -p 26380:26379 \ -v ~/redis-sentinel/sentinel2/sentinel.conf:/etc/redis/sentinel.conf \ redis:7 \ redis-server /etc/redis/sentinel.conf --sentinelSentinel3docker run -d \ --name sentinel3 \ --network redis-net \ -p 26381:26379 \ -v ~/redis-sentinel/sentinel3/sentinel.conf:/etc/redis/sentinel.conf \ redis:7 \ redis-server /etc/redis/sentinel.conf --sentinel3.2检查Sentinel是否发现Master主节点进入 Sentineldocker exec -it sentinel1 redis-cli -p 26379执行sentinel masters应该看到name mymaster ip redis-master port 6379查看 Slavesentinel slaves mymaster应该看到redis-slave1 redis-slave2说明Sentinel | 发现 | Master | 发现 | Slave坑点Redis Sentinel 配置文件权限问题在使用 Docker 部署 Redis Sentinel 时一个常见的问题是Sentinel 容器启动后立即退出并提示配置文件不可写Sentinel config file /etc/redis/sentinel.conf is not writable: Permission denied. Exiting...这个问题的核心原因是通过 Docker Volume 挂载 Sentinel 配置文件时-v ~/redis-sentinel/sentinel1/sentinel.conf:/etc/redis/sentinel.conf容器中的/etc/redis/sentinel.conf实际上对应宿主机WSL中的~/redis-sentinel/sentinel1/sentinel.conf因此Sentinel 对配置文件的读写权限取决于宿主机文件的权限。解决办法实验环境中可以直接修改权限chmod 777 sentinel.conf让 Sentinel 拥有读取权限修改权限然后重新启动容器即可。更规范的生产方式生产环境不建议直接使用chmod 777更推荐修改文件所属用户使 Redis 进程拥有权限chown redis:redis sentinel.conf挂载整个目录而不是单个文件宿主机目录 | ↓ /data/sentinel/ | sentinel.conf这样 Sentinel 可以正常管理相关配置文件。4.模拟主节点宕机查看故障转移第一步记录当前 Master现在Master: 172.21.0.2:6379也就是redis-master第二步写入测试数据打开 Masterdocker exec -it redis-master redis-cli执行set name sentinel-test查看get name应该sentinel-test退出exit第三步模拟 Master 宕机执行docker stop redis-master现在redis-master X redis-slave1 redis-slave2第四步观察 Sentinel 故障转移等待大约 10~20 秒。然后docker exec -it sentinel1 redis-cli -p 26379执行sentinel get-master-addr-by-name mymaster原来172.21.0.2 6379应该变成172.21.0.3 6379或者172.21.0.4 6379第五步确认角色变化分别查看slave1docker exec -it redis-slave1 redis-cli info replicationslave2docker exec -it redis-slave2 redis-cli info replication新的 Master 会显示role:master另一个role:slave你马上会看到一个非常重要的现象原来的redis-master | ---- slave1 ---- slave2变成redis-slave1 | ---- redis-slave2或者redis-slave2 | ---- redis-slave1也就是说Sentinel 不只是发现故障而是自动完成角色切换。附Redis Sentinel 故障转移机制总结Redis Sentinel 的核心作用是监控 Redis 主从节点状态当 Master 发生故障时通过多个 Sentinel 节点协商自动选举新的 Master并让其他 Slave 重新复制新的 Master实现自动故障恢复。整个故障转移过程可以分为以下几个阶段1. 节点监控MonitoringSentinel 会持续向 Redis 节点发送心跳检测Sentinel | | PING ↓ Redis Master / Slave通过检测节点是否响应判断节点状态。Sentinel 监控的信息包括Master 是否存活Slave 是否正常其他 Sentinel 是否在线Redis 节点之间的复制关系例如正常状态Sentinel集群 S1 S2 S3 \ | / | | Master | -------------- | | Slave1 Slave22. 主观下线SDOWN当某个 Sentinel 连续检测不到 Master 响应时例如Sentinel1: PING Master 无响应此时 Sentinel1 会认为Master可能故障状态变为SDOWN Subjectively Down含义当前 Sentinel 自己认为 Master 下线。注意此时不会立即故障转移。因为网络可能临时异常当前 Sentinel 可能自身异常可能只是一次通信失败所以需要其他 Sentinel 判断。3. 客观下线ODOWNSentinel 会向其他 Sentinel 请求确认例如Sentinel1: Master挂了 Sentinel2: Master挂了 Sentinel3: Master正常根据配置sentinel monitor mymaster 172.21.0.2 6379 2最后的2代表quorum 2表示至少需要 2 个 Sentinel 认为 Master 下线。满足条件确认数量 quorum状态升级SDOWN | ↓ ODOWN即Objectively Down 客观下线此时 Sentinel 集群确认Master 确实故障4. Sentinel Leader 选举进入故障转移后多个 Sentinel 需要选出一个负责人。例如Sentinel1 Sentinel2 Sentinel3通过 Sentinel 内部选举Sentinel Leader | | 执行 Failover选出的 Leader 负责选择新的 Master修改复制关系通知其他节点其他 Sentinel 负责提供投票同步状态5. 选择新的 MasterLeader Sentinel 会从 Slave 节点中选择候选者。例如原结构Master | ---- Slave1 | ---- Slave2Master 宕机X Slave1 Slave2Sentinel 会根据多个因素选择① Slave 优先级Redis 配置replica-priority 100优先级越高越容易被选为 Master。例如Slave1 priority100 Slave2 priority200优先选择 Slave1。② 复制偏移量offset判断哪个 Slave 数据最新。例如Slave1 offset: 10000 Slave2 offset: 8000Slave1 数据更完整。优先选择Slave1③ Run ID如果前面条件相同比较 Redis runid。保证最终只有一个节点被选中。6. Slave 提升为 Master选中的 Slave 执行SLAVEOF NO ONE角色变化之前Slave1 | 复制 Master之后Slave1 角色: Master例如redis-slave1 | ↓ 新的 Master7. 修改其他 Slave 复制关系原来旧 Master | ----------- | | Slave1 Slave2旧 Master 宕机X Slave1 Slave2假设 Slave1 成为新 MasterSentinel 通知Slave2 | ↓ 复制新的 Master Slave1最终New Master | | Slave28. 更新 Sentinel 配置故障转移完成后Sentinel 会修改自己的状态例如旧Master: 172.21.0.2:6379新Master: 172.21.0.3:6379同时更新Master 地址Slave 信息Sentinel 状态epoch 编号这些信息会写回sentinel.conf所以 Sentinel 配置文件必须可写。完整流程图Redis Sentinel故障转移流程 Master故障 | ↓ Sentinel持续PING检测 | ↓ 某个Sentinel发现异常 | ↓ SDOWN 主观下线 | ↓ Sentinel之间互相确认 | ↓ ODOWN 客观下线 | ↓ Sentinel Leader选举 | ↓ 选择最佳Slave节点 | ↓ Slave升级为Master | ↓ 其他Slave重新复制新Master | ↓ Sentinel更新拓扑信息Cluster-集群模式Redis Cluster 和 Sentinel 的定位不一样模式解决的问题主从复制数据备份、读扩展Sentinel主节点故障自动切换Redis Cluster数据分片 高可用 横向扩展Redis Cluster 是 Redis 官方提供的分布式数据库方案用于解决单机 Redis 在数据容量、吞吐量、可用性方面的限制。它通过数据分片Sharding节点间通信Cluster Bus主从复制Replication自动故障转移Failover实现一个去中心化的 Redis 分布式集群。1. 分片集群1.1 为什么需要分片集群传统 Redis 主从结构Master / \ Slave1 Slave2所有数据都存储在 Master 节点。例如业务数据 用户信息 500GB 单机 Redis: 最大内存 64GB问题单节点存储容量有限单节点 CPU 处理能力有限写请求无法通过增加 Slave 扩展因为Slave 只能读扩展写请求: Client | Master所有写操作仍然集中到 Master。因此需要将数据拆分到多个 Redis 节点中每个节点负责一部分数据。这就是分片集群。1.2 Redis Cluster 的分片思想Redis Cluster 不采用key - 节点这种直接映射。而采用key | slot | 节点流程key | | CRC16(key)%16384 | slot | Redis节点Redis Cluster 将整个数据空间划分为16384 个槽(slot)范围0 ~ 16383每个 Master 节点负责一部分 slot。例如三个 MasterNode1: 0 - 5460 Node2: 5461 - 10922 Node3: 10923 - 16383因此keyuser:100 计算 CRC16(user:100)%16384 得到 5000 5000属于Node1最终user:100 | ↓ Node12. 集群搭建Redis Cluster 最小要求最少节点数量理论3 Master原因需要至少三个节点分配全部 slotNode1 0-5460 Node2 5461-10922 Node3 10923-16383但是生产环境通常3 Master 3 Slave即Cluster Master1 Master2 Master3 | | | Slave1 Slave2 Slave3原因Master 故障后Slave 可以提升。2.1 Cluster 节点配置开启集群cluster-enabled yes指定节点配置文件cluster-config-file nodes.conf设置节点超时时间cluster-node-timeout 5000开启 AOFappendonly yes启动后Redis 会生成nodes.conf保存节点 ID节点状态slot 分配节点关系2.2 创建 Cluster启动多个 Redis例如7001 7002 7003 7004 7005 7006此时它们只是6个独立Redis还没有关系。通过redis-cli --cluster create完成节点握手slot 分配主从绑定例如7001 7002 7003 成为Master 7004 7005 7006 成为Slave3. 节点间通信Redis Cluster 是去中心化架构。不存在中心节点 | | 管理所有节点每个节点都保存部分集群信息。节点之间通过Cluster Bus通信。Redis Cluster 使用两个端口例如Redis端口7001Cluster Bus17001规则Bus端口 Redis端口 100003.1 Gossip 协议Redis Cluster 使用 Gossip 协议进行节点信息传播。特点节点之间随机交换状态信息使整个集群最终达到一致。例如三个节点NodeA NodeB NodeCNodeA知道NodeB正常NodeA通过 Gossip告诉 NodeC。最终所有节点知道 NodeA NodeB NodeC 状态Gossip 传播的信息包括节点是否在线节点角色节点地址slot 信息epoch 信息3.2 节点间的数据交换Redis Cluster 节点之间主要交换1. 节点状态例如Node1: master online2. slot 信息例如Node1: 负责: 0-54603. 故障信息例如Node2: 认为Node3失败通知其他节点。注意Redis Cluster 节点之间不会自动同步全部数据。数据同步依赖Master-Slave复制例如Master1 | | Slave13.3 为什么集群规模不是越大越好Redis Cluster 节点数量增加会带来成本1. Gossip 通信增加节点越多需要交换的信息越多。2. 故障检测成本增加更多节点意味着更多状态需要维护。3. 数据迁移复杂度增加扩容时slot 需要迁移。例如新增节点Node4加入需要Node1 迁移部分slot ↓ Node4因此Redis Cluster 并不是无限扩展。官方建议集群规模应该根据数据量QPS运维能力设计。4. 哈希槽4.1 哈希槽分配Redis Cluster 固定16384 slots创建集群时slot 被分配给 Master。例如Master1: 0-5460 Master2: 5461-10922 Master3: 10923-16383每个 slot 只能属于一个 Master。4.2 Key 是如何路由的客户端访问SET user:100 Tom客户端计算slot CRC16(user:100)%16384得到5000查询slot 5000属于Node1发送Node1: SET user:100 TomRedis Cluster 客户端通常需要cluster-aware client例如JavaJedisCluster Lettuce Cluster它们会缓存slot - node映射。4.3 请求到了错误的节点怎么办例如客户端认为slot 5000 属于Node1但是实际上slot5000已经迁移到Node2请求 Node1GET user:100Node1返回MOVED格式MOVED slot ip:port例如MOVED 5000 192.168.1.20:7002含义这个 slot 已经属于另一个节点请客户端重新发送。ASKASK 出现在slot 正在迁移过程中。例如Node1 slot5000 正在迁移 ↓ Node2此时Node1可能返回ASK区别命令含义MOVED永久迁移完成ASK临时迁移过程中4.4 集群环境如何批量操作Redis Cluster 不支持传统KEYS *跨节点执行。原因数据分散Node1 Node2 Node3需要分别查询。常用方式方案1遍历节点node1 scan node2 scan node3 scan方案2使用支持 Cluster 的工具。4.5 为什么基于哈希槽而不是一致性哈希Redis Cluster 没有采用一致性哈希。原因Redis 更希望slot 数量固定节点负责 slot节点变化时迁移 slot优势1. 易于管理知道哪个节点负责哪些slot2. 扩容简单新增节点只需要迁移部分slot3. 故障转移方便slot 与节点绑定。4.6 为什么槽数量是16384Redis 官方选择16384主要考虑1. 节点规模如果槽过多节点间传播信息增加。2. 精度16384 可以支持较细粒度的数据分布。3. 集群规模Redis Cluster 面向几十到几百节点规模。16384 足够。5. 扩容缩容5.1 数据迁移新增节点例如Node1 Node2 Node3 新增: Node4需要迁移 slotNode1 slot 1000 ↓ Node4迁移过程中数据逐步移动。5.2 ASK 响应与 ASKING 请求迁移阶段客户端访问旧节点旧节点ASK 1000 Node4客户端先发送ASKING然后GET key告诉目标节点这是一次迁移中的访问。6. 故障转移6.1 故障检测Redis Cluster 使用节点之间通信检测故障。流程Node1发现Node2无响应 | 标记疑似失败 | 通知其他节点 | 多数节点确认 | Fail6.2 节点下线后集群还能运行吗取决于故障节点是否持有 slot。例如Master1挂Master1 负责: 0-5460如果没有 Slaveslot不可用集群部分不可用。如果有 SlaveSlave提升Master恢复。6.3 主从切换过程Master故障 ↓ Slave检测 ↓ 参与选举 ↓ 获得多数票 ↓ 升级Master ↓ 接管slot总结Redis Cluster 解决的是单机Redis容量和吞吐瓶颈核心机制数据分片: key | slot | node 节点通信: Gossip 数据复制: Master-Slave 故障恢复: 自动Failover与 Sentinel 最大区别SentinelCluster主要目标高可用分布式存储数据分布单Master全部数据slot分片节点数量主从结构多个Master故障转移Sentinel负责Cluster内部完成扩容困难slot迁移Redis Cluster 本质上是通过哈希槽实现数据水平拆分通过节点通信维护集群状态通过主从复制和自动选举保证高可用的 Redis 分布式系统。