Redis主从复制的搭建及原理分析

news2024/11/26 1:40:21

目录

一、Redis主从复制

1.1 搭建主从复制架构

1.1.1 主从复制架构简介

1.1.2 搭建主从复制架构

1.2 主从复制工作流程

1.2.1 建立连接阶段

1.2.2 数据同步阶段

1.2.2.1 工作流程

1.2.2.2 增量同步原理

1.2.3 命令传播阶段

1.2.3.1 偏移量(offset)

1.2.3.2 运行id(runid)

1.2.3.3 复制积压缓冲区

1.2.3.4 心跳机制


一、Redis主从复制

1.1 搭建主从复制架构

1.1.1 主从复制架构简介

在实际开发中,redis通常会搭建集群,来提高redis的整体的性能。但在客户端访问时有可能多次访问到不同的redis,因此造成多台redis数据不一致问题,为了解决这种多台redis中数据不同步问题,我们提出了主、从的概念;

image

Master负责写的操作,Slave负责读的操作,Master与Slave直接保证数据的同步。

注:一个Master可以对应有多个Slave,一个Slave只能有一个Master

1.1.2 搭建主从复制架构

准备好两个Redis配置文件(一主一从):

6379(Master):

port 6379
dir "/root/redis-4.0.11/data"
daemonize no
dbfilename dump-6379.rdb
appendonly yes
appendfsync everysec
appendfilename "appendonly-6379.aof"

6380(Slave):

port 6380
dir "/root/redis-4.0.11/data"
dbfilename dump-6380.rdb
daemonize no
appendonly yes
appendfsync everysec
appendfilename "appendonly-6380.aof"

启动两台Redis服务器

redis-4.0.11/src/redis-server redis-4.0.11/conf/redis-6379.conf
redis-4.0.11/src/redis-server redis-4.0.11/conf/redis-6380.conf

使用客户端连接:

redis-4.0.11/src/redis-cli -p 6379
redis-4.0.11/src/redis-cli -p 6380
  • 主从复制命令:

Slave连接Master,在Slave的客户端输入如下命令:

Slaveof <Masterip> <Masterport>

示例:

127.0.0.1:6379> Slaveof 192.168.170.142 6379
OK
127.0.0.1:6379>

如果Master设置了密码,那么在Slave服务器启动的时候就要指定Master的密码:

redis-server ../config/redis-6380.conf --Masterauth admin

分别查看Slave与Master启动日志:

  • Master日志:
23305:M 11 Apr 10:24:20.225 * Slave 127.0.0.1:6479 asks for synchronization
23305:M 11 Apr 10:24:20.225 * Partial resynchronization not accepted: Replication ID mismatch (Slave asked for '18b61ced5990337dd8377e8bf81fcd2b20e7d399', my replication IDs are 'fa4d40f8562c10acbbd7a9955a88f7cd6dc33182' and '0000000000000000000000000000000000000000')
23305:M 11 Apr 10:24:20.225 * Starting BGSAVE for SYNC with target: disk
23305:M 11 Apr 10:24:20.225 * Background saving started by pid 23339
23339:C 11 Apr 10:24:20.227 * DB saved on disk
23339:C 11 Apr 10:24:20.227 * RDB: 2 MB of memory used by copy-on-write
23305:M 11 Apr 10:24:20.315 * Background saving terminated with success
23305:M 11 Apr 10:24:20.315 * Synchronization with Slave 127.0.0.1:6479 succeeded
  • Slave日志:
23279:S 11 Apr 10:24:20.224 * Connecting to Master 127.0.0.1:6379
23279:S 11 Apr 10:24:20.224 * Master <-> Slave sync started
23279:S 11 Apr 10:24:20.224 * Non blocking connect for SYNC fired the event.
23279:S 11 Apr 10:24:20.224 * Master replied to PING, replication can continue...
23279:S 11 Apr 10:24:20.224 * Trying a partial resynchronization (request 18b61ced5990337dd8377e8bf81fcd2b20e7d399:1).
23279:S 11 Apr 10:24:20.226 * Full resync from Master: f1d39130cfadf4b3e0eb192e4143ae6bcb01677b:0
23279:S 11 Apr 10:24:20.226 * Discarding previously cached Master state.
23279:S 11 Apr 10:24:20.315 * Master <-> Slave sync: receiving 176 bytes from Master
23279:S 11 Apr 10:24:20.315 * Master <-> Slave sync: Flushing old data
23279:S 11 Apr 10:24:20.315 * Master <-> Slave sync: Loading DB in memory
23279:S 11 Apr 10:24:20.316 * Master <-> Slave sync: Finished with success
23279:S 11 Apr 10:24:20.316 * Background append only file rewriting started by pid 23340
23279:S 11 Apr 10:24:20.356 * AOF rewrite child asks to stop sending diffs.
23340:C 11 Apr 10:24:20.356 * Parent agreed to stop sending diffs. Finalizing AOF...
23340:C 11 Apr 10:24:20.356 * Concatenating 0.00 MB of AOF diff received from parent.
23340:C 11 Apr 10:24:20.356 * SYNC append only file rewrite performed
23340:C 11 Apr 10:24:20.357 * AOF rewrite: 6 MB of memory used by copy-on-write
23279:S 11 Apr 10:24:20.426 * Background AOF rewrite terminated with success
23279:S 11 Apr 10:24:20.426 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
23279:S 11 Apr 10:24:20.426 * Background AOF rewrite finished successfully
  • 当Master宕机后Slave会一直尝试连接Master,日志信息如下:
29511:S 11 Apr 10:37:37.567 # Error condition on socket for SYNC: Connection refused
29511:S 11 Apr 10:37:38.577 * Connecting to Master 127.0.0.1:6379
29511:S 11 Apr 10:37:38.577 * Master <-> Slave sync started
29511:S 11 Apr 10:37:38.577 # Error condition on socket for SYNC: Connection refused
29511:S 11 Apr 10:37:39.587 * Connecting to Master 127.0.0.1:6379
29511:S 11 Apr 10:37:39.587 * Master <-> Slave sync started
29511:S 11 Apr 10:37:39.587 # Error condition on socket for SYNC: Connection refused
29511:S 11 Apr 10:37:40.597 * Connecting to Master 127.0.0.1:6379
29511:S 11 Apr 10:37:40.597 * Master <-> Slave sync started
29511:S 11 Apr 10:37:40.597 # Error condition on socket for SYNC: Connection refused
29511:S 11 Apr 10:37:41.606 * Connecting to Master 127.0.0.1:6379

Slave端口与Master的连接(断开与Master连接后,Slave不再接收Master的同步数据):

Slaveof no one

1.2 主从复制工作流程

image

redis的主从复制分为三个阶段:

1)Slave连接Master(建立连接阶段)

2)Master同步数据到Slave(数据同步阶段)

3)期间Master接到来自客户端"写"的命令之后需要将数据同步到Slave(命令传播阶段)

1.2.1 建立连接阶段

在主从配置的建立连接阶段Master与Slave之间会做如下操作:

1)Slave发送Slaveof Masterhost Masterport命令连接Master

2)Master接到来自Slave的连接,并开始响应对方。

3)Slave得到响应之后将Masterhost与Masterport及一些其他的Master信息保存到Slave端。

4)Slave确保连接无误后开始创建socket通道,用于后续的数据复制工作。

5)Slave与Master之间周期性的发送ping心跳,检查Slave与Master之间是否通信正常。

6)Master接收到Slave的ping心跳后会给对应的Slave响应pong。ping/pong机制

7)Slave发送本机设置的Master密码Masterauth来到Master进行验证(Master有设置密码的情况下)。

8)Master进行身份识别,如果认证错误,尝试重新连接。Slave服务器端报如下错误:

Master aborted replication with an error: NOAUTH Authentication required.

9)Master身份识别成功后,Slave会将自己的ip、端口等信息发送到Master,Master将保存此Slave的ip、端口以及一些其他状态信息,记录在info Replication。

1.2.2 数据同步阶段

1.2.2.1 工作流程

image

在Master与Slave建立连接成功后,开始数据同步。

1)Slave发送psync2(psync1、sync)指令给Master,需要同步数据

2)Master接到指令后开始执行bgsave指令,并创建复制积压缓冲区,在此期间,Master接收到任何来自客户端的"写"操作都会记录在复制积压缓冲区一份

3)Master将rdb文件通过前面创建的socket通道发送给Slave

4)Slave接收到rdb文件后,清空当前机器的所有数据,开始同步rdb中的数据

5)告知Master文件以及恢复完毕

6)Master将复制积压缓冲区中的指令发送给Slave

7)Slave将接收到的指令执行bgrewriteaof重写,之后进行数据恢复

步骤1-4属于全量同步

步骤5-7属于增量同步

1.2.2.2 增量同步原理

