Redis集群部署详解:主从复制、Sentinel哨兵模式与Cluster集群的工作原理与配置

集群部署形式

    • 1、主从复制
      • [1.1 工作机制](#1.1 工作机制)
      • [1.2 配置实现](#1.2 配置实现)
      • [1.3 优缺点](#1.3 优缺点)
      • [1.4 部署形式](#1.4 部署形式)
      • [1.5 主从复制优化](#1.5 主从复制优化)
    • [2、Sentinel 哨兵模式](#2、Sentinel 哨兵模式)
      • [2.1 工作机制](#2.1 工作机制)
      • [2.2 配置实现](#2.2 配置实现)
      • [2.3 优缺点](#2.3 优缺点)
      • [2.4 哨兵机制选举流程](#2.4 哨兵机制选举流程)
      • [2.5 脑裂问题解决方案](#2.5 脑裂问题解决方案)
    • [3、Redis Cluster](#3、Redis Cluster)
      • [3.1 工作机制](#3.1 工作机制)
      • [3.2 配置实现](#3.2 配置实现)
      • [3.3 优缺点](#3.3 优缺点)
      • [3.4 故障转移](#3.4 故障转移)
      • [3.5 哈希槽为什么是16384个槽](#3.5 哈希槽为什么是16384个槽)
      • [3.6 集群扩容](#3.6 集群扩容)

1、主从复制

Redis 主从复制方案是 Redis 最基本的集群方案。实现了读写分离和数据备份。

  • 1、主从复制集群包括1个主节点,多个从节点。主节点用来处理写数据,从节点用来读数据,实现读写分离
  • 2、多个从节点做负载均衡,分发读请求到不同的从节点,以提升系统并发能力
  • 3、从节点复制主节点数据相当于做了数据备份,保证了数据安全故障转移。

从节点通过 replicaof 配置项指定主节点进行数据同步复制。一般建议2-3个从节点,保证数据的安全可故障转移。

1.1 工作机制

主从复制数据同步过程包括全量同步、部分同步、命令同步。

  • 1、全量同步过程
    主节点生成 RDB 快照文件,将文件发送给从节点,从节点加载 RDB 文件初始化数据。
    主节点发送 RDB 文件之后发生新的写命令会记录在复制积压缓冲区(Replication Backlog),在从节点完成数据初始化后,将这段期间内复制积压缓冲区的写命令发送给从节点,保证数据一致性。
  • 2、部分同步过程
    主节点将复制积压缓冲区中的写命令发送给从节点,保证数据一致性。
  • 3、命令同步过程
    主节点将每个写命令发送给从节点,从节点接收并执行这些写命令,保持与主节点的数据一致性。

1>全量同步触发时机

(1)从节点首次连接主节点会触发全量同步。

(2)从节点的复制偏移量(Replication Offset)不在主节点的复制积压缓冲区中时触发全量同步。

2>部分同步触发时机

(1)从节点的复制偏移量在主节点的复制积压缓冲区中。

1.2 配置实现

对于从节点一般通过 redis.conf 配置文件进行配置主节点,或者可以通过启动命令指定主节点

redis.conf 配置项在 Redis5.0 之前是 slaveof,在 Redis5.0 及之后的版本是 replicaof,此处以 replicaof 演示。

假设主节点部署 ip 和 port 为 192.168.1.101:6379,密码为 123456

  • 1、redis.conf 配置文件方式
js 复制代码
# Redis5.0之前通过slaveof配置指定集群主节点
# Redis5.0及之后命令为replicaof
# slaveof 192.168.1.101 6379
replicaof 192.168.1.101 6379
# 配置主节点密码,如果没有密码,可以注释掉该配置
masterauth 123456
  • 2、启动命令方式
js 复制代码
redis-server --replicaof 192.168.1.101 6379 --masterauth 123456

1.3 优缺点

1>优缺点

  • 优点
    数据备份
    读写分离
  • 缺点
    主节点宕机,需要手工切换主节点
    一写多读,不支持多写

2>适合场景

适合小规模应用,读写分离。不支持故障转移,不支持数据分片。

1.4 部署形式

形式 说明 适合场景
一主一从 一个主节点一个从节点 适合小规模应用,从节点作为主节点的备份
一主多从 一个主节点多个从节点 适合读多写少的场景,从节点可以分担读请求
链式复制 从节点可以作为其他从节点的主节点的链式形式 适合网络带宽有限或跨地域复制的场景

链式复制形式:主节点 -> 从节点 A -> 从节点 B

1.5 主从复制优化

  • 1、启用无盘复制。主节点不写入磁盘IO,直接网络传输给从节点。
  • 2、调整主节点复制缓存区大小。
  • 3、调整复制积压缓冲区。针对从节点断开重连场景,会从复制积压缓冲区同步数据,如果过小,会导致全量复制。
js 复制代码
# 1、主节点启用无盘复制
repl-diskless-sync yes
# 2、主节点复制缓存区
# 256mb:缓冲区硬限制。64mb:缓冲区软限制。60:缓冲区达到软限制后,60 秒内不再接受新数据。
client-output-buffer-limit replica 256mb 64mb 60
# 3、调整复制积压缓冲区
repl-backlog-size 128mb
  • 4、主节点写操作过多,导致数据同步不及时,考虑批量写数据;考虑使用管道技术将多个写操作合并成一次网络请求。
  • 5、确保主从节点部署在一个机房,降低网络延迟
  • 6、升级从节点的硬件配置
  • 7、从节点负载均衡,降低单个节点负载
  • 8、使用Redis6.0的多线程配置

扩展:Redis 6.0 的多线程 IO

Redis 多 IO 线程模型只⽤来处理处理网络数据的读写和协议解析,对于 Redis 的读写命令,依然是单线程处理。

⽹络处理经常是瓶颈,通过多线程并⾏处理可提⾼性能。

继续使⽤单线程执⾏读写命令,不需要为了保证 Lua 脚本、事务、等开发多线程安全机制,实现更简单

建议只在机器至少有4个内核时才启用多线程模型,且至少留下一个备用内核

io-threads 3

io-threads-do-reads yes

2、Sentinel 哨兵模式

Redis 的哨兵机制(Sentinel)是一种高可用解决方案,实现了读写分离和数据备份,保证了集群高可用

  • 1、主从复制集群下,当主节点挂掉,无法支持写命令,集群就挂了。
  • 2、通过增加名称为"哨兵"的哨兵节点,来定期监控集群中 Redis 各个主从节点的健康情况。
  • 3、当发生主节点宕机的情况,多个哨兵节点会根据 Raft 算法选举一个哨兵领导者。
  • 4、哨兵领导者来负责选举一个从节点作为主节点,并通知其他从节点切换新的主节点。

2.1 工作机制

Sentinel 哨兵模式工作过程包括哨兵监控、哨兵通知、自动故障转移

  • Sentinel 哨兵模式包括 Sentinel 哨兵集群和 Redis 主从复制架构两部分。
  • 哨兵集群包括多个哨兵节点,一般推荐奇数个哨兵节点,避免脑裂问题。
  • 哨兵节点之间通过发布/订阅机制(Pub/Sub) 和 Gossip 协议实现互相发现和通信
  • 启动哨兵节点后,哨兵节点会自动加入哨兵集群,无需手动配置互相发现
  • 哨兵集群监控 Redis 主从复制架构下Redis节点的健康状态。
  • 哨兵节点通过 Redis 主节点,自动发现主从复制架构中所有的 Redis 从节点。
  • 哨兵节点通过心跳机制,监控 Redis 节点的健康状况。
  • 主节点挂掉,哨兵节点会认为需要发生故障转移。
  • 当同意触发故障转移的哨兵节点数量达到配置数量 quorum 时,哨兵集群节点通过 Raft 算法选举一个哨兵领导者。
  • 哨兵领导者负责从健康的从节点中选举一个从节点作为主节点。
  • 哨兵节点通知其他 Redis 从节点切换旧的主节点配置为新的主节点。

2.2 配置实现

Redis 主从架构配置此处就略过,可以参考上文主从复制下的配置实现。

Redis 从节点配置节点优先级,方便故障转移时选举新的 Redis 主节点。

下面是哨兵集群的配置

1>Redis 节点配置文件 redis.conf

js 复制代码
# 从节点的优先级越高,越容易被选中
slave-priority 100

2>哨兵节点配置文件 sentinel.conf

配置 说明
quorum 指定需要多少个哨兵节点同意才能触发故障转移。
down-after-milliseconds 主节点多久无响应后判定为宕机。
failover-timeout 故障转移的超时时间。
yml 复制代码
# 哨兵监听的端口
port 16379
# 监控 Redis 主节点名称、IP 和端口,quorum 表示需要多少个哨兵同意才能触发故障转移
# sentinel monitor <master-name> <master-ip> <master-port> <quorum>
sentinel monitor mymaster 192.168.1.101 6379 2
# 主节点多久无响应后标记为下线(单位:毫秒)
sentinel down-after-milliseconds mymaster 5000
# 故障转移的超时时间(单位:毫秒)
sentinel failover-timeout mymaster 180000
# 故障转移时,最多有多少个从节点同时同步新的主节点
sentinel parallel-syncs mymaster 1
# 设置主节点的密码(如果主节点设置了密码)
sentinel auth-pass mymaster 123456

3>启动哨兵节点

比如 Redis 主从节点共3个,此处部署3个哨兵节点。

通过配置文件启动哨兵节点后,哨兵节点会自动加入哨兵集群,无需手动配置互相发现

  • 哨兵的自动发现机制
    • 每个哨兵节点会定期向一个特定的频道(sentinel:hello)发布消息。
    • 消息中包含哨兵节点的信息(如 IP、端口、运行 ID 等)。
    • 其他哨兵节点会订阅这个频道,从而接收到新哨兵节点的信息。
js 复制代码
redis-server /path/to/sentinel-1.conf --sentinel
redis-server /path/to/sentinel-2.conf --sentinel
redis-server /path/to/sentinel-3.conf --sentinel

2.3 优缺点

1>优缺点

  • 优点
    自动故障转移,保证了集群的高可用
  • 缺点
    需要部署多个哨兵节点,并配置监控规则;
    无法解决写的瓶颈,只有主节点写数据

2>适用场景

中小规模应用,高可用

2.4 哨兵机制选举流程

  • 哨兵节点通过ping命令监控主节点。当主节点超过配置的最大响应时长down-after-milliseconds,当前哨兵节点会认为主节点宕机。

  • 当认为主节点宕机的哨兵节点数量,超过配置的同意故障转移的哨兵数量quorum 时,开始故障转移。

  • 哨兵节点使用 Raft 算法选举一个领导者哨兵,来负责故障转移。

    • 哨兵会向其他节点发送请求
    • 哨兵节点会投票给第一个收到请求的节点
    • 得票最多的哨兵节点作为领导者哨兵
  • 领导者哨兵选举健康的从节点,针对从节点优先级和数据偏移量进行选举。如果配置了优先级slave-priority,哨兵会优先选择优先级高的从节点。如果优先级相同,哨兵会选择复制偏移量Replication Offset最大的从节点。

  • 领导者哨兵会向选举的从节点发送SLAVEOF NO ONE命令,提升为主节点

  • 领导者哨兵回向其他从节点发送SLAVEOF命令,通知切换新的主节点。哨兵会更新配置,记录新的主节点

注意:哨兵数量应为奇数。避免脑裂问题。最低需要3个哨兵节点来保证集群的高可用。

2.5 脑裂问题解决方案

由于网络分区或节点故障导致的,出现多个子集群,互相认为对方已下线不可用。每个集群有自己的主节点,并且都认为自己是健康的。

  • 多数派原则 Quorum,做决策时,需要得到大多数节点的同意
  • 心跳检测,节点之间互相检测健康状态
  • 强制隔离故障节点,写操作时必须确保存在足够多的健康的从节点时,才能写,如Redis的MIN-SLAVES-TO-WRITEMIN-SLAVES-MAX-LAG;Redis Cluster的cluster-require-full-coverage
  • 合理的集群节点数量,配置奇数个

3、Redis Cluster

Redis Cluster 是 Redis 官方提供的分布式解决方案,通过数据分片(Sharding)和主从复制实现高可用性和水平扩展,支持自动故障转移、数据分片

3.1 工作机制

Redis Cluster集群包括数据分片和主从复制

  • Redis Cluster 将数据划分为 16384 个哈希槽,每个节点负责一部分槽。根据键的哈希值,将数据分散到各个哈希槽,即每个节点负责一部分数据。
  • 每个节点有一个或多个从节点,当主节点挂掉,可以升级为主节点,保证高可用
  • Redis Cluster 使用 Gossip 协议实现节点之间的通信和状态同步。节点之前定期交换信息维持集群状态。

3.2 配置实现

  • 通过 redis.conf 配置文件开启集群模式
yml 复制代码
cluster-enabled yes
cluster-config-file nodes.conf
cluster-node-timeout 15000
  • 使用命令启动 Redis 节点
js 复制代码
redis-server /path/to/redis.conf --cluster-enabled yes
  • 使用命令创建 Redis Cluster 集群
js 复制代码
redis-cli --cluster create <node1-ip>:<node1-port> <node2-ip>:<node2-port> ... --cluster-replicas 1

3.3 优缺点

1>优缺点

  • 优点
    数据分片,解决单节点写的性能瓶颈
    自动故障转移
    去中心化,没有主单点故障
  • 缺点
    手工配置复杂的分片规则
    扩容需要手动迁移数据

2>适用场景

大规模应用,分布式高可用

3.4 故障转移

当主节点下线时,从节点会发起故障转移,选举新的主节点。

选举过程基于 Raft 算法(参考Sentinel哨兵选举),确保只有一个从节点升级为主节点

3.5 哈希槽为什么是16384个槽

(1)集群节点越多,心跳包的消息体携带的数据越多。如果节点超过1000个,会导致网络拥堵。因此 redis 的作者,不建议 redis cluster 节点数量超过 1000 个。16384 个插槽范围比较合适,当集群扩展到1000个节点时,也能确保每个master节点有足够的插槽。

(2)正常的心跳数据包携带节点的完整配置,它能以幂等方式来更新配置。每秒 redis 节点需要发送一定数量的 ping 消息作为心跳包,如果槽位为 65536,这个 ping 消息的消息头太大了,浪费带宽;如果采用 16384 个插槽,占空间 2KB (16384/8);如果采用 65536 个插槽,占空间 8KB (65536/8)。

(3)槽位越小,节点少的情况下,压缩率更高。

3.6 集群扩容

添加节点分配哈希槽

yml 复制代码
CLUSTER MEET
CLUSTER ADDSLOTS 

迁移哈希槽

yml 复制代码
CLUSTER SETSLOT

移除节点

yml 复制代码
CLUSTER FORGET

常用命令

yml 复制代码
CLUSTER MEET <ip> <port>:将节点加入集群。
CLUSTER ADDSLOTS <slot>:为节点分配哈希槽。
CLUSTER DELSLOTS <slot>:移除节点的哈希槽。
CLUSTER SETSLOT <slot> MIGRATING <node-id>:迁移哈希槽。
CLUSTER SETSLOT <slot> IMPORTING <node-id>:接收哈希槽。
CLUSTER INFO:查看集群信息。
CLUSTER NODES:查看集群节点信息。

参考博客:
Redis集群详解
Redis 主从复制功能和部分重同步的实现

相关推荐
我真的是大笨蛋2 小时前
Redis的String详解
java·数据库·spring boot·redis·spring·缓存
zhengzizhe4 小时前
Redssion出现attempt to unlock lock, not locked by current thread by node id
redis
兜兜风d'8 小时前
redis字符串命令
数据库·redis·缓存
西瓜er9 小时前
Docker 一键部署指南:GitLab、Nacos、Redis、MySQL 与 MinIO 全解析
redis·docker·gitlab
道可到10 小时前
别再瞎拼技术栈!Postgres 已经能干 Redis 的活了
redis·后端·postgresql
野犬寒鸦10 小时前
从零起步学习Redis || 第十二章:Redis Cluster集群如何解决Redis单机模式的性能瓶颈及高可用分布式部署方案详解
java·数据库·redis·后端·缓存
悟能不能悟20 小时前
redis的红锁
数据库·redis·缓存
qq_5470261791 天前
SpringBoot+Redis实现电商秒杀方案
spring boot·redis·后端
野犬寒鸦1 天前
从零起步学习Redis || 第十一章:主从切换时的哨兵机制如何实现及项目实战
java·服务器·数据库·redis·后端·缓存
problc1 天前
PostgreSQL + Redis + Elasticsearch 实时同步方案实践:从触发器到高性能搜索
redis·elasticsearch·postgresql