redis-3

作者: 甜甜起司猫_ | 来源:发表于2021-06-24 21:45 被阅读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错误发生的概率,在发生迁移后也能很快的修正映射关系

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

    相关文章

      网友评论

          本文标题:redis-3

          本文链接:https://www.haomeiwen.com/subject/cdigyltx.html