从上图可以看出,在Master执行bgsave期间接收到的所有命令都会存放在复制积压缓冲区一份,而复制积压缓冲区的大小是有限度的,默认是1MB,如果缓冲区已经满了,则会把最前面的数据挤出去(删除),后期进行增量同步时发现数据不一致,则会进行全量同步,从而造成同步死循环,因此复制积压缓冲区不易设置为太小。

  • 查看复制积压缓冲区:
127.0.0.1:6379> config get repl-backlog-size
1) "repl-backlog-size"
2) "1048576"
127.0.0.1:6379>
  • 调整复制积压缓冲区大小:
repl-backlog-size 2096576

1.2.3 命令传播阶段

Master与Slave保持连接后,此后Master接到来自客户端"写"的命令之后,需要将数据同步各个Slave端,此阶段叫命令传播阶段。

1.2.3.1 偏移量(offset)

在数据同步中,Master与Slave之间分别维护着一个offset偏移量

  • Master的offset记录的是:Master在发送数据到Slave时Master已经发送的数据位置
  • Slave的offset记录的是:Slave实际接收到的数据位置

这样利于在网络抖动情况下,主从节点之间还可以继续接着上一次同步的位置进行同步,而不必要进行全量同步。

Tips:Master与Slave的offset不一致一般情况下是Master发送了指令但由于网络抖动等原因Slave没有接收到;

image

假设在命令传播时,Master已经传输到了"4"这个字节(offset为7),但Slave实际直接收到"t"这个字节(offset为5),由于Slave与Master一直保持着ping/pong机制,因此每秒Slave都会将自己所保存的offset发送到Master与之对比,那么下次Master则会从"t"这个字节开始发送数据到Slave;

1.2.3.2 运行id(runid)

在上一小结说了Master与Slave之间都维护着一个offset偏移量,让我们可以根据offset的偏移量进行增量同步,避免网络抖动情况下进行全量同步。

但是如果在同步的过程中切换了Master节点则会出现问题(哨兵切换等问题),因为新的Master节点并没有维护着offset偏移量,并且Slave中的数据应该与新Master节点数据保持一致。那么redis是如何做到这一点的呢?

image

其实在Master与Slave服务器启动时都保存有一个由40位随机的16进制字符串组成的运行id(runid),用于标识一台唯一的redis,每次启动都不一样。在info的server组下可以查看到:

info server

image

在Slave首次连接Master时,Master会将自己的runid发送给Slave,Slave会将此runid保存下来(我们查询不到),当出现网络抖动时,Slave会将此runid发送给Master,Master根据此runid判断进行全量同步还是增量同步。

  • runid与现在Master的runid一致:说明网络是同一个Master节点,增量同步条件满足(具体是否执行还需要看复制积压缓冲区是否有溢出)。
  • runid与现在Master的runid不一致:说明是新的Master节点,进行全量同步。

1.2.3.3 复制积压缓冲区

复制积压缓冲区(replication backlog buffer):复制积压缓冲区是Master节点创建的一个先进先出的队列,默认大小为1MB,用于备份主节点的传播命令,所有的Slave共享一个复制积压缓冲区。

Slave将offset发送给Master之后,Master会根据当前的offset值来决定是全量同步还是增量同步。

  • 如果offset偏移量之后的数据仍在缓冲区中(意味着在执行bgsave时,缓冲区还未满,未溢出),则执行增量同步(runid要是同一个)。
  • 如果offset偏移量之后的数据不在缓冲区中(意味着在执行bgsave时间过长,缓冲区的数据已经被挤出,数据溢出),此时执行全量同步

完整同步过程如下:

image

总结:在网络抖动情况下,增量同步的条件:

1)offset之后的数据仍在复制积压缓冲区中(在Master执行bgsave期间,复制积压缓冲区未发现溢出)

2)runid要是同一个

1.2.3.4 心跳机制

在命令传播阶段,Master与Slave之间通过心跳机制来保证Master与Slave双方正常连接在线。

  • Master定时向Slave发送ping,查看对方是否在线,通过repl-ping-Slave-period参数维护,默认10s
127.0.0.1:6379> config get repl-ping-Slave-period
1) "repl-ping-Slave-period"
2) "10"
127.0.0.1:6379>
  • Slave定时向Master发送 replcconf ack<偏移量>命令,频率为每秒发送一次。

作用1):用于检测Slave与Master的连接状态,可以在Master端使用info命令查看replication组的lag值,代表上一次接收到此Slave的replcconf ack命令间隔。

image

