Redis详解(七)哨兵模式和集群模式

1. 哨兵模式

哨兵模式是redis高可用的实现方式之一
使用一个或者多个哨兵(Sentinel)实例组成的系统,对redis节点进行监控,在主节点出现故障的情况下,能将从节点中的一个升级为主节点,进行故障转义,保证系统的可用性。

1.1 哨兵们是怎么感知整个系统中的所有节点(主节点/从节点/哨兵节点)的

1. 首先主节点的信息是配置在哨兵(Sentinel)的配置文件中

2. 哨兵节点会和配置的主节点建立起两条连接命令连接订阅连接

3. 哨兵会通过命令连接每10s发送一次INFO命令,通过INFO命令,主节点会返回自己的run_id和自己的从节点信息

4. 哨兵会对这些从节点也建立两条连接命令连接订阅连接

5. 哨兵通过命令连接向从节点发送INFO命令,获取到他的一些信息

  • run_id
  • role
  • 从服务器的复制偏移量 offset

6. 因为哨兵对与集群中的其他节点(主从节点)当前都有两条连接,命令连接订阅连接

  • 通过命令连接向服务器的_sentinel:hello频道发送一条消息,内容包括自己的ip端口、run_id、配置纪元(后续投票的时候会用到)等
  • 通过订阅连接对服务器的_sentinel:hello频道做了监听,所以所有的向该频道发送的哨兵的消息都能被接受到
  • 解析监听到的消息,进行分析提取,就可以知道还有那些别的哨兵服务节点也在监听这些主从节点了,更新结构体将这些哨兵节点记录下来
  • 向观察到的其他的哨兵节点建立命令连接----没有订阅连接

1.2 哨兵模式下的故障迁移

1.2.1 主观下线

哨兵(Sentinel)节点会每秒一次的频率向建立了命令连接的实例发送PING命令,如果在down-after-milliseconds毫秒内没有做出有效响应包括(PONG/LOADING/MASTERDOWN)以外的响应,哨兵就会将该实例在本结构体中的状态标记为SRI_S_DOWN主观下线

1.2.2 客观下线

当一个哨兵节点发现主节点处于主观下线状态是,会向其他的哨兵节点发出询问,该节点是不是已经主观下线了。如果超过配置参数quorum个节点认为是主观下线时,该哨兵节点就会将自己维护的结构体中该主节点标记为SRI_O_DOWN客观下线
询问命令SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <run_id>

参数意义
ip/port当前认为下线的主节点的ip和端口
current_epoch配置纪元
run_id*标识仅用于询问是否下线
有值标识该哨兵节点希望对方将自己设置为leader
询问时用*,选举时用run_id

1.2.3 leader选举

在认为主节点客观下线的情况下,哨兵节点节点间会发起一次选举,命令还是上面的命令SENTINEL is-master-down-by-addr <ip> <port> <current_epoch> <run_id>,只是run_id这次会将自己的run_id带进去,希望接受者将自己设置为主节点。如果超过半数以上的节点返回将该节点标记为leader的情况下,会有该leader对故障进行迁移

1.2.4 故障迁移

1. 在从节点中挑选出新的主节点

  • 通讯正常
  • 优先级排序
  • 优先级相同是选择offset最大的

2. 将该节点设置成新的主节点 SLAVEOF no one,并确保在后续的INFO命令时,该节点返回状态为master

3. 将其他的从节点设置成从新的主节点复制, SLAVEOF命令

4. 将旧的主节点变成新的主节点的从节点

1.2.5 优缺点

  • 优点:高可用,在主节点故障时能实现故障的转移
  • 缺点:好像没办法做到水平拓展,如果内容很大的情况下

2. 集群模式

官方提供的分布式方案(槽指派/重新分片/故障转移)
集群内的节点,都会有个数据结构存储整个集群内的节点信息

//整体
struct clusterState{
  clusterNode *mySelf;
  ....
  dict *nodes;  //集群内的所有节点
}

// 单个节点
struct clusterNode {
  char name[];
  char ip[];
  int port;
  clusterLink *link;  //保存节点间,连接的信息
  int flags;    //状态标记
}

