Redis实战-主从复制-哨兵-集群

📅 2026/8/8 9:21:21
Redis实战-主从复制-哨兵-集群
Redis 实战三连击源码编译 主从复制 哨兵高可用 官方集群CentOS 7实战环境CentOS 7.x三台机器IP 规划见下Redis 源码编译安装。目录环境规划一、Redis 源码编译安装CentOS 7二、Redis 主从复制三、高可用方案主从复制 哨兵Sentinel四、Redis 官方集群Redis Cluster五、三大方案对比与选型环境规划角色IP端口node1主192.168.40.1316379 / 26379node2从192.168.40.1326379 / 26379node3从192.168.40.1336379 / 26379主从 哨兵场景用上面的规划官方集群场景会在一台机器上各起 6 个 Redis 实例端口 30001-30006逻辑一样。redis持久化redis有两种持久化方式均通过/etc/下的配置文件配置。RDB(快照)把某一时刻的全量内存数据生成一个二进制的.rdb快照文件有两种触发方式。SAVE主线程阻塞生成RDB大库会卡死业务。BGSAVEfork子进程子进程做快照主进程继续处理业务。生成二进制压缩文件体积小重启恢复速度块适合做备份。不是实例化两次RDB之间的数据可能丢失。AOF记录一条写命令以文本的格式追加到aof日志文件重启时恢复数据。具有AOF重写机制日志内容庞大时不读取旧日志读取当前内存状态重新生成日志文件不会阻塞主进程。数据安全性高默认 everysec 最多丢 1 秒数据。一、Redis 源码编译安装CentOS 7redis源码在执行完make make install后并没有真正意义上的安装成功因为redis具有一软件多实例机制make install只是将软件本体拷贝到了/usr/local/bin下初始化与相关配置仍需要安装。cd到源码编译目录下的utils目录下执行redis-server安装产生报错是因为现代系统不在使用init来管理服务大多数使用systemd,而redis由于历史原因仍然使用init来启动。所以需要修改install_server.sh脚本重新安装执行脚本执行/etc/init.d/redis_6379 start后测试启动成功二、Redis 主从复制2.1 知识点主从复制原理主从复制Replication就是数据冗余 读写分离一个主库Master负责写多个从库Replica同步数据、分担读。redis是异步复制。主从复制的核心流程分为 ** 初始化同步** 和 ** 增量同步 ** 两个阶段初始化同步(首次连接或者连接重启后)从节点向主节点发送SYNC命令。主节点收到命令后执行BGSAVE后台异步生成RDB快照并缓存此过程中的写命令。主节点将RDB文件发送给从节点从节点收到并加载RDB清空原有数据。主节点将缓存的写命令发送给从节点从节点执行这些命令最终与从节点数据一致。增量同步(初始化后持续同步)主节点每执行一次写命令都会将写命令记录到【复制缓冲区】(replication buffer)。从节点通过【偏移量】(offset)记录已同步的命令位置定期向主节点发送ACK 报告自己的同步进度。主节点对比自身偏移量和从节点的偏移量将差值对应的命令发送给从节点。.2.2 部署拓扑一主两从主库无需修改任何配置┌──────────────┐ │ Master │ 192.168.200.101:6379 可读可写 └──────┬───────┘ 异步复制 ┌──────────┴──────────┐ ┌───────┴───────┐ ┌───────┴───────┐ │ Replica-1 Replica-2 │ │ . 102:6379 . 103:6379 │ 只读分担读请求 └───────────────┘ └───────────────┘2.3 配置从库node2、node3在从库的redis.conf里追加一行指向主库# node2 / node3 的 redis-6379.conf 追加 replicaof 192.168.40.131 6379 replica-read-only yes # 从库默认只读防止数据不一致重启从库/etc/init.d/redis-6379 restart注意先启动主库再启动从库。从库首次启动会自动向主库发起全量同步。2.4 功能验证读写分离主库写从库读2.5 知识点主从复制的致命短板主从复制有两个明显的坑主库挂了整个系统只能读不能写——从库是只读的而且不会自动把自己升级为主库需要执行slaveof no one手动把它提升为新主并且是只在内存中生效。从库永远落后主库异步复制主机宕机时可能丢数据。手动故障恢复很痛苦得手动REPLICAOF NO ONE提升一个从库、再让其它从库重新指向它、还要改客户端配置……于是有了哨兵Sentinel。三、高可用方案主从复制 哨兵Sentinel3.1 知识点哨兵是什么Sentinel是一个特殊的Redis进程但是不储存业务数据只做监控投票故障切换工作。也是一个独立运行的 Redis 进程干四件事职责说明监控Monitoring周期性 PING 主库和从库检查存活通知Notification某个节点异常时通知管理员/客户端自动故障转移Automatic Failover主库挂了自动选一个从库提升为主库并让其它从库重新指向新主库配置提供Configuration Provider客户端不用记主库地址问哨兵要当前主库是谁3.2 知识点哨兵的故障转移原理① 心跳与下线判断哨兵每1 秒PING 一次主库每10 秒向主库发一次INFO获取从库列表主观下线sdownSubjective Down某个哨兵发现主库在down-after-milliseconds默认 30s内没回应 PING它自己单方面认为主库挂了客观下线odownObjective Down这个哨兵向其它哨兵发SENTINEL is-master-down-by-addr征询意见当同意的哨兵数≥ quorum时才判定主库确实挂了。知识点为什么要有 sdown/odown 两步单个哨兵可能因自身网络抖动误判比如它自己跟主库的链路断了别人都正常。必须多数哨兵一致才执行故障转移避免“误杀”还在正常工作的主库。② 选举 Leader 哨兵Raft 思想odown 后多个哨兵会竞争成为“执行故障转移”的领导者每个哨兵发起SENTINEL is-master-down-by-addr的同时带上自增的 epoch纪元投票拿到超过一半哨兵票数严格多数n/21的哨兵当选 Leader这就是哨兵集群为什么至少 3 台、且建议奇数的原因——3 台能容忍挂 1 台5 台能容忍挂 2 台。③ 选择新主库Leader 哨兵按以下优先级挑一个从库提升为主库过滤掉断线、超时、被标记为slave-priority的从库slave-priority值越小越优先0 表示永远不参与竞选相同 priority 下复制偏移量offset最大的从库优先数据最新再相同选 runid 最小的。④ 完成切换Leader 哨兵给选中的从库发REPLICAOF NO ONE升为主库等它确认可写后再给其它从库发REPLICAOF 新主IP 新主端口最后把旧主库标记为从库旧主恢复后自动变从。整个过程客户端无感知只需要客户端连哨兵拿主库地址。3.3 哨兵配置文件详解一般哨兵和 Redis 部署在同一批机器上每台机器上跑一个 redis 一个 sentinel省机器。源码目录下提供了sentinel配置文件模板只需要将其拷贝到我们的redis配置文件目录即可三台机器上各建一个哨兵配置# /etc/redis/sentinel.conf port 26379 daemonize yes pidfile /usr/local/redis/run/sentinel-26379.pid logfile /usr/local/redis/logs/sentinel-26379.log dir /usr/local/redis/data # 监控主库sentinel monitor 自定义名 主IP 主端口 quorum sentinel monitor mymaster 192.168.40.131 6379 2 sentinel down-after-milliseconds mymaster 5000 sentinel parallel-syncs mymaster 1 sentinel failover-timeout mymaster 10000配置项讲解配置说明sentinel monitor name ip port quorum监控的主库quorum2表示至少 2 个哨兵同意才判定客观下线down-after-milliseconds超过该时长收不到 PING 回复判 sdownparallel-syncs故障转移后同时允许几个从库去同步新主库设 1 逐个来避免压力failover-timeout故障转移操作超时时间3.4 启动哨兵并验证三台机器各启动# 启动顺序先主后从再依次启动三个哨兵redis-sentinel /etc/redis/sentinel.conf3.5 故障演练kill 掉主库看自动切换# node1 上强制杀掉主库模拟宕机redis-cli shudown观察恢复旧主库把 node1 的 Redis 重新启动/etc/init.d/6379.conf start不用改任何配置——哨兵会自动把恢复的 node1 降级为新主库node2的从库。3.6 知识点哨兵方案的边界与坑数据可能丢失。哨兵只是保“可用性A”不是保“一致性C”。主库宕机时还没同步到从库的写会丢。写能力不扩展。只有一个主库能写写 QPS 到瓶颈时哨兵也救不了——这就轮到官方集群上场了。四、Redis 官方集群Redis Cluster4.1 知识点为什么需要集群主从 哨兵解决了高可用但有两个天花板单机容量一个主库内存有上限单点写写流量全压在一台主库上。Redis Cluster把数据分片到多个主节点上每个节点只存一部分数据写能力水平扩展同时自带主从复制和自动故障转移一套解决“扩展 高可用”。4.2 知识点集群核心原理无中心节点集群中所有的节点地位平等既负责存储数据也参与集群管理(故障检测、槽位分配)避免了“中心节点”的性能瓶颈。数据分片哈希槽Hash Slot集群将所有数据划分为16384个固定数量哈希槽每个节点负责一部分槽位。主从备份每个主节点(负责槽位的节点)可配置一或多个从节点从节点同步主节点数据。当主节点宕机时从节点自动晋升为新主节点保证槽位持续可用。4.3 部署拓扑3 主 3 从官方最小生产拓扑默认redis是开启集群模式的。相关配置也保持默认。4.4 创建集群我们使用源码自带的集群创建脚本在一台机器上模拟集群。并且可以通过修改脚本来创建不同的集群节点。./create-cluster start./create-cluster create查看集群状态最少 3 个主节点。因为故障转移需要“过半主节点投票”3 个主节点能容忍挂 1 个2 个主节点各 50%无法形成多数派永远做不了选举所以集群最少 3 主。4.6 验证集群可以使用redis-cli --cluster help查看命令帮助测试关闭redis实例集群自动切换redis-cli-c-p30001setname world# - Redirected to slot [5798] located at 127.0.0.1:30002 ← 自动跳转# OK#重启redis-cli-c-p30001-a123456get name# world五、三大方案对比与选型维度主从复制主从 哨兵官方集群数据分片水平扩展❌❌✅16384 槽写能力扩展❌❌✅ 多主并行写自动故障转移❌手动✅✅自动数据同步✅✅✅读扩展读写分离✅✅多节点天然分摊读数据一致性最终一致异步最终一致最终一致单点写瓶颈有有无运维复杂度低中高分片、reshard适用场景学习/简单读写分离中小规模、要高可用大数据量/高写入 QPS