300分钟吃透分布式缓存-27讲:Redis是如何进行主从复制的?

Redis 复制原理

为了避免单点故障,数据存储需要进行多副本构建。同时由于 Redis 的核心操作是单线程模型的,单个 Redis 实例能处理的请求 TPS 有限。因此 Redis 自面世起,基本就提供了复制功能,而且对复制策略不断进行优化。
在这里插入图片描述
通过数据复制,Redis 的一个 master 可以挂载多个 slave,而 slave 下还可以挂载多个 slave,形成多层嵌套结构。所有写操作都在 master 实例中进行,master 执行完毕后,将写指令分发给挂在自己下面的 slave 节点。slave 节点下如果有嵌套的 slave,会将收到的写指令进一步分发给挂在自己下面的 slave。通过多个 slave,Redis 的节点数据就可以实现多副本保存,任何一个节点异常都不会导致数据丢失,同时多 slave 可以 N 倍提升读性能。master 只写不读,这样整个 master-slave 组合,读写能力都可以得到大幅提升。

master 在分发写请求时,同时会将写指令复制一份存入复制积压缓冲,这样当 slave 短时间断开重连时,只要 slave 的复制位置点仍然在复制积压缓冲,则可以从之前的复制位置点之后继续进行复制,提升复制效率。
在这里插入图片描述
主库 master 和从库 slave 之间通过复制 id 进行匹配,避免 slave 挂到错误的 master。Redis 的复制分为全量同步和增量同步。Redis 在进行全量同步时,master 会将内存数据通过 bgsave 落地到 rdb,同时,将构建 内存快照期间 的写指令,存放到复制缓冲中,当 rdb 快照构建完毕后,master 将 rdb 和复制缓冲队列中的数据全部发送给 slave,slave 完全重新创建一份数据。这个过程,对 master 的性能损耗较大,slave 构建数据的时间也比较长,而且传递 rdb 时还会占用大量带宽,对整个系统的性能和资源的访问影响都比较大。而增量复制,master 只发送 slave 上次复制位置之后的写指令,不用构建 rdb,而且传输内容非常有限,对 master、slave 的负荷影响很小,对带宽的影响可以忽略,整个系统受影响非常小。

在 Redis 2.8 之前,Redis 基本只支持全量复制。在 slave 与 master 断开连接,或 slave 重启后,都需要进行全量复制。在 2.8 版本之后,Redis 引入 psync,增加了一个复制积压缓冲,在将写指令同步给 slave 时,会同时在复制积压缓冲中也写一份。在 slave 短时断开重连后,上报master runid 及复制偏移量。如果 runid 与 master 一致,且偏移量仍然在 master 的复制缓冲积压中,则 master 进行增量同步。

但如果 slave 重启后,master runid 会丢失,或者切换 master 后,runid 会变化,仍然需要全量同步。因此 Redis 自 4.0 强化了 psync,引入了 psync2。在 pysnc2 中,主从复制不再使用 runid,而使用 replid(即复制id) 来作为复制判断依据。同时 Redis 实例在构建 rdb 时,会将 replid 作为 aux 辅助信息存入 rbd。重启时,加载 rdb 时即可得到 master 的复制 id。从而在 slave 重启后仍然可以增量同步。

在 psync2 中,Redis 每个实例除了会有一个复制 id 即 replid 外,还有一个 replid2。Redis 启动后,会创建一个长度为 40 的随机字符串,作为 replid 的初值,在建立主从连接后,会用 master的 replid 替换自己的 replid。同时会用 replid2 存储上次 master 主库的 replid。这样切主时,即便 slave 汇报的复制 id 与新 master 的 replid 不同,但和新 master 的 replid2 相同,同时复制偏移仍然在复制积压缓冲区内,仍然可以实现增量复制。

Redis 复制分析

在设置 master、slave 时,首先通过配置或者命令 slaveof no one 将节点设置为主库。然后其他各个从库节点,通过 slaveof $master_ip $master_port,将其他从库挂在到 master 上。同样方法,还可以将 slave 节点挂载到已有的 slave 节点上。在准备开始数据复制时,slave 首先会主动与 master 创建连接,并上报信息。具体流程如下。
在这里插入图片描述
slave 创建与 master 的连接后,首先发送 ping 指令,如果 master 没有返回异常,而是返回 pong,则说明 master 可用。如果 Redis 设置了密码,slave 会发送 auth $masterauth 指令,进行鉴权。当鉴权完毕,从库就通过 replconf 发送自己的端口及 IP 给 master。接下来,slave 继续通过 replconf 发送 capa eof capa psync2 进行复制版本校验。如果 master 校验成功。从库接下来就通过 psync 将自己的复制 id、复制偏移发送给 master,正式开始准备数据同步。

