26 redis 中 replication/cluster 集群中的主从复制

前言

我们这里首先来看 redis 这边实现比较复杂的 replication集群模式 

我们这里主要关注的是 redis 这边的主从同步的相关实现

这边相对比较简单, 我们直接基于 cluster集群模式 进行调试

 

 

主从命令同步复制

比如这里 master 是 redis_7002, slave 是 redis_7005

然后 这里是 master 这边直接同步 相关命令到各个 slave 

a19730e124774c85857090955e267bc1.png

 

然后这里是在 server.call:3765 进行命令存储到 backlog, aof, 以及同步发送到 slave 

命令真实执行是在 server.call:3675 的 cmd->proc->proc(c)

418fbbc6622a45fcbacaabe770ce8a0c.png

 

然后 redis_7005 这边拿到命令之后, 开始执行, 这个执行过程就和客户端这边发送执行命令一样 

e696cfc4a7874538a99cdc3dceaf3285.png

 

 

全量同步

整个流程分为两个 part, 一个是请求方, 就是 slave, 一个是提供方, 是 master 

slave 这边连接到 master 之后, slave 发送 SYNC 命令到 master 

master 通知客户端需要全量同步, 然后 master 这边后台去 dump 内存快照文件

slave 这边等待 master 这边 dump 内存快照文件, 并通过网络传递过来 

master 这边 dump 内存快照文件生成之后, 会向 slave 这边进行传输

slave 这边拿到 master 的 dump 的内存快照信息, 将其持久化到 临时文件, 完成之后重命名为 dump.rdb, 然后清空当前数据库, 然后 加载 dump.rdb 文件进行一个快照的数据恢复 

我们这里 一边一边的看, 先看 slave, 再看 master 

 

slave 的处理

这个是 slave 这边启动的时候 就会进行的一个操作

这里 syncWithMaster 根据 server.repl_state 这边同步的处理了几个 slave 和 master 的交互, 分为了几个不同的阶段 REPL_STATE_CONNECT, REPL_STATE_CONNECTING, REPL_STATE_RECEIVE_PING_REPLY, REPL_STATE_SEND_HANDSHAKE 等等 

比如这里会 发送 ping 给 master, 然后等待 master 这边回复信息 

在发送 masterauth 等相关信息, REPLCONF 等相关信息 

940a1e1b87924188a50abcc903662b87.png

 

后面和全量同步相关比较重要的流程就是 发送 SYNC 相关命令 

4a39f9fed3e045e2b222f3c318044dc3.png

 

然后 slave 这边会收到 master 这边的 FULLRESYNC 的通知 

34b74496b62949cda7472938880967fa.png

 

然后就是后面 slave 这边创建临时文件, 然后准备接受 master 这边 后台持久化 rdb 文件之后传递给 slave 这边, 之后的处理交给 readSyncBulkPayload

13b038ad45434cd3ad20a771daccc517.png

 

接受服务器这边传输过来的 rdb 文件的相关信息, 持久化到 上面创建的临时文件 repl_transfer_tmpfile

b0c87aeb46884d6aab1a5b22d8bcd4ed.png

 

然后就是 清空 slave 本地数据库, 然后重命名 临时文件 为 dump.rdb

然后加载 dump.rdb 到 slave 本地数据库 

2b7f847234874d599af93f8000cfbfdd.png

 

触发上面 syncWithMaster 的地方, 从上下文是可以看到是 serverCron 注册了一个定时任务, 100ms 跑一次, 跑的任务是 clusterCron 相关, 里面包含了这里的 connectWithMaster

所以节点的上下线 是可以再 100ms 左右感知到的 

6ead85e84fc64625b0fdd0679f2f5bc7.png

 

客户端这边相关日志如下, 基本上是 syncWithMaster + readSyncBulkPayload 这两部分中输出的 

前面两行是 connectWithMaster 中输出的连接 master 的相关日志 

后面的是 slave 这边向 master 发送 PING, master 进行回复 

