redis 集群

1. 主从复制

1.1 一主二从

  • 主机shutdown后情况如何?从机是上位还是原地待命

从机不动,原地待命,从机数据可以正常使用;等待主机重启动归来

  • 主机shutdown后,重启后主从关系还在吗?从机还能是否复制?

青山依旧在。还可以

1.2 薪火相传

  1. 上一个slave可以是下一个slave的Master,slave同样可以接收其他slaves的连接和同步请求,那么该slave作为了链条中下一个的master, 可以有效减轻master的写压力,去中心化降低风险.
    中途变更转向:会清除之前的数据,重新建立拷贝最新的
    风险是一旦某个slave宕机,后面的slave都没法备份
    2

1.3 反客为主

当一个master宕机后,后面的slave可以立刻升为master,其后面的slave不用做任何修改。
用 slaveof no one 将从机变为主机。

1.4 主从同步原理

1.4.1 全量同步

  • 主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点

  • 两个概念

    • Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid
    • offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

·因此slave做数据同步,必须向master声明自己的replication id 和offset,master才可以判断到底需要同步哪些数据。

master判断发现slave发送来的replid与自己的不一致,说明这是一个全新的slave,就知道要做全量同步了。

master会将自己的replid和offset都发送给这个slave,slave保存这些信息。以后slave的replid就与master一致了。

主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点,流程:
redis 集群_第1张图片

  • 主要步骤

    • slave节点请求增量同步
    • master节点判断replid,发现不一致,拒绝增量同步
    • master将完整内存数据生成RDB,发送RDB到slave
    • slave清空本地数据,加载master的RDB
    • master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
    • slave执行接收到的命令,保持与master之间的同步

1.4.2 增量同步

redis 集群_第2张图片
先看两个概念: replication bufferrepl_backlog_buffer

repl_backlog_buffer:它是为了从库断开之后,如何找到主从差异数据而设计的环形缓冲区,从而避免全量复制带来的性能开销。如果从库断开时间太久,repl_backlog_buffer 环形缓冲区被主库的写命令覆盖了,那么从库连上主库后只能乖乖地进行一次全量复制,所以 repl_backlog_buffer 配置尽量大一些,可以降低主从断开后全量复制的概率。而在 repl_backlog_buffer 中找主从差异的数据后,如何发给从库呢?这就用到了 replication buffer。

replication buffer:Redis 和客户端通信也好,和从库通信也好,Redis 都需要给分配一个 内存 buffer 进行数据交互,客户端是一个 client,从库也是一个 client,我们每个 client 连上 Redis 后,Redis 都会分配一个 client buffer,所有数据交互都是通过这个 buffer 进行的:Redis 先把数据写到这个 buffer 中,然后再把 buffer 中的数据发到 client socket 中再通过网络发送出去,这样就完成了数据交互。所以主从在增量同步时,从库作为一个 client,也会分配一个 buffer,只不过这个 buffer 专门用来传播用户的写命令到从库,保证主从数据一致,我们通常把它叫做 replication buffer。

1.4.3 repl_backlog原理

这个文件是一个固定大小的数组,只不过数组是环形,也就是说角标到达数组末尾后,会再次从0开始读写,这样数组头部的数据就会被覆盖。

repl_baklog中会记录Redis处理过的命令日志及offset,包括master当前的offset,和slave已经拷贝到的offset:
redis 集群_第3张图片
slave与master的offset之间的差异,就是salve需要增量拷贝的数据了。

随着不断有数据写入,master的offset逐渐变大,slave也不断的拷贝,追赶master的offset:
redis 集群_第4张图片
直到数组被填满:
redis 集群_第5张图片
此时,如果有新的数据写入,就会覆盖数组中的旧数据。不过,旧的数据只要是绿色的,说明是已经被同步到slave的数据,即便被覆盖了也没什么影响。因为未同步的仅仅是红色部分。

但是,如果slave出现网络阻塞,导致master的offset远远超过了slave的offset:

redis 集群_第6张图片
如果master继续写入新数据,其offset就会覆盖旧的数据,直到将slave现在的offset也覆盖:
redis 集群_第7张图片
棕色框中的红色部分,就是尚未同步,但是却已经被覆盖的数据。此时如果slave恢复,需要同步,却发现自己的offset都没有了,无法完成增量同步了。只能做全量同步。
2

1.4.4 为什么还有无磁盘复制模式?

Redis 默认是磁盘复制,但是 ·如果使用比较低速的磁盘,这种操作会给主服务器带来较大的压力 。Redis 从 2.8.18 版本开始尝试支持无磁盘的复制。使用这种设置时,子进程直接将 RDB 通过网络发送给从服务器,不使用磁盘作为中间存储。

无磁盘复制模式:master 创建一个新进程直接 dump RDB 到 slave 的 socket ,不经过主进程,不经过硬盘。适用于 disk 较慢,并且网络较快的时候。

使用 repl-diskless-sync 配置参数来启动无磁盘复制。

使用 repl-diskless-sync-delay 参数来配置传输开始的延迟时间;master 等待一个 repl-diskless-sync-delay 的秒数,如果没 slave 来的话,就直接传,后来的得排队等了;否则就可以一起传
##1.5 主从同步优化
从同步可以保证主从数据的一致性,非常重要。

可以从以下几个方面来优化Redis主从就集群:

  • 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO。
  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO
  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

2. 哨兵模式

2.1选举新的master的策略

  1. priority 优先级高
    2

  2. offset 大

  3. 最小的runid 节点

redis 集群_第8张图片

2. 俯首称臣

sentinel leader 像选举出来的新 master 执行 slaveof no one 命令,将其升级为 master节点。
sentinel 发送slavleof 命令到其他slave 节点,让他们成为新的master的slave节点。

3. 老master 变成slave 节点

老master 节点恢复后,seltinel leader 让原来的master 降级为salve节点。

你可能感兴趣的:(#,缓存,redis)