主库接收到从库发来的 psync 指令后,则开始判断可以进行数据同步的方式。前面讲到,Redis 当前保存了复制 id,replid 和 replid2。如果从库发来的复制 id,与 master 的复制 id(即 replid 和 replid2)相同,并且复制偏移在复制缓冲积压中,则可以进行增量同步。master 发送 continue 响应,并返回 master 的 replid。slave 将 master 的 replid 替换为自己的 replid,并将之前的复制 id 设置为 replid2。之后,master 则可继续发送,复制偏移位置 之后的指令,给 slave,完成数据同步。

如果主库发现从库传来的复制 id 和自己的 replid、replid2 都不同,或者复制偏移不在复制积压缓冲中,则判定需要进行全量复制。master 发送 fullresync 响应,附带 replid 及复制偏移。然后, master 根据需要构建 rdb,并将 rdb 及复制缓冲发送给 slave。

对于增量复制,slave 接下来就等待接受 master 传来的复制缓冲及新增的写指令,进行数据同步。

而对于全量同步,slave 会首先进行,嵌套复制的清理工作,比如 slave 当前还有嵌套的 子slave,则该 slave 会关闭嵌套 子slave 的所有连接,并清理自己的复制积压缓冲。然后,slave 会构建临时 rdb 文件,并从 master 连接中读取 rdb 的实际数据,写入 rdb 中。在写 rdb 文件时,每写 8M,就会做一个 fsync操作, 刷新文件缓冲。当接受 rdb 完毕则将 rdb 临时文件改名为 rdb 的真正名字。

接下来,slave 会首先清空老数据,即删除本地所有 DB 中的数据,并暂时停止从 master 继续接受数据。然后,slave 就开始全力加载 rdb 恢复数据,将数据从 rdb 加载到内存。在 rdb 加载完毕后,slave 重新利用与 master 的连接 socket,创建与 master 连接的 client,并在此注册读事件,可以开始接受 master 的写指令了。此时,slave 还会将 master 的 replid 和复制偏移设为自己的复制 id 和复制偏移 offset,并将自己的 replid2 清空,因为,slave 的所有嵌套 子slave 接下来也需要进行全量复制。最后,slave 就会打开 aof 文件,在接受 master 的写指令后,执行完毕并写入到自己的 aof 中。

相比之前的 sync,psync2 优化很明显。在短时间断开连接、slave 重启、切主等多种场景,只要延迟不太久,复制偏移仍然在复制积压缓冲,均可进行增量同步。master 不用构建并发送巨大的 rdb,可以大大减轻 master 的负荷和网络带宽的开销。同时,slave 可以通过轻量的增量复制,实现数据同步,快速恢复服务,减少系统抖动。

但是,psync 依然严重依赖于复制缓冲积压,太大会占用过多内存,太小会导致频繁的全量复制。而且,由于内存限制,即便设置相对较大的复制缓冲区,在 slave 断开连接较久时,仍然很容易被复制缓冲积压冲刷,从而导致全量复制。

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

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

相关文章

基于SWOT的智能手机企业财务战略研究1.62

摘 要 近些年,网络技术日新月异,智能手机深受消费者喜爱,人们通过网络,手机应用,可以极大地方便人们学习,工作等等。由于国家对电信行业的大力支持,中国消费者群体逐步成为最具潜力的手机购买者…

十六、接口隔离原则、反射、依赖注入

接口隔离原则、反射、特性、依赖注入 接口隔离原则 客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。 五种原则当中的i 上一章中的接口,即契约。 契约就是在说两件事,甲方说自己不会多要,乙方会在…

朴素贝叶斯算法基础——案例:对新闻进行分类

贝叶斯公式 朴素:假设特征与特征之间相互独立 朴素贝叶斯算法:朴素贝叶斯 应用场景:文本分类(单词作为特征) 拉普拉斯平滑系数 Ni:F1词在C类别所有文档中出现的次数 N:所属类别C下的文档所…

AHU 数据库 实验三

《数据库》实验报告 【实验名称】 实验3 数据库的连接查询 【实验目的】 1. 熟悉基本的连接查询的概念和作用; 2. 了解数据库管理系统DBMS 实现连接查询的基本方法; 3. 掌握SQL语言连接查询语句的语法和功能&#…

STM32第十课:串口发送

一、usart串口 1.1 USART串口协议 串口通讯(Serial Communication) 是一种设备间非常常用的串行通讯方式,因为它简单便捷,因此大部分电子设备都支持该通讯方式,电子工程师在调试设备时也经常使用该通讯方式输出调试信息。在计算机科学里&…

主流数据库的区别

几个主流的数据库有: 1. MySQL:MySQL是一种关系型数据库管理系统,常用于Web应用程序开发和数据存储。 2. Oracle:Oracle是一种关系型数据库管理系统,由Oracle Corporation开发和销售。它广泛用于企业级应用程序中。 …