作用2):Slave发送当前的offset来到Master与之对比,如果出现网络丢包情况下那么Slave与Master之间的offset不一致,通常是Master发了多个字节,而Slave由于网络原因没有接到那么多,可通过offset判断出上一条指令是否丢失;如果丢失,主服务器可从复制积压缓冲区找出丢失的指令,重新命令传播。

2.8版本以前无法检测命令是否丢失,因此存在主从数据不一致的风险。

作用3):Slave每次发送replcconf ack命令给Master,Master用于确认有多少个Slave与之连接,并且还可以确定多个Slave与Master上一次发送心跳的时间(lag),如果Slave长时间未发送心跳来到Master,可以先将Master暂停写的操作。

  • min-Slaves-to-write:当前Master的Slave数量小于此值则暂停写操作
min-Slaves-to-write 3
  • min-Slaves-max-lag:当前Master的Slave的lag都等于此值则暂停写的操作
min-Slaves-max-lag 5

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

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

相关文章

固定资产太多怎么管理好

固定资产太多时&#xff0c;可以采取以下措施进行管理&#xff1a;  分类管理&#xff1a;将固定资产按照种类、用途等进行分类&#xff0c;便于管理和查询。  建立台账&#xff1a;建立固定资产台账&#xff0c;记录每项资产的名称、编号、购置日期、购买价格、使用部门、…

keil在点击debug无法运行(全速运行)

1、今天发现我之前可以debug的程序&#xff0c;在板子上无法debug了&#xff0c;打断点完全没用 2、换了电脑&#xff0c;带板子过去也这样&#xff0c;之前可以运行的代码都debug不了 3、按照网上的方法&#xff0c;都不行&#xff0c;全速运行&#xff0c;单步执行都是灰色…

nodejs pkg打包生成exe,设置自定义图标和产品信息

一、使用node开发应用程序,通常采用express框架进行功能扩展,当系统开发完成后,直接的方式就是采用gulp压缩后,在服务端运行node app.js命令执行,to C的系统这样开发部署没有问题。 二、而在to B,to G的项目中,采用源码的方式运行,一方面部署不太友好,需要拷贝的文件很…

Python随机森林、线性回归对COVID-19疫情、汇率数据预测死亡率、病例数、失业率影响可视化...

全文链接&#xff1a;https://tecdat.cn/?p33536 自2019年12月以来&#xff0c;传染性冠状病毒疾病2019&#xff08;COVID-19&#xff09;迅速席卷全球&#xff0c;并在短短几个月内达到了大流行状态&#xff08;点击文末“阅读原文”获取完整代码数据&#xff09;。 相关视频…

双基证券:中国房地产开发投资可能已经见底 未来或将反弹

双基证券表示&#xff0c;差别化住宅信贷方针优化调整&#xff0c;估计将和前期认房不认贷的方针一起构成合力&#xff0c;助力居民减轻置业担负&#xff0c;有利于加快开释合理住宅需求。这也显示了方针积极有为&#xff0c;决断致力于防危险和稳增长。存量房贷利率重定价&…

sort排序字母+数字混合排序

使用ocaleCompare进行排序后&#xff0c;发现排序后的顺序是这样的&#xff08;为什么会这样排序&#xff0c;可以自己去研究一下&#xff09;&#xff0c;但这并不是自己想要的。期望顺序&#xff1a;A-11&#xff0c;A-22&#xff0c;A-111&#xff0c;A-222 在网上查找了半…

企业架构LNMP学习笔记2

企业架构分布式集群最终解决方案 集群&#xff1a;多台服务器在一起做同样的事情。 分布式&#xff1a;多台服务器在一起做不同的事情。 最终架构&#xff1a;实现负载均衡LB&#xff0c;高可用HA&#xff0c;数据库主从复制M-S&#xff0c;读写分离R-W&#xff0c;缓存中间件…

火热的低代码

低代码风头正紧&#xff0c;不管你是做后端开发、还是前端设计、销售、售前&#xff0c;如果你没接触过低代码都不好意思说自己在软件领域工作&#xff0c;这篇文章从我的角度聊聊低代码是什么、以怎么样的方式开发、及低代码的未来发展趋势。 一、低代码由来 低代码并不是一项…

红石外汇|每日汇评:如非农数据疲软的情况下,黄金是否会突破1955美元的100日移动平均线?

1、金价已进入 1,950 美元下方盘整阶段&#xff0c;关注美国非农就业数据&#xff1b; 2、在关键就业数据和美国劳工节长周末之前&#xff0c;美元出现空头回补&#xff1b; 3、9月份开始&#xff0c;金价关注 100 日移动平均线 1955 美元&#xff1b; 金价交易接近一个月高点…