后面的是 slave 这边发送 SYNC 指令, 询问是否可以增量同步, master 这边回复 只能全量同步

然后是 slave 这边接收到了 master 的 dump.rdb 的数据信息, 合计210字节, 清空 slave 的数据库, 从 dump.rdb 中加载数据到 slave 的数据库, 最终同步成功 

e6e4e511e17a4d33b9c4d079075d44da.png

 

 

master 的处理

需要全量同步的有几个场景 

场景1 是 slave 未传递同步偏移, 或者偏移传递错误 

场景2 是 master 和 slave 两边的 replyid 对不上 

场景3 是 slave 这边传递的偏移不在 master 这边数据同步的偏移区间内, 偏移错误 或者 落后的太多

c5c9b8775a3444bd9eec5f6bde5487f7.png

 

然后就是 master 这边处理全量同步的大头了 

场景1 如果是已经在进行 dump 内存快照文件, 则等待即可 

场景2 如果是已经在 dump 内存快照, 并且通过 tcp 直接传输数据, 则只能等待操作完成 

场景3 master 可以 dump 内存快照, 或者直接通过 tcp 传输数据, 

af85abbcfcfa45ceb8e0ea54936075f4.png

 

处理如下, 通过 startBgsaveForReplication 进行逻辑上的分发 

是 dump 内存快照文件, 还是 dump内存快照直接通过 tcp 传输数据 

52f259ff5fdc4f738f35bd2887180487.png

 

然后这里就是 fork 出子进程, 让子进程 来 dump 内存快照, 并保存到目标文件 

b8228fd2a58f4d5eaf6e17f268540803.png

 

然后 master 这边有定时任务在定时检查 子进程是否完成, 周期为 1秒 

如果完成了, 则向 slave 这边传输 dump 的内存快照的数据 

917c4dbcf0904cc08b352d0337f836ea.png

 

master 这边日志如下 

slave 这边发送过来了 PSYNC 的请求 

然后 master 这边判断 replyid, replyid2 匹配不上, 然后开始进行 全量同步 

然后 master 开始进行 dump 内存快照, fork 子进程 来生成 dump.rdb

master dump 内存快照生成完成之后, 发送数据到 slave, 之后记录 成功日志

da60fc2fde1b4f83b00c8c124b7f8a1e.png

 

 

基于 backlog 的增量同步

master 这边添加增量命令到 backlog

命令到 server.call:3765 的时候, 会将命令添加到 backlog 队列 

其中存储的数据就是 具体的执行命令, 存储在了一个数据中, 比如这里的 “set name4 jerry17”, 会将其存储为 一个长度为3的数组, 元素分别为 [“set”, “name4”, “jerry17”]

ba04a1534ab046718c620d9d3b0cad42.png

 

具体的复制命令到 backlog 中的相关处理如下, 可以简单理解为一个 memcpy 进去, 然后更新 索引 repl_backlog_idx

a3044b1a017d43da8de3032f1f1d5aca.png

 

 

slave 这边长时间和 master 失联, 重新连接之后发送 PSYNC 增量同步请求

clusterCron 为定时任务, 定时扫描集群的状态, 如果失联了, 则重新建立连接 

同样是在 syncWithMaster 的代码中, 这里传入了 replyid 和 offset 到 master 

0c02133909a24ac9949c51dcf4be9040.png

 

 

master 这边获取增量的命令响应给客户端

比如这里传输了 134 字节的命令数据到客户端, 我们 再来看一下 详细的命令信息

b3fae4214f3e40d9bb2df8f977400e62.png

 

从响应的字符串信息中可以看到, 传输了 “select 0”, “set name4 jerry18”, “set name4 jerry19”, “set name4 jerry20” 四条命令, 其中 “select 0” 是 redis 自己增加的, 然后 其他的几个命令是 客户端这边交互产生的

d264df34188742058d2ec667e97c961a.png

 

 

slave 这边收到命令之后执行

客户端这边接收到这一批次的命令之后, 依次进行执行 “select 0”, “set name4 jerry18”, “set name4 jerry19”, “set name4 jerry20” 进而实现了增量的同步 