在使用qml的qmldir文件创建常用组件报错unknow component

解决方法:Qt Creator中的工具-->QML/JS-->重置代码模型 参考博文:QML自定义模块及qmldir的使用_同一资源文件目录下的qml模块使用-CSDN博客 不一样的地方是我给我的文件起了别名 以及我的qrc文件路径有前缀/qml 总体操作: 1.使用模块中的组件时…

线程与进程的区别、协程

1【线程与进程的区别、协程】 【1】 进程跟线程 进程(Process)和 线程(Thread)是操作系统的基本概念, 但是它们比较抽象, 不容易掌握。关于多进程和多线程,教科书上对经典的一句话“进程是资源分…

铭文:探索比特币世界的数字印记

铭文是什么? 铭文指的是在某种物品(如石头、硬币、平板等)上刻有文字。在比特币领域,铭文指的是刻在聪(satoshi)上的元数据。比特币的最小单位是聪,1比特币可分为1亿聪。每个聪都通过序数理论进…

OpenAI GPT LLMs 高级提示词工程方法汇总

原文地址:An Introduction to Prompt Engineering for OpenAI GPT LLMs Github:Prompt-Engineering-Intro 2023 年 3 月 2 日 提示工程指南 | Prompt Engineering Guide Naive 提示词:带有提示的情感分类器 prompt Decide whether a T…

计算机缺失iutils.dll怎么办,分享5种靠谱的解决方法

​在计算机系统运行过程中,如果发现无法找到或缺失iutils.dll文件,可能会引发一系列的问题与故障。首先,由于iutils.dll是系统中一个重要的动态链接库文件,它的主要功能可能涉及到系统核心服务、应用程序支持或者特定功能模块的运…

互联网高频面:输入URL按下回车后,中间发生了什么

题目 输入URL按下回车后,中间发生了什么 这个问题其实是计算机网络里面很经典的一个问题,不能去死机硬背,很考察对网络架构和通信原理的理解,也是各个互联网大厂喜欢考察的面试题。 一些图片参考了小林的计算机网络面经 从输入…

“光谱视界革新:ChatGPT在成像光谱遥感中的智能革命“

遥感技术主要通过卫星和飞机从远处观察和测量我们的环境,是理解和监测地球物理、化学和生物系统的基石。ChatGPT是由OpenAI开发的最先进的语言模型,在理解和生成人类语言方面表现出了非凡的能力。本文重点介绍ChatGPT在遥感中的应用,人工智能…

爬虫案例2:playwright 超爽体验

参考链接:https://playwright.bootcss.com/python/docs/intro 目标网站:https://spa6.scrape.center/通过观察,页面的信息是通过Ajax请求后返回的信息 下面使用playwright实现绕过token的获取直接拿到返回的数据import asyncio import json f…

深入挖掘C语言之——联合

目录 联合的定义 联合的特点 联合的应用场景 在C语言中,联合(Union)是一种特殊的数据结构,它允许在同一内存地址存储不同类型的数据。与结构体(Struct)不同的是,联合中的所有成员共享同一块内…

C语言--从零开始的扫雷游戏

C语言--从零开始的扫雷游戏 1. 游戏说明2. 总体代码3. 详细讲解3.1 菜单部分3.2 游戏主体部分3.2.1 总体分析3.2.2 棋盘初始化3.2.3 棋盘展示3.2.4 设置地雷3.2.5 扫雷阶段3.2.6 统计雷个数的代码3.2.7 使用迭代的方式进行展开:3.2.8 扫雷部分主体代码 4. 总结 1. 游…

docker常用操作-docker私有仓库的搭建(Harbor),并将本地镜像推送至远程仓库中。

1、docker-compose安装,下载docker-compose的最新版本 第一步:创建docker-compose空白存放文件vi /usr/local/bin/docker-compose 第二步:使用curl命令在线下载,并制定写入路径 curl -L "https://github.com/docker/compos…

Linux学习:基础开发工具的使用(1)

目录 1. Linux软件包管理器:yum工具1.1 yum是什么(软件商城)1.2 yum的使用1.3 yum的背景生态 2. 项目开发与集成开发环境3. vim编辑器3.1 vim编辑器的常见模式与模式切换3.3 vim编辑器的使用3.3.1 命令模式下的常见命令:3.3.2 vim…

【rk3368 android6.0 恢复出厂设置功能】

rk3368 android6.0 恢复出厂设置功能 恢复出厂设置三种方法一,设置--进入恢复出厂设置页面二,发送广播形式三,命令形式总结 郑重声明:本人原创博文,都是实战,均经过实际项目验证出货的 转载请标明出处:攻城狮2015 恢复…

主机、虚拟机和开发板三者互相之间能ping通的配置参数

主机网络配置 开发板网络配置 虚拟机网络配置