常见面试题-Redis 主从复制原理以及痛点

Redis 主从复制如何同步数据呢?

参考文章:https://blog.csdn.net/Seky_fei/article/details/106877329

https://zhuanlan.zhihu.com/p/55532249

https://cloud.tencent.com/developer/article/2063597

https://xie.infoq.cn/article/4cffee02a2a12c2450412fa21

在 Redis2.8 之后,进行主从同步使用 psync 命令,在 2.8 之前使用 sync 命令,sync 在断线情况下会进行全量复制,效率很低,因此使用 psync 命令进行改进,具备了 全量同步部分同步 的功能

psync 命令格式如下:

# runid 为 master 的身份 id
# offset 是从节点同步命令的偏移量
psync [runid] [offset]

那么在从节点第一次同步主节点数据时,会向主节点发送 psync ? -1 命令,那么 master 收到命令后,匹配 runid,如果匹配成功,会使用 bgsave 生成 RDB 文件快照,并将 RDB 文件发送给 slave,slave 在收到 RDB 快照后将数据载入

如果从节点是断线之后重新连接上主节点,那么在同步数据时,会向主节点发送 psync runid offset ,那么 master 在收到命令之后,如果 runid 匹配成功,会判断 offset 这个偏移量与 master 本机的数据缓存的偏移量相差是否超过了 复制积压缓冲区 的大小,如果超过了,说明 slave 断线时间太长了,master 的 复制积压缓冲区 中的数据已经和 slave 的数据不连续了,因此进行全量复制;否则,就进行增量复制,将 slave 断线期间没有收到的数据给发送一下就可以了

主节点在接收到命令时,如何保存命令并将命令增量复制给从节点?

master 在接收命令时,将命令传递给 slave 的同时,也会将命令存放到 复制积压缓冲区,并且记录当前积压队列中存放命令的偏移量 offset,当 slave 重连时,master 会根据 slave 传的 offset 和自己最新命令的 offset 进行比较,如果相差的大小超过 复制积压缓冲区 的大小,就直接进行全量复制;否则,就增量复制

复制积压缓冲区 其实就是一个环形的循环队列,默认大小为 1MB,该缓冲区大小越大,允许 slave 断线的时间就越长

#设置复制积压缓冲区大小
repl-backlog-size 1mb

Redis 4.0 PSYNC2.0

在 Redis2.8 之后,使用 psync runid offset 来实现增量同步,但是如果发生了主从切换,那么新的 master 的 runid 和 offset 都会发生变化,因此还是需要全量复制

在 Redis4.0 的 PSYNC2.0 中优化了这个问题,即使发生了主从切换,如果条件允许,也可以进行增量同步

那么在 PSYNC2.0 中,舍弃了 runid 的概念,使用 replidreplid2 来代替,并且 replid2 和 second_replid_offset 是一对:

  • 对 master 来说,replid 就是自己的复制 id,没有发生主从切换之前,replid2 为空,发生主从切换之后,新的 master 的 replid2 是旧 master 的 replid
  • 对 slave 来说,replid 保存的是自己当前正在同步的 master 的 replidreplid2 保存的旧 master 的 replid

second_replid_offset 记录了上一次复制的主库的 offset

psync2.0中如何判断增量复制?

从节点向主节点发送同步请求,那么主节点需要判断两个东西:

  1. 从节点的 offset 是否在 复制积压缓冲区

  2. 判断复制历史是否一样

    判断复制历史首先 master 要判断 replid 是否一致,也就是从节点的 replid 和 master 的 replid2 相同,如果一致(表明新的主节点和从节点之前都是复制的同一个主节点),再来判断这个 offset 是否在上一次的 second_replid_offset,如果也在的话,就可以进行增量同步

下边这个例子说明一下为什么 offset 要在上一次的 second_replid_offset 中:

在这里插入图片描述

比如一主一从机器来说,master1 和 slave1,master1 中写入两条数据:

# master1  
lpush A B
lpush A C

我们假设一条数据偏移量为 10,那么在 master1 中插入两条数据,master1 的 offset = 20,此时 master1 和 slave1 主从复制,slave1 在复制完第一条数据之后,也就是 lpush A B 之后,failover 后 slave1 变为新的 master,我们先称原 slave1 为 master2,原 master1 为 slave2

那么 master2 又会接收新的请求,假如在 master2 中写入如下数据:

# master2
lpush A D

那么此时 master2 中也有两条数据了,如上图,在发生主从切换之后,master2 和 slave2 的 offset 都是 20,是相同的,但是他们两个能进行增量复制吗?

肯定不可以,虽然他们的 offset 是相同的,但是他的复制上下文已经变了,原来的 slave 进行主从复制是基于

lpush A B
lpush A C

这个上下文来进行复制的,那么在主从切换之后,新的主库写入了新的数据,新主库的上下文已经变为了:

lpush A B
lpush A D

和原来主库的上下文都不同了,那么只单纯比较 offset 是没有意义的,所以需要拿 offset 和 second_replid_offset 进行比较