记一次反弹shell的操作【非常简单】

#什么是反弹shell 通常我们对一个开启了80端口的服务器进行访问时&#xff0c;就会建立起与服务器Web服务链接&#xff0c;从而获取到服务器相应的Web服务。而反弹shell是我们开启一个端口进行监听&#xff0c;转而让服务器主动反弹一个shell来连接我们的主机&#xff0c;我们再…

Python2022年06月Python二级 -- 编程题解析

题目一: 学过编程的小程同学想帮助医生对核酸检测人群进行分流和统计&#xff0c;根据健康码的颜色分配不同的核酸检测区域: 红码:A区 橙码:B区 绿码:C区 等待核酸检测人数众多&#xff0c;但是具体检测人数未知&#xff0c;请你帮小程编写一个程序来协助医生对核酸人群进行人群…

如何创建HttpServletRequest对象

我们常用的就是在Controller层的接口入参时定义&#xff0c;这样我们就能直接用了&#xff0c;如下图&#xff1a; 但是某些情况&#xff0c;我们需要传递这个request 到各种工具类中&#xff0c;传递这个request 相对要麻烦一些&#xff0c; 我们可以不用传递&#xff0c;在…

工具类APP如何解决黏性差、停留短、打开率低等痛点?

工具产品除了需要把自己的功能做到极致之外&#xff0c;其实需要借助一些情感手段、增设一些游戏机制、输出高质量内容、搭建社区组建用户关系链等方式&#xff0c;来提高产品的用户黏性&#xff0c;衍生产品的价值链。 工具类产品由于进入门槛低&#xff0c;竞争尤为激烈&…

【UIPickerView案例03-点餐系统之随机点餐 Objective-C语言】

一、先来看看我们这个示例程序里面,随机点餐是怎么做的 1.点击:“随机点餐”按钮 大家能想到,它是怎么实现的吗 1)首先,点击”随机点餐“按钮,的时候,你要让这个pickerView,进行随机选中,那么,得监听它的点击 2)然后呢,让pickeView选中数据, 3)然后呢,把那个…

IDEA无效发行版本17

IDEA无效发行版本17 idea开发工具依赖的 jdk版本 和 项目依赖的jdk版本一定要保持 一致&#xff0c;不然会报错。 setting-->build-->compiler-》javaCompiler project->structure 这个也要保持一样。 在porm.xml文件中&#xff0c;你配置jdk版本是1.8&#xff0c;这…

【云原生】Kubernetes容器编排工具

目录 1. K8S介绍 1.1 k8s的由来 下载地址 1.2 docker编排与k8s编排相比 1.3 传统后端部署与k8s 的对比 传统部署 k8s部署 ​2. k8s的集群架构与组件 &#xff08;1&#xff09; Kube-apiserver &#xff08;2&#xff09;Kube-controller-manager &#xff08;3&a…

怎样将几个pdf合并?

在日常工作中&#xff0c;我们经常需要处理大量的PDF文件。有时候&#xff0c;我们需要将多个PDF文件合并成一个文件&#xff0c;以便于快速传输或方便查阅。虽然PDF文件本身不能进行编辑&#xff0c;但是借助专业的PDF编辑软件&#xff0c;我们可以轻松地实现将多个PDF文件合并…

SIEM中的安全事件管理

组织经常面临意外和未知的安全威胁&#xff0c;无论威胁的级别、类型或大小如何&#xff0c;它们的存在都会对企业的整体运作产生冲击&#xff0c;事件管理是尽快识别和响应这些中断以最大程度地减少其对日常业务运营的影响的过程。 什么是安全事件 安全事件是指示对组织网络…

H.264视频编码推荐的分辨率和码率配置表

Video Encoding Settings for H.264 Excellence 针对H.264编码格式&#xff0c;根据不同分辨率&#xff0c;推荐其对应的码率配置关系如下图所示&#xff1a; 如下为上限&#xff0c;超过这个上限再增加码率基本无太大意义&#xff01;根据业务场景、帧率&#xff0c;建议码率…

Python中 re.compile 函数的使用

前言 嗨喽&#xff0c;大家好呀~这里是爱看美女的茜茜呐 以下介绍在python的re模块中怎样应用正则表达式 &#x1f447; &#x1f447; &#x1f447; 更多精彩机密、教程&#xff0c;尽在下方&#xff0c;赶紧点击了解吧~ python源码、视频教程、插件安装教程、资料我都准备…