redis-3

2021-06-24  本文已影响0人  甜甜起司猫_

redis-3

redis高可用

redis主从同步

全量同步

步骤:

  1. 主服务器开启BG SAVE写RDB文件
  2. 主服务器同步RDB文件给从服务器
  3. 从服务器接收RDB文件,清空本地数据,载入RDB文件(忽略过期key,和过期策略有关)
  4. 主服务同步缓存队列中的指令给从服务器,从服务器执行这些指令
  5. 从服务器重写AOF

增量同步

redis增量同步中3个关键概念点:

  1. 服务器ID:标识redis服务器ID
  2. 复制偏移量:主服务器用于标记它已经发出去多少;从服务器用于标记它已经接收了多少
  3. 复制缓冲区:主服务器维护一个1M的FIFO队列,用于记录近期执行的命令

从服务器将自己的复制偏移量发给主服务器,如果主服务器发现,该偏移量还在复制缓冲区,那么就执行增量复制,将偏移量后面的命令同步给从服务器;否则执行全量同步。

一般来说,在从服务器拥有大部分数据的场景下,没必要进行全量同步,所以要尽量避免全量同步。

全量OR增量

决定权基本在从服务器上:

  1. 从服务器发现自己从来没同步过,执行全量同步
  2. 从服务器发起同步命令PSYNC,但是主服务器发现上次同步的对象不是自己(服务器ID不一致),执行全量同步
  3. 从服务器发起同步命令PSYNC,主服务器发现偏移量太老,数据已经不在复制缓冲区,执行全量同步
  4. 从服务器发起同步命令PSYNC,主服务器发现偏移量在复制缓冲区,执行增量同步

由此推断:

  1. PSYNC发起的不一定是全量同步
  2. 增加或缩小同步缓冲区,会直接影响执行全量还是增量同步

redis重启会怎么影响同步

前面提到,触发全量同步的其中一点,是两次同步的主服务器ID不一致,而重启服务器,会改变服务器ID

  1. 对于主服务器,重启后自己的服务器ID已改变,所有对应的从服务器都要全量同步
  2. 对于从服务器,重启会丢失上一次同步的主服务器ID,所以会触发全量同步

