当前位置: 首页 > ds >正文

Redis设计与实现——分布式Redis

Redis Sentinel(哨兵)

Sentinel 的工作机制
  • 故障检测(Failure Detection)

    • 主观下线(Subjective Down):单个 Sentinel 实例检测到主节点在30 秒内无响应,标记其为 SDOWN

    • 客观下线(Objective Down):当超过 quorum的 Sentinel 实例确认主节点不可达,标记为 ODOWN,触发故障转移。

  • 领导者选举(Leader Election)

    • Raft 算法:Sentinel 使用类似 Raft 的算法选举领头 Sentinel(Leader),由 Leader 执行故障转移。

    • 选举条件:获得多数 Sentinel 实例的投票(> N/2 + 1,N 为 Sentinel 总数);避免多个 Sentinel 同时发起故障转移。

  • 故障转移(Failover)流程

    • 选择新主节点:Leader Sentinel 根据规则从从节点中选出新主节点:

      优先级(slave-priority 配置);复制偏移量最大(数据最新);运行 ID 字典序最小(最终裁决条件)。

    • 提升新主节点:向目标从节点发送 SLAVEOF NO ONE,使其成为主节点;等待新主节点确认角色切换。

    • 切换从节点复制关系:向其他从节点发送 SLAVEOF 命令,使其复制新主节点。

    • 更新配置:Sentinel 更新监控的主节点地址,并通知客户端。

  • 客户端服务发现

    • 连接流程:客户端向 Sentinel 查询当前主节点地址;客户端直接连接主节点,失败时重试查询。

    • SDK 支持:主流 Redis 客户端库(如 Jedis、Lettuce)内置 Sentinel 集成。

Sentinel 的架构与部署
  • Sentinel 部署模式

    • 推荐配置:至少部署 3 个 Sentinel 实例(奇数个,避免脑裂),分布在独立物理节点。

    • 网络拓扑:Sentinel 实例与 Redis 节点部署在同一网络,避免分区误判;Sentinel 之间通过 Gossip 协议通信,共享节点状态。

  • Sentinel 与 Redis 节点的关系

    • 监控对象:每个 Sentinel 监控 一个主节点及其所有从节点

    • 自动发现:Sentinel 通过主节点获取从节点列表,并持续监控其状态。

Sentinel 的优缺点
  • 优点

    • 自动化容灾:无需人工干预即可完成故障转移。

    • 高可用:Sentinel 自身多实例部署,避免单点故障。

    • 客户端透明:客户端通过 Sentinel 自动发现主节点,业务代码无需硬编码地址。

  • 缺点

    • 数据一致性:异步复制可能导致故障转移后数据丢失(已提交但未同步到从节点的数据)。

    • 复杂度:需部署多个 Sentinel 实例,配置和维护成本较高。

    • 脑裂风险:网络分区可能导致多个主节点并存(需合理配置 quorum 和节点分布)。

生产环境建议
  • 部署最佳实践

    • Sentinel 数量:至少 3 个实例,部署在独立物理节点或可用区。

    • 网络优化:确保 Sentinel 与 Redis 节点间低延迟通信,避免跨地域部署。

    • 监控告警:监控 Sentinel 日志和 INFO Sentinel 输出,关注 odown 事件和故障转移次数。

  • 避免脑裂的配置

    • 合理设置quorum:通常设为 N/2 + 1(N 为 Sentinel 总数)。

    • 调整min-slaves-to-write:主节点需至少同步到指定数量的从节点才接受写操作。

  • 客户端容错

    • 重试策略:客户端应实现重试逻辑,处理故障转移期间的短暂不可用。

    • 多语言 SDK:选择支持 Sentinel 的客户端库(如 Java 的 Jedis、Python 的 redis-py)。

常用命令
  • SENTINEL masters:查看主节点信息。
  • SENTINEL slaves {master}:查看从节点信息。
  • SENTINEL failover {master}:强制触发故障转移(无需ODOWN)。
  • SENTINEL sentinels {master}:查看 Sentinel 节点列表。

Redis集群

集群的架构与数据分片
  • 哈希槽(Hash Slot)分配

    • 分片规则:对键的 CRC16 值取模(CRC16(key) % 16384)确定所属槽位。

    • 哈希标签(Hash Tag):使用 {} 指定部分键名计算哈希值,强制相关键分配到同一槽。

    • 槽分配管理:集群启动时,槽均匀分配到主节点,可通过 CLUSTER ADDSLOTS 手动分配或自动平衡。

  • 节点角色

    • 主节点(Master):负责处理槽的读写请求,参与故障选举。

    • 从节点(Replica):复制主节点数据,主节点故障时接替其槽。

    • 集群模式节点:所有节点默认开启集群模式(cluster-enabled yes)。

  • 集群拓扑

    • 最小部署:至少 3 个主节点(每个主节点至少 1 个从节点),共 6 个节点。

    • 节点发现:节点通过 Gossip 协议交换状态信息(如 MEET 命令将节点加入集群)。