//节点间连接的信息
struct clusterLink{
  mstime_t ctime;  //创建时间
  int fd; //tcp套接字描述符
  sds sndbuf;  // 输出缓存区
  sds rcvbuf;  //输入缓存区
  struct clusterNode *node;
}

2.1 槽指派

redis集群可以被分为16384个槽,只有这些槽全被指派了处理的节点的情况下,集群的状态才能是上线状态(ok)
操作redis集群的时候,将key作为参数,就可以计算出对应的处理槽上,所以存储等操作都应该在该槽对应的节点上。通过这种方式,可以完美的实现集群存储的水平拓展。

def slot_number(key):
  return CRC16(key) & 16383
//得到的结果就是槽的序号

槽指派的信息是怎么存储的

struct clusterState{
  clusterNode *slots[16384]
 }

struct clusterNode{
  unsigned char slots[16384/8]
}

通过上面两个结构体中的定义可以看出,槽指派的信息是分了两种方式,保存在结构体里面。

分两种存储的好处
1. 如果需要判断某一个节点负责的槽,只需要获取方式二中的数组做判断就可以
2. 如果找某个槽是哪个节点负责,只需要获取方式一的列表,一查就知道

2.2 重新分片

将已经指派给节点的槽,重新执行新的节点。

2.3 故障转移

2.3.1 发现故障节点

  1. 集群内的节点会向其他节点发送PING命令,检查是否在线
  2. 如果未能在规定时间内做出PONG响应,则会把对应的节点标记为疑似下线
  3. 集群中一半以上负责处理槽的主节点都将主节点X标记为疑似下线的话,那么这个主节点X就会被认为是已下线
  4. 向集群广播主节点X已下线,大家收到消息后都会把自己维护的结构体里的主节点X标记为已下线

2.3.2 从节点选举

  1. 当从节点发现自己复制的主节点已下线了,会向集群里面广播一条消息,要求所有有投票权的节点给自己投票(所有负责处理槽的主节点都有投票权)
  2. 主节点会向第一个给他发选举消息的从节点回复支持
  3. 当支持数量超过N/2+1的情况下,该从节点当选新的主节点

2.3.3 故障的迁移

  1. 新当选的从节点执行 SLAVEOF no one,修改成主节点
  2. 新的主节点会撤销所有已下线的老的主节点的槽指派,指派给自己
  3. 新的主节点向集群发送命令,通知其他节点自己已经变成主节点了,负责哪些槽指派
  4. 新的主节点开始处理自己负责的槽的命令

3. 集群模式和哨兵模式的区别

  1. 哨兵模式监控权交给了哨兵系统,集群模式中是工作节点自己做监控
  2. 哨兵模式发起选举是选举一个leader哨兵节点来处理故障转移,集群模式是在从节点中选举一个新的主节点,来处理故障的转移