f02dc9a1337142dbb429264788559fde.png

 

 

 

 

 

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

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

相关文章

11.HarmonyOS鸿蒙app_page的显示跳转方法

11.HarmonyOS鸿蒙app_page的显示跳转方法&#xff0c;text文本触发点击事件 使用Intent和Operation对象 创建新项目后&#xff0c;再创建secondPageAbility ability_main.xml <?xml version"1.0" encoding"utf-8"?> <DirectionalLayoutxmlns:…

LeetCode(65)LRU 缓存【链表】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; LRU 缓存 1.题目 请你设计并实现一个满足 LRU (最近最少使用) 缓存 约束的数据结构。 实现 LRUCache 类&#xff1a; LRUCache(int capacity) 以 正整数 作为容量 capacity 初始化 LRU 缓存int get(int key) 如果关键字 k…

【ArkTS】路由传参

传参 使用router.pushUrl()&#xff0c;router.push()官方不推荐再使用了。 格式&#xff1a; router.pushUrl({url: 路由地址,params:{参数名&#xff1a;值} )跳转时需要注意路由表中是否包含路由地址。 路由表路径&#xff1a; entry > src > main > resources &g…

Python+pip下载与安装

Hi, I’m Shendi Pythonpip下载与安装 最近有识别图片中物体的需求&#xff0c;于是选用了TensorFlow&#xff0c;在一番考虑下&#xff0c;还是选择直接使用Python。 Python下载安装 直接在搜索引擎搜索Python或通过 https://www.python.org 进入官网 在 Downloads 处点击 Al…

Gin之GORM的表关联查询操作详解

前期工作&#xff1a; 先查看下要操作的两张表&#xff1a; carton carton_cate //关系如下&#xff1a; // 一个章节对应一个动漫&#xff08;一对一&#xff1b;两种方法&#xff1a;belong to&#xff1b;has one&#xff09; // 一个动漫可以对应多个章节&#xff08;一…

Eclipse_01_如何设置代码文件背景颜色为护眼沙绿色

设置方法 Window --> Preference 参考文档 参考文档 1

uni-app ucharts中饼图与圆环图区别

项目情况&#xff1a; uni-app的用于移动端H5项目&#xff0c;包使用uni_modules目录存放。 图表引用ucharts中的echarts配置的组件方式 区别1 饼图与圆环图在echarts使用的配置都是pie类型。但是配置raduis使用&#xff1a; radius: [40%, 70%] 区别2 组件type指明&#xf…

Linux 非阻塞网络IO模式

非阻塞网络IO模式介绍 当用户线程发起一个 read 操作后&#xff0c;并不需要等待&#xff0c;而是马上就得到了一个结果。如果结果是一个 error 时&#xff0c;它就知道数据还没有准备好&#xff0c;于是它可以再次发送 read 操作。一旦内核中的数据准备好了&#xff0c;并且又…

修复泰坦陨落2缺少msvcr120.dll的5种方法,亲测有效

游戏《泰坦陨落2》缺少msvcr120.dll的问题困扰着许多玩家。这个问题的主要原因可能是系统环境不完整、软件或游戏版本不匹配、DLL文件丢失或损坏以及杀毒软件误判等。msvcr120.dll是Microsoft Visual C 2013 Redistributable的一个组件&#xff0c;它包含了许多运行库文件&…

【百度PARL】强化学习笔记

文章目录 强化学习基本知识一些框架Value-based的方法Q表格举个例子 强化的概念TD更新 Sarsa算法SampleSarsa Agent类 On_policy vs off_policy函数逼近与神经网络DQN算法DQN创新点DQN代码实现model.pyalgorithm.pyagent.py总结&#xff1a;举个例子 实战 视频&#xff1a;世界…

苏宁开放平台API接口全攻略:掌握电商数据,提升业务效率