集群的工作机制
  • 客户端请求路由

    • Smart Client:客户端缓存槽与节点的映射关系,直接向目标节点发送请求,若节点返回MOVED重定向错误,更新缓存并重试。

    • Dumb Client:依赖代理(如 Redis Proxy)转发请求,客户端无需感知集群拓扑。

  • 数据读写流程

    • 键存在目标槽:直接由负责该槽的节点处理。

    • 键不在目标槽:返回 MOVED 错误,客户端重定向到正确节点。

    • 槽迁移中:返回 ASK 错误,客户端临时重定向到迁移目标节点。

  • 故障转移(Failover)

    • 主观下线(PFAIL):节点 A 在 cluster-node-timeout(默认 15 秒)内未收到节点 B 的响应,标记 B 为 PFAIL

    • 客观下线(FAIL):超过半数主节点确认节点 B 不可达,标记为 FAIL,触发故障转移。

    • 从节点选举:从节点发起选举,获得多数主节点投票后成为新主节点;接管原主节点的槽,并广播更新集群配置。

  • 数据迁移与平衡

    • 手动迁移:使用 CLUSTER SETSLOT <slot> IMPORTING/MIGRATING 命令迁移槽。

    • 自动平衡:通过 redis-cli --cluster rebalance 自动调整槽分布,均衡负载。

集群的优缺点
  • 优点

    • 水平扩展:支持 TB 级数据和高并发访问。

    • 高可用:自动故障转移,数据多副本存储。

    • 去中心化:无单点故障,节点自治。

  • 缺点

    • 功能限制:不支持跨槽事务、部分命令受限(如 KEYS *)。

    • 运维复杂度:需管理分片、迁移、节点扩缩容。

    • 客户端兼容性:需使用集群感知的客户端或代理。

生产环境建议
  • 部署与配置

    • 节点规划:主节点至少 3 个,跨物理机或可用区部署,从节点数 ≥ 主节点数。

    • 网络优化:确保节点间低延迟通信,避免跨地域部署。

    • 内存管理:监控节点内存使用,避免数据倾斜导致单个节点过载。

  • 数据均衡

    • 预分片:设计键时使用哈希标签,确保相关数据集中。

    • 定期平衡:使用 redis-cli --cluster rebalance 调整槽分布。

  • 监控与故障排查

    • 关键指标

      CLUSTER INFO        # 查看集群健康状态
      CLUSTER NODES       # 查看节点角色、槽分配、状态
      INFO memory         # 监控内存使用
      
    • 日志分析:关注 CLUSTERDOWN 告警和节点超时事件。

常用集群命令
  • CLUSTER NODES:查看集群节点信息。
  • CLUSTER INFO:检查集群状态。
  • CLUSTER FAILOVER:手动故障转移(从节点执行)。
Sentinel 与 Cluster 的对比
特性SentinelCluster
数据分片不支持,需客户端或代理分片。内置分片(16384 槽)。
高可用主从复制 + 故障转移。每个分片主从复制,自动故障转移。
扩展性垂直扩展(主节点性能瓶颈)。水平扩展(支持大规模数据集和高吞吐)。
适用场景中小规模,非分片架构。大规模数据,高并发场景。

Redis复制

主从复制的建立流程
  • Redis 复制的建立分为 全量同步(Full Sync)部分同步(Partial Sync) 两种模式,优先尝试部分同步以减少资源消耗。

  • 从节点初始化连接

    • 命令触发:从节点执行 SLAVEOF <master-ip> <master-port>,开启复制流程。

    • 连接主节点:从节点向主节点发起连接,发送 PING 确认网络可达性。

  • 身份验证(可选):若主节点配置了 requirepass,从节点需发送 AUTH <password> 完成认证。

  • 同步数据集

    • 全量同步(SYNC)

      主节点生成当前数据的 RDB 快照,通过子进程写入磁盘。

      将 RDB 文件发送给从节点,同时缓存期间的写命令至 复制缓冲区(Replication Buffer)

      从节点接收 RDB 并加载到内存,再执行缓冲区中的写命令,追上主节点状态。

    • 部分同步(PSYNC)

      从节点发送 PSYNC <replid> <offset>,携带自身记录的复制 ID 和偏移量。

      主节点检查复制 ID 和偏移量是否匹配历史记录:

      匹配:发送 +CONTINUE,传输从偏移量之后的写命令(利用 复制积压缓冲区)。

      不匹配:触发全量同步(+FULLRESYNC)。

  • 命令传播(Command Propagation):同步完成后,主节点持续将写命令发送给从节点,保持数据一致。