一种安全的重启机制(不会改变服务器ID

怎么避免全量同步

引起全量同步的总结:

  1. 主服务器宕机重连
  2. 主服务器没有安全重启(ID已变)
  3. 主从同步超时,同步偏移量不在缓冲区
  4. 从服务器重启(丢失主服务器ID)

所以避免措施:

  1. 主服务使用安全重启
  2. 增大缓冲区
  3. 调大超时

redis主从间网络不稳定会引发什么问题

和主从同步有关。网络不稳定会导致主从同步失败,需要结合redis的超时机制。

可能会导致(基于超时):

  1. 短暂的网络抖动,不属于超时,从服务器可以通过ACK机制重新补充丢失的数据,参考心跳机制
  2. 超时,但从服务器的偏移量还在缓冲区,增量复制
  3. 超时,偏移量不再缓冲区,全量复制

redis心跳机制

可结合TCP的ACK机制。

redis心跳机制有两个方向:

  1. 一个是主服务器向从服务器发送心跳,用于检测网络和从服务器的存活
  2. 一个是从服务器向主服务器发送 REPLCONF ACK,其中ACK会带上自身的复制偏移量。因此,从服务器可在心跳机制中同时触发同步机制。

第2点就类似TCP的ACK机制,ACK会告诉发送端下一次期望的数据报,然后发送端进行重发。

再结合TCP中滑动窗口协议,TCP是具备处理部分失序报文的能力,但redis的同步是严格有序的,所以redis不支持处理失序命令。

sentinel

sentinel如何监控主从集群

其工作核心:主观下线->客观下线->主节点故障转移

sentinel的三个定时任务:

  1. 获取主从结构信息,能够做到主从结构动态更新
  2. 获取其他sentinel节点的意见
  3. 对主从节点的心跳检测

监控过程:

首先sentinel获取主从结构信息,然后向所有节点发送心跳检测,如果这个时候发现某个节点没有回复,就把它标记为“主观下线”;如果这个节点是主节点,sentinel就会询问别的sentinel节点的主节点信息。如果大多数sentinel都认为这个主节点已经下线,就会认为这个主节点已经“客观下线”。

当主节点已经“客观下线”,就要步入故障转移阶段。

故障转移

两个步骤:

  1. sentinel中选出sentinel的leader
  2. sentinel leader挑出主节点

sentinel中选出leader是使用raft算法。选举出leader后,leader从健康节点中依据(优先级,偏移量,服务器ID)这三个维度进行排序,挑出一个节点作为主节点。

选出主节点后,sentinel要命令其他从节点连接新的主节点,同时保持关注旧主节点,在旧主节点宕机恢复之后,sentinel要将它设为从节点并命令它连接新的主节点。

在从节点连接新的主节点后,需要做一件事:同步。此时parallel-syncs参数可决定同时同步的节点数。当parallel-syncs设置过小时,那说明同时只能由一个从节点进行同步,如果从节点过多时,会导致整个故障转移的过程时间很长;当parallel-syncs设置过大时,说明同时由多个从节点进行全量同步,而全量同步的过程中需要清楚本地数据再载入RDB文件,从而导致这些正在全量的从节点不可用。

从节点最好优先级都配置为一样的,这样就会选取偏移量最大的从节点为主节点,这样的节点数据是最新的

脑裂

所有的主从模式都会有脑裂问题。发生脑裂的根本原因在于,当一个主节点被标记为从节点时(客观下线),而这个主节点还是以为自己是主节点,相当于当前的主从结构里有双主节点,此时如果客户端在伪主节点上执行命令,会导致两主之间数据不一致,从而导致脑裂。

解决方案

redis的配置文件中,存在两个参数:

  1. min-replicas-to-write 3
  2. min-replicas-max-lag 10

min-replicas-to-write表示连接到master的最少slave数量,min-replicas-max-la表示slave连接到master的最大延迟时间

结合来看,如果主节点的从节点少于3,并且主从复制延迟时间大于10s,主节点都会拒绝写入。这样能缓解脑裂问题(sentinel模式下的脑裂),但不能根本解决(cluster模式下的脑裂)。

只有非主从结构才能彻底解决这个问题。

redis为什么不直接用M-S结构而要引入sentinel

出于性能考虑,sentinel可以单独部署,sentinel在选举leader和挑选主节点时不会影响redis集群的性能。

cluster

读写过程的key有两个映射阶段:

  1. 先用key的hash值,将其分成16384个槽
  2. 每个槽被分配到不同的服务器上(这里的服务器指的是主从结构重的主服务器)

redis cluster是一种peer to peer的结构,即每个服务器都能提供读写服务。如果请求的key不在这个服务器上,该服务器会返回一个move错误,让客户端再请求一次正确的服务器(类似HTTP重定向),额外增加了IO开销。

基于上述处理,如果在客户端维护一份槽映射表,那么就可以省去转发这一步骤,这就是智能客户端。

槽迁移

分布式环境下,可能会对cluster进行扩容缩容,这个时候槽就会发生迁移过程。

redis提供了槽迁移命令,主要步骤就是让目标节点准备好接收,源节点准备好迁移,然后迁移是小批量的进行。

迁移过程中key的访问?

在迁移过程中,一个槽可能有部分key在目标节点,还有一部分在源节点。当有请求key发送到源节点,源节点发现该key已经被迁移,会返回一个ASK错误,这个错误会引导客户端直接去访问迁移后的节点。

move 与 ask的比较
两种都是重定向错误,move是发生在迁移完成后,ask是发生在迁移过程中。

smart client

关键特点:

  1. 维护了槽映射关系,并且会在收到move错误后更新
  2. 对每个节点,创建对应的线程池,提高smart client的性能

好处是:

  1. 避免与节点的通讯还需要通过一层Proxy
  2. 极大的减少move错误发生的概率,在发生迁移后也能很快的修正映射关系

坏处是,映射关系会稍微滞后。

上一篇下一篇

猜你喜欢

热点阅读