3redis集群
Redis集群
Redis Sentinel哨兵机制
简介
- Sentinel(哨兵)进程是用于监控redis集群中Master主服务器工作的状态
- 在Master主服务器发生故障的时候,可以实现Master和Slave服务器的切换,保证系统的高可用(HA)
哨兵进程的作用
- 监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
- 提醒(Notification) : 当被监控的某个Redis节点出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
- 自动故障迁移(Automatic failover) :当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作。
- 它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master
- 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用现在的Master替换失效Master
- Master和Slave服务器切换后,Master的redis.conf、Slave的redis.conf和sentinel.conf的配置文件的内容都会发生相应的改变,即,Master主服务器的redis.conf配置文件中会多一行slaveof的配置,sentinel.conf的监控目标会随之调换。
哨兵进程的配置
- 启动
- 直接使用redis-server ./sentinel.conf –sentinel 来启动哨兵
- redis-sentinel ./sentinel.conf 来启动哨兵
- sentinel monitor mymaster ip port member : 一套哨兵可以监控多套,member 为当前哨兵的权重值
- port 哨兵的端口号
哨兵进程的工作方式
- 每个Sentinel(哨兵)进程以每秒钟一次的频率向整 个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令
- 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)
- 如果一个Master主服务器被 标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态。
- 当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)
- 在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令
- 当Ma ster主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次
- 若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除
Redis Cluster集群
- 集群的使用
- 脚本位置: REDISHOME/utils/create-cluster/
- redis-cli -c -p 任一主机
- 执行redis-cli –cluster start 启动一个集群 // create 去创建一个redis集群
- set {XX}k1 手动设置key将某一个key设置到一个节点中。
- create-cluster脚本说明
- NODES :实例数量
- REPLICAS :从机数量
分区原理
- 带有虚拟节点的一致性哈希分区,Redis Cluster 将数据划分为 16384 个哈希槽(Hash Slot),每个键根据哈希算法分配到特定的槽
- 默认情况下,Redis 使用键的完整字符串计算哈希值(CRC16算法),决定键属于哪个槽。
故障检测及转移
- Cluster 节点之间通过 Gossip 协议通信,持续交换节点状态信息。当某个主节点被大多数节点判定为不可达时,其对应的从节点会自动触发故障转移(
failover),提升为新的主节点。
hash tag
- 用于控制键(Key)的分片规则,确保某些相关联的键被分配到同一个哈希槽(Hash Slot)中
- 所有包含相同 Hash Tag 的键,无论其他部分如何变化,都会被分配到同一个哈希槽,从而存储在同一节点。
优缺点
- 优点
- 1、不再需要额外的Sentinel集群,为使用者提供了一致的方案,减少了学习成本。
- 2、去中心架构,节点对等,集群可支持上千个节点。
- 3、抽象出了slot概念,针对slot进行运维操作。
- 4、副本功能能够实现自动故障转移,大部分情况下无需人工介入。
- 缺点
- 1、客户端要缓存部分数据,实现Cluster协议,相对复杂。
- 2、数据是通过异步复制的,不能保证数据的强一致性。
- 3、资源隔离困难,经常流量不均衡,尤其是多个业务共用集群的时候。数据不知道在哪里,针对热点数据,也无法通过专项优化完成。
- 4、从库是完全的冷备,无法分担读操作,真是太太浪费了。需要做额外工作。
- 5、MultiOp和Pipeline支持有限,老代码要是进行架构升级,要小心了。
- 6、数据迁移是基于key而不是基于slot的,过程较慢。
- 3.0后推出的集群架构
- 架构图
- 结构细节
- 所有的redisj节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽
- 某个节点的fail是通过集群超过半数的节点检测失效时才失效
- 客户端与redis节点直连,不需要中间代理层,客户端不需要连接所有节点,连接集群中任何一个可用节点即可
- redis-cluster把所有的物理节点映射到[0-16383]slot上,cluster 负责维护
- Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value 时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点
Redis Cluster投票:容错
- 最小节点数:3台
- 节点失效判断:集群中所有master参与投票,如果半数以上master节点与其中一个master节点通信超时(cluster-node-timeout),认为该master节点挂掉.
- 集群失效判断:什么时候整个集群不可用(cluster_state:fail)?
- 如果集群任意master挂掉,且当前master没有slave,则集群进入fail状态。也可以理解成集群的[0-16383]slot映射不完全时进入fail状态。
- 如果集群超过半数以上master挂掉,无论是否有slave,集群进入fail状态
集群配置
- redis集群需要使用集群管理脚本redis-trib.rb,它的执行相应依赖ruby环境
哨兵和集群模式对比
| 维度 | 哨兵模式 | 集群模式 |
|---|---|---|
| 设计目标 | 高可用性(主从故障转移) | 高可用性 + 数据分片(分布式存储与扩展) |
| 数据分片 | 不支持,数据集中存储于主节点 | 支持,数据按哈希槽分布到多个节点 |
| 读写能力 | 仅主节点可写,从节点只读 | 所有节点均可读写,负载均衡 |
| 扩展性 | 垂直扩展(增加从节点实现读分离) | 水平扩展(通过增加节点提升整体容量与性能) |
| 配置复杂度 | 简单,仅需配置哨兵节点与主从关系 | 复杂,需管理分片、节点间通信及数据迁移 |
| 故障恢复 | 主节点故障时切换从节点,可能短暂不可用 | 节点故障时自动迁移数据,服务持续(可能数据不一致) |
| 客户端支持 | 需适配哨兵协议获取主节点地址 | 需支持集群协议,直接路由到对应节点 |
Redis消息模式
队列模式
使用list类型的lpush和rpop实现消息队列
注意事项
- 消息接收方如果不知道队列中是否有消息,会一直发送rpop命令,如果这样的话,会每一次都建立一次连接,这样显然不好,可以使用brpop命令,它如果从队列中取不出来数据,会一直阻塞,在一定范围内没有取出则返回null
发布订阅模式
- 发布消息
分布式锁Redisson
Redlock
- https://redis.io/docs/latest/develop/use/patterns/distributed-locks/
- 在分布式系统中,传统的Redis单节点或主从架构下实现分布式锁存在异步复制导致锁失效的风险。例如:客户端A在主节点加锁成功后,若主节点宕机且数据未同步到从节点,此时新主节点无锁记录,客户端B可能再次加锁成功,导致两个客户端同时持有锁
- RedLock是Redis作者Antirez提出的分布式锁算法,旨在通过多独立Redis主节点协作解决这一问题。其核心思想是:
- 多数派原则:客户端需在超过半数(N/2+1)的独立Redis主节点上成功加锁,才算全局加锁成功。
- 时钟同步:通过时间戳控制锁的有效期,避免因网络延迟或节点故障导致锁超时失效
工作流程
- 获取时间戳:客户端记录当前时间戳T1,作为加锁起始时间。
- 依次加锁:向N个独立的Redis主节点发送加锁请求,每个请求包含:
- 唯一键值对:锁的Key和全局唯一值(如UUID+线程ID)。
- 超时时间:锁的自动释放时间(如30秒)。
- 网络超时:单节点加锁的超时时间(如5-50ms)。
- 校验结果:
- 成功条件:在N/2+1个节点加锁成功,且总耗时小于锁的超时时间(即T2-T1 < TTL)。
- 失败处理:若未满足条件,立即向所有节点发送解锁请求。
- 锁续期:若业务执行时间较长,需通过后台线程(如Redisson的看门狗机制)定期续期锁。
Redisson
- Redisson是Java中广泛使用的Redis客户端,其
RedissonRedLock类封装了RedLock算法,并扩展了可重入锁、自动续期等特性。
分布式读写锁
- 基于 Redis 的 Redisson 分布式可重入读写锁
RReadWriteLockJava 对象实现了java.util.concurrent.locks.ReadWriteLock接口。其中读锁和写锁都继承了RLock接口
看门狗自动续期
- 续期机制:默认每10秒检查锁状态,若业务未完成,将锁的TTL重置为30秒37。
- 避免锁超时:防止因业务执行时间过长导致锁提前释放。
3redis集群
https://x-leonidas.github.io/2025/10/26/05数据库/redis/3redis集群/