Redis主从架构

主要配置:

replicaof IP 端口  IP为主节点IP

replica-read-only yes 从节点配置为只读

Redis主从架构_第1张图片

全量复制 工作原理:

  1. 首先配置从节点,slave会像master发送PSync命令,请求复制数据到slava
  2. master节点收到命令后,将当前内存中的数据bgsave持久化RDB文件
  3. 发给slave,slave将RDB数据加载到内存
  4. 在发送和加载数据过程中,有新的数据修改,会存到repl buffer缓存中
  5. slave加载完数据后,master再次发送缓存数据到slave中
  6. slave架构缓存(一些命令)写到内存中
  7. 此后master-slave保持长连接,保持主从数据一致

如果当前有多个slave向master请求数据,master只会持久化一次

Redis主从架构_第2张图片

部分复制(断点续传) 工作原理:

  1. master与slave断开连接,此时会记录一个offset偏移量
  2. master会缓存最近一段时间的数据存入repl backlog buffer缓存中
  3. 重新建立连接时,slave发送信号(包含offset)给master
  4. 如果此时的offset在缓存中,则master将offset以后的数据一次性同步给slave,如果不存在,则全量同步。因为repl backlog buffer有容量限制,如果断开时间比较长时,之前的缓存数据可能已经清空了,既原来记录的offset也就不存在了

主从复制风暴: 

一个主节点下挂很多个从节点,如果从节点同时请求复制主节点数据,这样给主节点压力过大,可以做成树形结构

Redis主从架构_第3张图片

 管道pipeline:

一次发送多条指令,但是不具有原子性,一条指令失败,不影响其它指令。

lua脚本:

  1. 可以一次执行多条命令,作为一个整体
  2. 作为一个整体,所以具有原子性
  3. 可以替代redis事务

使用时不要出现死循环和耗时比较长的运算,否则会阻塞

哨兵架构:

Redis主从架构_第4张图片

 哨兵不是提供读写服务,主要是监控节点,如果client第一次要连接master,首先要经过哨兵,哨兵告诉客户端主节点是哪个,以后client就直接访问master。如果master挂了,哨兵会从slave中选出一个新的master并告诉client,client访问新的master,之前的master如果恢复了,则作为slave。

缺点:

  1. 主节点挂了,需要一段时间重新选出新的主节点
  2. 只有主节点提供写服务
  3. 节点内存有限制,一个节点顶多10G,无法扩容

哨兵选举流程:

当master挂了,某个sentinel发现了,会和其它sentinel先选出一个哨兵的leader,选哨兵leader也是超过半数机制,每个sentinel都向其它sentinel请求选自己,谁先选到了,谁就是 leader,那个leader负责选出新的master。

Redis集群:

高可用,一个节点挂了,其它节点可以用,还可以水平扩展

Redis主从架构_第5张图片

 集群共有16384个槽位,每个master节点分配一部分槽位,通过对key进行hash运算,得到对应的槽位,根据槽位的范围,数据落到对应的master,客户端会把相应的槽位信息缓存到本地,如果服务端槽位发生变化,客户端这样也会有相应的机制进行纠正。

集群选举原理:

Redis主从架构_第6张图片

 主节点挂掉--》从节点向其它节点发送信息--》只有主节点相应--》返给从节点ack(先收到哪个节点的就只发给哪个从节点)--》得到ack超过集群主节点半数之上的从节点当选为主节点--》向其它节点广播信息(我已经宣威主节点了)--》原来的主节点恢复会变为从节点。

如果两个从节点得到的票数相同,则进行重新一轮的选举。redis为了尽量避免票数相同,做了相应的延时处理,还有一种机制就是数据最新的从节点为主节点(大部分情况下是,并不是绝对的,因为受延时的影响)。

跳转重定位:

当客户端向某一个节点发送指令,但是key不在这个节点所管理的槽位,redis可以进行重定向,告诉客户端,跳转到对应槽位的节点。

节点与节点通信方式:

redis cluster采用gossip

网络抖动:

主从节点网络断开,集群就得重新选举主节点,可能断开的时间很短,没必要切换主从节点,可以通过设置参数:

cluster-node-timeout 节点连接超时时间,如果超过了此时间,才认为连接断开

 脑裂问题:

当主节点与从节点之间的网络通信突然断了,这时将一个从节点选举了主节点,此时出现了两个主节点,那么不同客户端会往这个两个主节点存数据,两个主节点数据不一致,当网络恢复后,原来的主节点变为从节点,从当前主节点复制数据,原来的主节点数据会丢失。

Redis主从架构_第7张图片

 解决办法:

可以配置min-slave-to-write [num]  

一般设置为num为:加上主节点超过小集群的半数以上,例如1主2从,则至少有1个以上的从写成功

写入主节点的同时,需要指定数量的从节点也写成功,客户端才算写成功,所以原来的主从节点网络断了,原来的主节点不能插入数据了,待网络恢复后,将新的主节点数据全量同步给原来的主节点(此时变为从节点了)。

缺点:无法保证高可用,假如从节点都挂了,主节点无法写入,小集群挂掉。


如果一个小集群挂掉是否会影响整个集群?

可以通过redis.conf中的cluster-require-full-coverage配置

如果为no时,不影响,yes时整个集群不可用

为什么集群至少3个master节点,且推荐为奇数?

不一定非得为奇数,偶数也不影响集群运行,但是奇数更能节省服务资源。

假如有4台主节点,根据主节点选举原理半数机制,也只能运行挂掉一台,同时挂掉2台无法选举出新的master节点了。

所以,只运行挂一台的话,3台master和4台master效果是一样的

你可能感兴趣的:(redis)