<think>嗯,用户想了解Redis的主从复制、哨兵机制集群模式的工作原理配置方法。首先,我需要回顾一下这些概念的基本原理,确保自己理解正确。主从复制主要是数据冗余读写分离,哨兵负责高可用,集群则是数据分片负载均衡。 主从复制的部分,我记得主库可以写,从库只能读。复制过程应该是异步的,主库将写操作传播给从库。需要说明配置方法,比如slaveof命令或者配置文件中的slaveof选项。还有持久化的问题,主库是否要开启持久化来避免重启后数据丢失,导致从库被清空?引用[1]提到了主库是否开启持久化的问题,这里需要强调推荐开启。 然后是哨兵机制,主要作用是监控主从节点,自动故障转移。用户可能想知道哨兵如何检测主库下线,如何进行投票切换。配置方面,sentinel.conf的配置参数,比如监控的主节点、quorum数量、认证密码等。引用[3]中有配置示例,可以结合说明。哨兵模式下客户端如何连接,比如通过哨兵获取主节点地址,这里可能需要提到Python客户端的示例。 集群模式方面,Redis Cluster的数据分片是使用哈希槽,每个节点负责一部分槽。配置集群需要多个节点,使用cluster meet命令或者配置文件中的集群选项。需要解释如何分配槽位,以及节点故障时的处理机制,比如主节点故障时从节点提升为主节点。 用户可能还关心这些机制之间的区别应用场景。比如主从复制适合读写分离,哨兵提高可用性,集群解决大数据量高并发。配置步骤要分点说明,可能包括命令配置文件两种方式,以及常见问题,比如复制延迟、哨兵的选举过程、集群的节点扩容等。 需要检查引用内容是否准确。引用[1][2]讨论了主从复制哨兵的基本架构配置步骤,引用[3]提供了哨兵配置的具体示例。确保回答中引用的部分正确对应,比如主库持久化的重要性来自引用[1],哨兵配置文件参考引用[3]。 用户的问题可能还涉及到实际配置中的细节,比如如何设置认证密码,如何处理网络分区,或者性能调优。不过根据问题,主要需要详细的工作原理配置方法,可能不需要深入调优。但相关问题可以引导用户进一步思考,比如性能分析、优化方法、应用场景等,类似示例中的快速排序问题。 最后,确保回答结构清晰,分点说明每个机制的工作原理、配置步骤常见问题,并附上相关问题供用户参考。同时,注意使用正确的中文术语,避免技术术语错误,比如“主从复制”而非“主备复制”,正确使用LaTeX格式,如配置项用代码块,数学表达式用$...$等。</think>### Redis主从复制、哨兵机制与集群模式详解 #### 一、主从复制(Replication) **工作原理** 主从复制通过数据冗余实现读写分离与容灾备份。主库(master)负责写操作,从库(slave)异步复制主库数据并支持读操作[^1]。 1. **复制流程**: - 从库发送`SYNC`命令请求同步数据。 - 主库生成RDB快照并发送给从库。 - 从库加载RDB后,主库持续推送写命令(基于AOF缓冲区)。 2. **配置方法**: - **命令行**:`SLAVEOF <master_ip> <master_port>`(从库执行)[^2]。 - **配置文件**: ```conf # 从库配置 replicaof 127.0.0.1 6379 masterauth 123456 # 主库密码 ``` **常见问题** - **数据不一致**:异步复制可能导致从库数据延迟,可配置`min-replicas-max-lag`限制最大延迟[^1]。 - **主库持久化**:建议主库开启RDB/AOF,避免重启后空数据覆盖从库[^1]。 --- #### 二、哨兵机制(Sentinel) **工作原理** 哨兵用于监控主从节点并自动故障转移,保障高可用性。 1. **功能**: - 监控节点状态(每秒`PING`检测)。 - 主库故障时,选举新主库并通知从库切换。 - 提供客户端服务发现接口。 2. **配置方法**: ```conf # sentinel.conf port 26379 sentinel monitor redis-master 127.0.0.1 6379 2 # 监控主库,2为quorum值 sentinel auth-pass redis-master 123456 # 主库密码 sentinel down-after-milliseconds redis-master 3000 # 超时判定下线[^3] ``` **常见问题** - **脑裂问题**:网络分区可能导致多主库,需配置`min-slaves-to-write`限制写入条件[^1]。 - **客户端适配**:客户端需通过哨兵获取主库地址,例如Python: ```python from redis.sentinel import Sentinel sentinel = Sentinel([('127.0.0.1', 26379)], socket_timeout=0.1) master = sentinel.master_for('redis-master', password='123456') ``` --- #### 三、集群模式(Cluster) **工作原理** Redis Cluster通过分片(16384个哈希槽)实现水平扩展与负载均衡。 1. **数据分布**: - 键通过CRC16算法映射到哈希槽。 - 每个节点负责部分槽,支持动态扩缩容。 2. **配置方法**: - 启动多个节点并启用集群模式: ```conf # redis.conf cluster-enabled yes cluster-config-file nodes.conf ``` - 构建集群: ```bash redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 ... --cluster-replicas 1 ``` **常见问题** - **节点故障**:从节点自动接替故障主节点(需至少一个从节点)。 - **跨槽操作**:多键操作需使用`{}`强制哈希标签,例如:`{user}:1``{user}:2`[^1]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值