PSYNC-AOF【扩展内容】

详细参考:Redis 主从复制演进历程与百度智能云的实践

百度智能云提出了 - PSYNC-AOF 方案

在 Redis 的主从复制中存在的问题,首先就是内存,Redis 的数据都存储在内存中,Backlog(复制积压缓冲区) 也在内存中,那么内存容量是有限的,当主从连接断开重连后,从库在主库的 Backlog 中查找数据,因为 Backlog 容量是有限的,所以查找数据也有限,那么如果主从断连时间过长的话,就在 Backlog 中找不到对应的数据,就需要进行全量复制了

那么 PSYNC-AOF 方案中,将 AOF 的内容和 Backlog 内容保持一致,主从断连后,从库去主库的 Backlog 中查找数据,那么如果没有找到的话,尝试从 AOF 里找,那么通过 RDB 文件作为基准,AOF 作为增量,就可以实现一个更大的 复制积压缓冲区 ,从而可以应对更长的网络延迟以及网络断开。

总结:总之,主从复制的痛点在于如果主从连接断开时间过长,或者发生主从切换,会导致全量复制,全量复制很伤,所以优化主从数据同步的目的就是尽可能地避免全量复制

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/207286.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

每日一题(LeetCode)----链表--分隔链表

每日一题(LeetCode)----链表–分隔链表 1.题目(86. 分隔链表) 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初…

pyqt5的组合式部件制作(四)

对组合式部件的制作又改进了一版,组合式部件的子部件不再需要单独“提升为”,如果在模板文件的提升部件窗口内选择了“全局包含”,那么只需要在模板文件和应用文件中直接复制粘贴即可,部件的应用更为简便。如下图:按住…

在windows笔记本中安装tensorflow1.13.2版本的gpu环境2

tensorflow1.13.2版本的gpu环境 看python-anacona的安装只需要看1.1部分即可 目录 1.1 Anaconda安装 1.2 tensorflow-gpu安装 1.3 python编译器-pycharm安装 1.1 Anaconda安装 从镜像源处下载anaconda,地址:Index of /anaconda/archive/ | 北京…

快速入门Postman接口测试,让你轻松掌握接口测试技能!

1.postman界面 下载安装postman工具,以下是postman的界面 快捷区:提供常用的操作入口,新建请求,执行器,导入别人共享的收藏夹测试数据,包括运行收藏夹的一组测试数据; 侧边栏:搜索栏…

SpringBoot集成Swagger2登录功能和安全认证

本篇文章要实现的功能: 1.集成swagger2.集成swagger登录功能,访问 /swagger-ui.html需要先登录3.集成安全认证,访问接口时携带header 请求接口时携带了上一步输入的header参数和值 1.集成swagger jdk11,SpringBoot 2.7.13 pom…

pycurl>=7.43.0.5机器学习环境配置问题

去官网下载对应版本.whl文件,注意使用python --version提前查看 python版本信息和64bit还是32bit,下载对应版本。 cd 到该路径下,并pip。6

排序算法-----快速排序(非递归实现)

目录 前言 快速排序 基本思路 非递归代码实现 前言 很久没跟新数据结构与算法这一栏了,因为数据结构与算法基本上都发布完了,哈哈,那今天我就把前面排序算法那一块的快速排序完善一下,前面只发布了快速排序递归算法,…

国际版Amazon Lightsail的功能解析

Amazon Lightsail是一项易于使用的云服务,可为您提供部署应用程序或网站所需的一切,从而实现经济高效且易于理解的月度计划。它是部署简单的工作负载、网站或开始使用亚马逊云科技的理想选择。 作为 AWS 免费套餐的一部分,可以免费开始使用 Amazon Lightsail。注册…

机器学习/sklearn 笔记:K-means,kmeans++

1 K-means介绍 1.0 方法介绍 KMeans算法通过尝试将样本分成n个方差相等的组来聚类,该算法要求指定群集的数量。它适用于大量样本,并已在许多不同领域的广泛应用领域中使用。KMeans算法将一组样本分成不相交的簇,每个簇由簇中样本的平均值描…

【办公常识】写好的代码如何上传?使用svn commit

首先找到对应的目录 找到文件之后点击SVN Commit

oracle面试相关的,Oracle基本操作的SQL命令

文章目录 数据库-Oracle〇、Oracle用户管理一、Oracle数据库操作二、Oracle表操作1、创建表2、删除表3、重命名表4、增加字段5、修改字段6、重名字段7、删除字段8、添加主键9、删除主键10、创建索引11、删除索引12、创建视图13、删除视图 三、Oracle操作数据1、数据查询2、插入…

【Delphi】开发IOS 程序,TLabel 中英文字对齐(水平),一行代码解决显示对齐问题!

目录 一、问题现象: 二、解决方案(一行代码解决ios对齐问题): 三、解决后效果: 四、后记: 一、问题现象: 在用 Delphi 开发ios程序时,使用TLabel控件显示,会出现中英…