Redis 的主从模式指的就是主从复制。

用户可以通过 SLAVEOF 命令或者配置的方式,让一个服务器去复制另一个服务器即成为它的从服务器。

主从模式架构

Redis 如何实现主从模式?
Redis 的从服务器在向主服务器发起同步时,一般会使用 SYNC 或 PSYNC 命令。
在这里插入图片描述

  1. 你启动一台slave 的时候,他会发送一个psync命令给master ,
  2. 如果是这个slave第一次连接到master,他会触发一个全量复制。
  3. master就会启动一个线程,生成RDB快照,还会把新的写请求都缓存在内存中,
  4. RDB文件生成后,master会将这个RDB发送给slave的,slave拿到之后做的第一件事情就是写进本地的磁盘,然后加载进内存,
  5. 然后master会把内存里面缓存的那些新命名都发给slave。

问题:主从同步的时候,新的slaver进来的时候用RDB,那之后的数据呢?有新的数据进入master怎么同步到slaver?
可以基于AOF,类似于mysql的binlog,将数据从主服务器同步到从服务器。

Redis 哨兵模式 (Sentinel)

Redis 主从模式虽然能做到很好的数据备份,但是他并不是高可用的。一旦主服务器点宕机后,只能通过人工去切换主服务器。因此 Redis 的哨兵模式也就是为了解决主从模式的高可用方案。

哨兵模式引入了一个 Sentinel 系统去监视主服务器及其所属的所有从服务器。一旦发现有主服务器宕机后,会自动选举其中的一个从服务器升级为新主服务器以达到故障转义的目的。

同样的 Sentinel 系统也需要达到高可用,所以一般也是集群,互相之间也会监控。而 Sentinel 其实本身也是一个以特殊模式允许 Redis 服务器。具体可以参考我之前的文章 — redis哨兵集群架构的核心知识及原理.

这里说下整体的实现原理
1. sentinel与主从服务器建立连接

Sentinel 服务器启动之后便会创建于主服务器的 命令连接 ,并订阅主服务器的 sentinel:hello 频道以创建 订阅连接

Sentinel 默认会每 10 秒向主服务器发送 INFO 命令,主服务器则会返回主服务器本身的信息,以及其所有从服务器的信息。

根据返回的信息,Sentinel 服务器如果发现有新的从服务器上线后也会像连接主服务器时一样,向从服务器同时创建命令连接与订阅连接。

2.判定主服务器是否下线
每一个 Sentinel 服务器每秒会向其连接的所有实例包括主服务器,从服务器,其他 Sentinel 服务器)发送 PING命令,根据是否回复 PONG 命令来判断实例是否下线。

  1. 判定主观下线
    如果实例在收到 PING命令的 down-after-milliseconds 毫秒内(根据配置),未有有效回复。则该实例将会被发起 PING命令的 Sentinel 认定为主观下线。

  2. 判定客观下线
    当一台主服务器被某个 Sentinel 服务器判定为客观下线时,为了确保该主服务器是真的下线, Sentinel 会向 Sentinel 集群中的其他的服务器确认,如果判定主服务器下线的 Sentinel 服务器达到一定数量时(一般是 N/2+1),那么该主服务器将会被判定为客观下线,需要进行故障转移。

3.选举领头 Sentinel
当有主服务器被判定客观下线后,Sentinel 集群会选举出一个领头 Sentinel 服务器来对下线的主服务器进行故障转移操作。整个选举其实是基于 RAFT 一致性算法而实现的,大致的思路如下:

每个发现主服务器下线的 Sentinel 都会要求其他 Sentinel 将自己设置为局部领头 Sentinel。

接收到的 Sentinel 可以同意或者拒绝

如果有一个 Sentinel 得到了半数以上 Sentinel 的支持则在此次选举中成为领头 Sentinel。

如果给定时间内没有选举出领头 Sentinel,那么会再一段时间后重新开始选举,直到选举出领头 Sentinel。

4.选举新的主服务器
领头服务器会从从服务中挑选出一个最合适的作为新的主服务器。挑选的规则是:

选择健康状态的从节点,排除掉断线的,最近没有回复过 INFO命令的从服务器。

选择优先级配置高的从服务器

选择复制偏移量大的服务器(表示数据最全)

挑选出新的主服务器后,领头服务器将会向新主服务器发送 SLAVEOF no one命令将他真正升级为主服务器,并且修改其他从服务器的复制目标,将旧的主服务器设为从服务器,以此来达到故障转移。

Redis Cluster

Redis 哨兵模式实现了高可用,读写分离,但是其主节点仍然只有一个,即写入操作都是在主节点中,这也成为了性能的瓶颈。

一个 Redis 集群中会由多个节点组成,每个节点都是互相连接的,会保存自己与其他节点的信息。节点之间通过 gossip 协议交换互相的状态,以及保新加入的节点信息

1.数据的 Sharding
Redis Cluster 的整个数据库将会被分为 16384 个哈希槽,数据库中的每个键都属于这 16384 个槽中的其中一个,集群中的每个节点可以处 0 个或者最多 16384 个槽。

2.Redis Cluster 的高可用

  1. Redis 的每个节点都可以分为主节点与对应从节点。
  2. 主节点负责处理槽,从节点负责复制某个主节点,
  3. 并在主节点下线时,代替下线的主节点。

3.如何实现故障转移
其实与哨兵模式类似,

  1. Redis 的每个节点都会定期向其他节点发送 Ping 消息,以此来检测对方是否在线。
  2. 当一个节点检测到另一个节点下线后,会将其设置为疑似下线。
  3. 如果一个机器中,有半数以上的节点将某个主节点设为疑似下线,则该节点将会被标记为已下线状态,并开始执行故障转移。
  4. 通过 raft 算法从下线主节点的从节点中选出新的主节点
    被选中的从节点执行 SLAVEOF no one 命令,成为新的主节点
  5. 新的主节点撤销掉已下线主节点的槽指派,并将这些槽指给自己
  6. 新的主节点向集群中广播自己由从节点变为主节点
  7. 新的主节点开始接受和负责自己处理槽的有关命令请求

总结
本文主要介绍了 Redis 三种集群模式,总结一下
主从模式 可以实现读写分离,数据备份。但是并不是「高可用」的
哨兵模式 可以看做是主从模式的「高可用」版本,其引入了 Sentinel 对整个 Redis 服务集群进行监控。但是由于只有一个主节点,因此仍然有写入瓶颈。
Cluster 模式 不仅提供了高可用的手段,同时数据是分片保存在各个节点中的,可以支持高并发的写入与读取。当然实现也是其中最复杂的。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