J3:Redis主从复制(减少服务中断),哨兵机制(主从切换)

主从复制

  • 主从库采用读写分离(读操作 主从都可以,写操作:主库执行 同步到从库)
  • 读写分离是为了:如果主从都可以进行修改,那就要对主从进行协调,分离可以通过同步给从库,让主从数据一致。
    AOF和RDB可以让数据少丢失,但是减少服务的中断需要增加冗余副本

主从第一次同步

主从复制使用RDB不用AOF是因为 AOF文件比较大(还会包含一个Key的重复操作),ROB是经过压缩的二进制,文件小,执行快,如果需要使用AOF(需要打开AOF功能,要选择文件刷盘策略,业务不敏感的场景不需要开启AOF)

从节点:replicaof 主ip 主port

在这里插入图片描述

  1. 主从建立链接,协调。从库给主库发送 psync 主库的 runID(?,第一次复制不知道主库id) 复制进度 offset(-1,代表第一次复制)命令,表示要进行数据同步。主库收到命令之后,返回 FULLRESYNC {主库 runID} {和主库目前的复制进度 offset},FULLRESYNC 响应表示第一次复制采用的全量复制
  2. 主库将所有数据同步给从库(使用RDB文件): 执行bgsave 生成rdb文件,从库接受文件清空数据库,加载文件。主库在同步的时候仍然可以接受请求,为保证主从数据一致,会将新操作写到 replication buffer。

在这里插入图片描述

基于长连接的命令传播

主从完成全量复制之后,会维护长连接,主库会通过长连接同步给从库。

主从网络中断

  • Redis 2.8 之前,如果主从库在命令传播时出现了网络闪断,从库就会和主库重新进行一次全量复制。
  • Redis 2.8 开始,主从库会采用增量复制的方式。

主从通过 repl_backlog_buffer 实现增量复制。
数据会写入 replication buffer和 repl_backlog_buffer。
**repl_backlog_buffer:**只要从库存在,这个就会存在,主库将命令传播给从库的时候,会记录到repl_backlog_buffer一份,只有缓存了这些命令之后,从库断了 发送psync $master_runid $offset 才能同步数据。(大一点可以降低全量同步的概率)要将数据发送给从库 需要使用replication buffer。
replication buffer: redis把数据先写入buffer,再把数据通过socket发送出去,完成数据交互,主从增量同步的时候,从库也会有一个client,传播用户的写命令,这个buffer叫做replication buffer。超过client-output-buffer-limit限制,会断开连接。

  • repl_backlog_buffer 是一个环形缓冲区,主库会记录自己写到的位置,从库则会记录自己已经读到的位置。
  • 对主库来说,对应的偏移量就是 master_repl_offset。
  • 从库已复制的偏移量 slave_repl_offset。

在这里插入图片描述

  • 主从断连之后,主库的操作会写入replication buffer,也会写入repl_backlog_buffer
  • repl_backlog_buffer 主库会记录自己写的位置,从库会记录读的位置。
  • 主库写的偏移量是master_repl_offset,从库已复制的偏移量是slave_repl_offset
  • 从库恢复之后,会发给主库psync,把slave_repl_offset 发送给主库,主库会判断两个直接差了多少(如果数据被覆盖,进行全量复制)

增量同步
在这里插入图片描述

  • 如果读操作过慢,容易导致主从数据不一致。
  • repl_backlog_size:缓冲空间大小 = 主库写入命令速度 * 操作大小 - 主从库间网络传输命令速度 * 操作大小。可以考虑扩大缓冲空间

哨兵机制(持续提供服务)

哨兵是一个特殊的redis进程,哨兵的任务是:健康、选主和通知

哨兵进程会在定期给所有主从发送PING,如果从库回复超时,哨兵会标记为“主观下线”,如果是主库超时,为防止误判(重新选主,主从同步,开销大),通过哨兵集群(多实例一起判断,减小单哨兵误判的可能性)。当集群的多数判断主库“主观下线”那就回认定他已经“客观下线”,同时触发主从切换流程。(一般是选择 N/2+1)

如何选定新主库?

  1. 判断从库当前在线状态,在判断他之前的链接状态,超过 down-after-milliseconds时间10次以上,不适合做主库(筛选范围)
  2. 优先级最高的从库,通过 slave-priority设置
  3. 其次选择和旧主库同步程度最接近的从库
  4. 再次实例ID小的 会被选择

主从切换中,客户端如何正常请求

  • 使用读写分离,读正常,写失败(持续时间 = 哨兵切换主从时间+ 客户端感知新主库时间)
  • 如果不想让客户端感知失败,把失败写请求写入MQ,哨兵切换完在发给主库(适合对写值不敏感,切换时间长,消息堆积)
  • down-after-milliseconds参数是主从切换的感应期,过长容易导致故障时间变长,过短容易导致误判。

如果想让程序不感知服务中断,需要这样做:

  1. 哨兵把从变成主之后,会把新地址写入pubsub(switch-master)中。客户端需要订阅这个pubsub,当pubsub有数据,就可以获得最新主库数据,需要将写请求写入这个主库(哨兵主动通知客户端)
  2. 客户端也需要支持主动获取最新主从地址
  3. 客户端不能写死主从地址,需要从哨兵集群获取最新地址(sentinel get-master-addr-by-name),这样当异常之后就能获取到最新的实例地址。

选取哨兵领导者是通过Raft的共识算法(为每个哨兵设置随机超时时间,超时后每个哨兵请求其他哨兵为自己投票,其他哨兵对收到的第一个请求进行投票确认,一轮投票下来首先达到多数选票成为“哨兵领导者”,如果没有达到多数选票会进行重新选举)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值