复制的核心机制
  • 复制ID与偏移量

    • 复制ID(Replication ID):主节点的唯一标识,每次主节点重启或角色变更时生成新 ID。

    • 偏移量(Offset):主从节点各自维护一个偏移量,记录已复制的数据量。

  • 复制积压缓冲区(Replication Backlog)

    • 作用:主节点维护一个固定大小的环形缓冲区(默认 1MB),缓存最近的写命令。

    • 触发部分同步:若从节点的偏移量在缓冲区范围内,直接发送增量数据。

    • 配置参数

      repl-backlog-size 1mb     # 缓冲区大小
      repl-backlog-ttl 3600     # 主节点无连接时缓冲区保留时间(秒)
      
  • 心跳检测与断线重连

  • 心跳机制:主从节点定期确认存活状态和复制进度;主节点超时未收到心跳(默认 60 秒)则认为从节点下线。

  • 断线处理:从节点重连后尝试部分同步,失败则触发全量同步。

复制拓扑与高级特性
  • 级联复制(主-从-从)

    • 场景:主节点连接过多从节点时,可通过级联复制分摊压力。

    • 配置:将从节点(Slave A)作为另一从节点(Slave B)的主节点。

  • 延迟副本(Lagging Replica)

    • 作用:人为设置从节点延迟同步,用于误操作恢复(需第三方工具支持)。

    • 实现:通过 slave-repl-delay 配置延迟时间(Redis 自身不原生支持,需外部控制)。

复制的问题与优化
  • 全量同步的资源消耗

    • 问题:大数据集时生成和传输 RDB 文件会阻塞主节点并占用带宽。

    • 优化:增大 repl-backlog-size 减少全量同步概率;使用无盘同步(repl-diskless-sync yes),但需主节点内存充足。

  • 复制延迟

    • 原因:网络延迟、从节点负载过高或主节点写入压力大。

    • 监控:通过 INFO replicationslave_repl_offsetmaster_repl_offset 差值判断延迟。

    • 优化:提升网络带宽,减少主从节点跨地域部署;限制主节点写入速率(如使用管道批量写入)。

  • 数据不一致

    • 原因:主从网络中断导致部分数据未同步。

    • 检测:使用 redis-cli --slave 模拟从节点检查数据差异。

    • 修复:手动触发全量同步(SLAVEOF NO ONE + 重新配置复制)。

http://www.xdnf.cn/news/6938.html

相关文章:

  • 共享内存【Linux操作系统】
  • Go语言语法---输入控制
  • Node.js 源码架构详解
  • [system-design] ByteByteGo_Note Summary
  • 如何开发专业小模型
  • 强化学习赋能医疗大模型:构建闭环检索-反馈-优化系统提升推理能力
  • 数据库实验报告 数据定义操作 3
  • 【leetcode】逐层探索:BFS求解最短路的原理与实践
  • 使用Python和Selenium打造一个全网页截图工具
  • CSS- 4.1 浮动(Float)
  • Echart地图数据源获取
  • hysAnalyser 从MPEG-TS导出ES功能说明
  • 【C++详解】string各种接口如何使用保姆级攻略
  • Kotlin变量与数据类型详解
  • C++ - 仿 RabbitMQ 实现消息队列(2)(Protobuf 和 Muduo 初识)
  • DeepSeek 赋能军事:重塑现代战争形态的科技密码
  • Florence2代码实战
  • 初识计算机网络。计算机网络基本概念,分类,性能指标
  • 终端和shell , 以及XShell 用ssh命令登陆主机的过程
  • Spring三级缓存的作用与原理详解
  • 内网环境下如何使用ntpdate实时同步时间
  • java+selenum专题(一)
  • Java 与 面向对象编程(OOP)
  • dify知识库支持图文回复实践
  • 【Win32 API】 lstrcpynA()
  • 浮动静态路由配置实验
  • 使用 Cookie 实现认证跳转功能
  • 用Python绘制梦幻星空
  • 5.9/Q1,GBD数据库最新文章解读
  • 华三H3C交换机配置NTP时钟步骤 示例