一、概述 苏宁平台提供了丰富的API接口&#xff0c;用于开发人员与平台进行交互&#xff0c;实现各种功能。本文将介绍苏宁平台API接口的基本概念、使用方法和注意事项&#xff0c;帮助开发人员更好地利用这些接口&#xff0c;提高开发效率和质量。 二、API接口介绍 商品详情…

html之CSS的高级选择器应用

文章目录 一、CSS高级选择器有哪些呢&#xff1f;二、高级选择器的应用1、层次选择器后代选择器子选择器相邻兄弟选择器通用兄弟选择器 2、结构伪类选择器&#xff08;不常用&#xff09;3、属性选择器E[attr]E[attrval]E[attr^val]E[attr$val]E[attr*val] 一、CSS高级选择器有…

excel该如何实现生成条形码/二维码?

如何在Excel中制作条形码/二维码&#xff1f; 1.首先&#xff0c;打开电脑上的Excel。进入后&#xff0c;在上方菜单栏中找到并点击“开发工具”。如果没有找到开发工具&#xff0c;就先点击“文件”&#xff0c;在弹出菜单中再点击“选项”。 2.打开Excel选项窗口后&#xff0…

【Flink-cdc-Mysql-To-Kafka】使用 Flinksql 利用集成的 connector 实现 Mysql 数据写入 Kafka

【Flink-cdc-Mysql-To-Kafka】使用 Flinksql 利用集成的 connector 实现 Mysql 数据写入 Kafka 1&#xff09;环境准备2&#xff09;准备相关 jar 包3&#xff09;实现场景4&#xff09;准备工作4.1.Mysql4.2.Kafka 5&#xff09;Flink-Sql6&#xff09;验证 1&#xff09;环境…

VuePress安装及使用——使用 Markdown 创建你自己的博客网站和电子书

目录 前言一、依赖环境二、vuepress 安装和使用1.初始化2.将 VuePress 安装为本地依赖3. package.json 中添加脚本4. 新建 docs 文件夹5.启动6. 效果 三、进阶使用1.新增配置文件2.安装搜索插件3.config.js 中增加配置4.效果展示5.注意 四、使用主题1.安装2. 目录结构说明&…

Hadoop3.x完全分布式模式下slaveDataNode节点未启动调整

目录 前言 一、问题重现 1、查询Hadoop版本 2、集群启动Hadoop 二、问题分析 三、Hadoop3.x的集群配置 1、停止Hadoop服务 2、配置workers 3、从节点检测 4、WebUI监控 总结 前言 在大数据的世界里&#xff0c;Hadoop绝对是一个值得学习的框架。关于Hadoop的知识&…

git修改远程commit信息

git 修改远程commit信息 如果你已经把本地commit的信息push到远程了&#xff0c;此时需要修改远程中的commit信息 第一步&#xff1a;git log 查看提交的信息,看下提交的commit日志 如下入所示 第二步&#xff1a;然后确定你需要修改的那一次commit&#xff0c;比如&#xf…

简单的绑定发布事件

在绑定事情之前&#xff0c;我们需要对我们的需求进行分析&#xff1b;判断我们是否需要同时存在条件。 发布动态的时候&#xff0c;分为以下三种情况&#xff1a; ① 输入了标题&#xff0c;没有图片&#xff0c;可以发布动态 ②输入了图片&#xff0c;没有标题&#xff0c;…

清空缓存区的方法

fflush(文件指针) fflush()用于刷新相应文件的缓存区。 使用getchar()函数来清空标准输入缓存区 上面的fflush是一个函数,有些编译器不一定支持,这时候我们可以自己实现清空标准输入缓存区的操作。 代码示例: 使用scanf()的高级特性来清空标准输入缓存区 上面代码的意思是: …

GO 的 socks5代理 编写

这里学习一下 socks5 代理的编写 网上有很多 学习一下 go 语言实战入门案例之实现Socks5 - 知乎 滑动验证页面 socks5协议原理学习-腾讯云开发者社区-腾讯云 (tencent.com) 首先我们要了解一下socks5的代理方式 socks5 是基于 认证建立连接转发数据 所形成的代理 我们只…