面试官:熟悉Redis,那聊聊Redis主从复制?我画了13张图讲明白了
mhr18 2024-10-25 12:40 31 浏览 0 评论
怎么实现高可用呢? 最重要的一点就是冗余数据啊,redis 是通过主从复制来实现数据的冗余存储,这样在主redis down调用之后,切换到从就可以了,这样就实现了故障转移,保证了高可用了,今天我们主要来讲主从复制,至于主down掉之后,怎么切换到从,我们会在下篇再聊。
怎么做备份
我想在再看redis 主从复制之前,有必要看下下面这三个基础概念。
备份分为冷备和热备,如果再深入一些还有多活。
- 热备:由主库或者说是主数据中心承担业务流量,同时会实时的备份数据到从库或者从的数据中心。如下图。
- 冷备:由主库或者主数据中心承担业务流量,备份数据会定时或者离线手动的执行脚本同步数据到一个从库或者从数据中心,如下图。
- 双活:由两个数据中心承担业务流量,数据中心互为主备,一般主数据中心会承担大部分流量,另一数据中心会承担小部分流量,如下图。
注意:这里直接说明了定义,至于出现故障后,怎么做手动或者自动的故障转移,本篇这不讲解,后面讲redis 哨兵的时候,会细讲。上面的图只是能让我们加深对备份概念的理解。
那么redis属于哪种备份呢? 相信你读完肯定就会明白了。
定义
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。一个主节点可以有多个从节点,但一个从节点只能有一个主节点。
看图:
这里我们不会讲或者讲解redis 主从的安装步骤,这个网上的博文和官网都会有,相信大家都会一步步地配置成功。
我们主要会讲解:
- 主从复制从开始到现在都经历了什么,同步的是什么,数据还是文件?
- 在主从过程中,如果网络中断了,怎么办?
- 同步的过程中,哪些因素会增加主库的压力?
全量同步
当我们配置好主从同步的时候,由于之前没有进行过任何同步,所以首先会进行一次全量数据同步到从库。
主从建立连接
当设置完主从同步配置后,第一步就是主从之间要建立连接,主要之间要相互认识一下,建立信任,才能开始进行同步。
执行slaveof 后,发生了什么,看图说话:
此时Slave从库会主动和Master主库进行通信,发送psync 命令,该命令会捎带两个参数过去给Master,第一个参数是主库ID(runID),redis 在启动的时候,都会为自己生成一个ID,第二个是Slave 需要从Master哪里开始复制数据,也就是Slave复制Maser数据的偏移量offset。
Slave第一次和Master进行通信,由于一开始不知道Master的ID,所以传递了?
由于是第一次复制,传递-1 表示第一次要进行全量复制。
接着Master接收到了Slave传递过来的命令以及相应的参数,一看是? 和 -1 ,那么就知道这个Slave要进行全量的复制,Master会给Slave 发送一个fullresync 命令,告诉Slave接下来要开始全量复制,并带上自己的ID,Slave 接收到这两个参数后会保存起来。 看图说话:
发送rdb文件
Master接着就会执行bgsave 生成子进程,完成rdb文件的生成,生成完rdb文件后,会发送rdb文件给Slave,Slave会接收rdb文件,在进行接收之前,会先清空Slave自己的数据库数据【这个过程是阻塞的】,清空完成后,开始接收rdb文件,接收完成之后,就加载rdb文件到内存中。
这里还有一个问题,就是在接收rdb文件的时候,Master可能会有新的写操作过来,由于rdb是某一时刻的内存快照,所以之后的数据,是无法这里进行传输的,这里redis采用了一个缓冲区来解决,在发送rdb开始,新的写请求数据都会放到这个缓冲区一份,等待rdb传输完成之后,Master接着就会传输这个缓冲区的数据到Slave,Slave开始接收,接收完成,主从数据保持一致了,看图说话:
rdb文件的传输:
缓冲区的传输:
后续命令的传输:
其实这个缓冲区的在redis中叫做replication buffer ,redis 会为每一个连接Master的Slave生成一个这样的缓冲区,因为每个Slave开始同步的时刻,可能是不一样的,那同步的进度肯定就不一样了,所以要分别设置一个replication buffer。
只要一个Slave和Master 建立好连接,对应的Slave缓冲区就会建立,如果断开连接,那么这个缓冲区就会释放。
在开始执行bgsave 生成rdb,后续的所有写请求都会保存到这个缓冲区,也就是replication buffer中,也就是后面所有的写请求都会通过这个缓冲区发送给Slave。
看图说话:
如上图所示,每个Slave对应一个缓冲区,也就是replication buffer。
增量复制
其实上面整个过程完成之后,全量复制就完成了,只要连接不中断,那么会持续进行主从的复制,那么你有没有想过,如果网关抖动了或者中断了,主从连接断开了,redis 会怎么处理呢?重新走全量复制吗?
网络中断了,怎么办?
如果网络发生中断,在redis2.8之前会再走一次全量生成rdb进行复制传输的,这个是很耗费资源和性能的操作。redis2.8以后,对这个过程做了优化,采用增量复制的机制,来减少数据的传出,达到了快速复制的目的,下面主要来讲解增量复制的过程。
还记得全量复制的时候,会返回给Slave一个偏移量吗?其实Slave在接收数据之后,会增加这个偏移量来记录当前接收Master多少数据了。如果Master和Slave的偏移量是1000 ,传递30字节给Slave,那么此时Master和Slave的偏移量应该是1030.
如果网络发生了中断,就会重试和Master重新连接,连接之后,会发送自己的offset给Master,Master会根据Slave发送的偏移量来决定是给Slave做增量复制还是做全量复制。
知道了大概的过程,那么在网络中断之后,恢复连接之前,中断这段时间内的数据,肯定是同步不过去了,那么数据存储在哪里了呢?
只要开始进行主从复制了,那么新的写请求在写入replication buffer的同时,也都会写入到一个叫做repl_backlog_buffer 的缓冲区内,这是一个环形缓冲区,会记录Master接收新的写请求数据的偏移量和新写命令,这样Slave再重新连接之后,就可以从这里接着发送命令给Slave了。
看下replication buffer 和 repl_backlog_buffer(环形缓冲区)的位置图,加深印象:
注意连接没有断开的时候,这两个缓冲区是同时存在,如果连接断开,那么对应Slave的replication buffer缓冲区就会被删除。
其实就是环形的每段记录着当前数据和偏移量,随着当前写入的offset不断增大,因为这是一个环形的缓冲区,就会发生覆盖之前的数据。
环形缓冲区,repl_backlog_buffer 记录是当前Master 接收到新写请求的累计的offset值(master_repl_offset),表示是Master的进度,当发生网络中断时候,所有的Slave都会和Master的offset进行比较,所以它是所有Slave公用的。
增量复制的过程
- Slave尝试发送psync 带上Master的runID和 自己的 offset (slave_repl_offset) 。
- Master接收到psync 之后,进行判断是进行增量复制还是进行全量复制。
可以进行增量复制,看图:
如果接收到的runID 和Master runID 相同,同时repl_backlog_buffer缓冲区的offset会与Slave 发过来的offset进行比较,如果主从节点的差距没有超过环形缓冲区的长度,或者没有发生套圈,也就是不会发生覆盖之前的数据,那么Master会回复Continue给Slave,告诉Slave可以进行增量复制了。
如果发现runID和现在Master不一致,或者 主从的offset差距超过的repl_backlog_buffer缓冲区的长度,那么就会走全量复制了,这里就不多说了。
- Master发送offset之后的命令给Slave,看图说话。
由于Slave发送过来的offset是998 ,现在Master的offset是1000,所以Master会把998-1000之间的命令继续传递给Slave,这样就做到增量传输了。
总结
到现在整个redis 主从复制的过程就讲解完成了,现在来做下总结。
主从同步分为两个类型:
- 全量同步
全量同步redis 会执行bgsave 来生成rdb文件,然后发送给从库,从库接收之前会先清空从库的数据空,防止之前有数据造成数据的污染,接收完rdb文件之后,就会就加载rdb文件到内存,这是同步其实并没有完成,在进行生成rdb文件的时候,还会有新的写请求过来,此时这些写请求会缓存在一个缓冲区内,这个缓冲区叫做replication buffer,当从库加载完rdb之后,就会接收这个缓冲区的所有写命令了,到此全量复制就结束了。
由于生产rdb是会阻塞主线程,这个过程很耗费资源,如果采用一个主多个从的方式,那么势必会增加主库的压力,可以选择一个从,再从库上再分裂出一个从或者多个从,来减少主库的压力。
如果想要快速的生成rdb文件 ,应该减少redis设置内存的大小,这样生成rdb文件就会很快,减少阻塞的时间。
- 增量同步
如果主从断开连接了,redis 主库会判断是进行全量复制还是增量复制,主库会根据从库发送过来的runID和从库复制进行offset,如果runID和主库的ID相同,并且主从的offset差距没有超过repl_backlog_buffer缓冲区的长度,就会复制offset之间的repl_backlog_buffer的命令给Slave。
两个缓冲区:
- replication buffer
replication buffer 是在从库和主库建立连接成功后创建的,在主从断开后,这个缓冲区也会被主库进行删除,主从库之间复制命令的传输,都会经过这个buffer,而且这个buffer是每个从库独有的。
- repl_backlog_buffer
开始进行命令传输之前,就会建立好这个buffer,这个buffer记录当前Master接收到的新的写操作命令offset和命令本身,是所有Slave公用的buffer,Slave 发送psync之后,会和Master的offset进行比较,来决定是否进行增量复制。
注意点:
1、redis 实例的内存大小不要设置太大,这样能够缩短生成rdb文件的时间,同时也能缩短全量复制的时间,减少带宽的占用。
2、如果从库和主库断开连接超时很长,那么repl_backlog_buffer缓冲区内的数据很可能就会被覆盖了,进而会退化为全量复制了,此时可以设置repl_backlog_size 这个参数设置大些。
3、replication buffer,这个缓冲区也要留意,如果从库接收得很慢,这个缓冲区会满,redis可能就会OOM了,如果这个buffer满了redis 会怎么处理,redis提供了client-output-buffer-limit参数限制这个buffer的大小,如果满了,主库会和从断开连接,删除buffer,如果从再来请求链接,可能会造成恶性循环。
今天的分享就到这里了,码字画图不易,期待你的点赞、关注、转发,谢谢。
来源于:https://juejin.cn/post/6981744631000072205
相关推荐
- 订单超时自动取消业务的 N 种实现方案,从原理到落地全解析
-
在分布式系统架构中,订单超时自动取消机制是保障业务一致性的关键组件。某电商平台曾因超时处理机制缺陷导致日均3000+订单库存锁定异常,直接损失超50万元/天。本文将从技术原理、实现细节、...
- 使用Spring Boot 3开发时,如何选择合适的分布式技术?
-
作为互联网大厂的后端开发人员,当你满怀期待地用上SpringBoot3,准备在项目中大显身手时,却发现一个棘手的问题摆在面前:面对众多分布式技术,究竟该如何选择,才能让SpringBoot...
- 数据库内存爆满怎么办?99%的程序员都踩过这个坑!
-
你的数据库是不是又双叒叕内存爆满了?!服务器监控一片红色警告,老板在群里@所有人,运维同事的电话打爆了手机...这种场景是不是特别熟悉?别慌!作为一个在数据库优化这条路上摸爬滚打了10年的老司机,今天...
- springboot利用Redisson 实现缓存与数据库双写不一致问题
-
使用了Redisson来操作Redis分布式锁,主要功能是从缓存和数据库中获取商品信息,以下是针对并发时更新缓存和数据库带来不一致问题的解决方案1.基于读写锁和删除缓存策略在并发更新场景下,...
- 外贸独立站数据库炸了?对象缓存让你起死回生
-
上周黑五,一个客户眼睁睁看着服务器CPU飙到100%——每次页面加载要查87次数据库。这让我想起2024年Pantheon的测试:Redis缓存能把WooCommerce查询速度提升20倍。跨境电商最...
- 手把手教你在 Spring Boot3 里纯编码实现自定义分布式锁
-
为什么要自己实现分布式锁?你是不是早就受够了引入各种第三方依赖时的繁琐?尤其是分布式锁这块,每次集成Redisson或者Zookeeper,都得额外维护一堆配置,有时候还会因为版本兼容问题头疼半...
- 如何设计一个支持百万级实时数据推送的WebSocket集群架构?
-
面试解答:要设计一个支持百万级实时数据推送的WebSocket集群架构,需从**连接管理、负载均衡、水平扩展、容灾恢复**四个维度切入:连接层设计-**长连接优化**:采用Netty或Und...
- Redis数据结构总结——面试最常问到的知识点
-
Redis作为主流的nosql存储,面试时经常会问到。其主要场景是用作缓存,分布式锁,分布式session,消息队列,发布订阅等等。其存储结构主要有String,List,Set,Hash,Sort...
- skynet服务的缺陷 lua死循环
-
服务端高级架构—云风的skynet这边有一个关于云风skynet的视频推荐给大家观看点击就可以观看了!skynet是一套多人在线游戏的轻量级服务端框架,使用C+Lua开发。skynet的显著优点是,...
- 七年Java开发的一路辛酸史:分享面试京东、阿里、美团后的心得
-
前言我觉得有一个能够找一份大厂的offer的想法,这是很正常的,这并不是我们的饭后谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司...
- mysql mogodb es redis数据库之间的区别
-
1.MySQL应用场景概念:关系型数据库,基于关系模型,使用表和行存储数据。优点:支持ACID事务,数据具有很高的一致性和完整性。缺点:垂直扩展能力有限,需要分库分表等方式扩展。对于复杂的查询和大量的...
- redis,memcached,nginx网络组件
-
1.理解阻塞io,非阻塞io,同步io,异步io的区别2.理解BIO和AIO的区别io多路复用只负责io检测,不负责io操作阻塞io中的write,能写多少是多少,只要写成功就返回,譬如准备写500字...
- SpringBoot+Vue+Redis实现验证码功能
-
一个小时只允许发三次验证码。一次验证码有效期二分钟。SpringBoot整合Redis...
- AWS MemoryDB 可观测最佳实践
-
AWSMemoryDB介绍AmazonMemoryDB是一种完全托管的、内存中数据存储服务,专为需要极低延迟和高吞吐量的应用程序而设计。它与Redis和Memcached相似,但具有更...
- 从0构建大型AI推荐系统:实时化引擎从工具到生态的演进
-
在AI浪潮席卷各行各业的今天,推荐系统正从幕后走向前台,成为用户体验的核心驱动力。本文将带你深入探索一个大型AI推荐系统从零起步的全过程,揭示实时化引擎如何从单一工具演进为复杂生态的关键路径。无论你是...
你 发表评论:
欢迎- 一周热门
-
-
Redis客户端 Jedis 与 Lettuce
-
高并发架构系列:Redis并发竞争key的解决方案详解
-
redis如何防止并发(redis如何防止高并发)
-
Java SE Development Kit 8u441下载地址【windows版本】
-
开源推荐:如何实现的一个高性能 Redis 服务器
-
redis安装与调优部署文档(WinServer)
-
Redis 入门 - 安装最全讲解(Windows、Linux、Docker)
-
一文带你了解 Redis 的发布与订阅的底层原理
-
Redis如何应对并发访问(redis控制并发量)
-
Oracle如何创建用户,表空间(oracle19c创建表空间用户)
-
- 最近发表
- 标签列表
-
- oracle位图索引 (74)
- oracle批量插入数据 (65)
- oracle事务隔离级别 (59)
- oracle主从同步 (56)
- oracle 乐观锁 (53)
- redis 命令 (83)
- php redis (97)
- redis 存储 (67)
- redis 锁 (74)
- 启动 redis (73)
- redis 时间 (60)
- redis 删除 (69)
- redis内存 (64)
- redis并发 (53)
- redis 主从 (71)
- redis同步 (53)
- redis结构 (53)
- redis 订阅 (54)
- redis 登录 (62)
- redis 面试 (58)
- redis问题 (54)
- 阿里 redis (67)
- redis的缓存 (57)
- lua redis (59)
- redis 连接池 (64)