首页 > 数据库 >【Redis分析】(一) 主从同步

【Redis分析】(一) 主从同步

时间:2024-08-19 16:51:27浏览次数:14  
标签:同步 Slave buffer Redis 复制 Master 全量 rdb 主从

主从复制 - 数据备份, 读写分离, 手动高可用

  1. 负载均衡: 主结点只负责处理写请求, 从节点负责读请求;
  2. 主从复制, 主机挂了, 我们可以手动切换从机, 还可以搭配哨兵实现自动切换, 实现高可用;
  3. 需要注意的是, 在主从模式下, 假设进行同步的过程中主节点宕机了, 那么从节点此时还没有同步到所有的数据, 会发生数据不一致问题;

开启主从复制

通常有以下三种方式:

  • 在 slave 直接执行命令:replicaof <masterip> <masterport>
  • 在 slave 配置文件中加入:replicaof <masterip> <masterport>
  • 使用启动命令:-- replicaof <masterip> <masterport>

主从同步

主节点

从结点

全量同步

当我们配置好主从同步的时候,由于之前没有进行过任何同步,所以首先会进行一次全量数据同步到从库。

主从建立连接

Slave从库会主动和Master主库进行通信,发送psync 命令,该命令会捎带两个参数过去给Master,第一个参数是主库ID(runID),redis 在启动的时候,都会为自己生成一个ID,第二个是Slave复制Maser数据的偏移量offset。

Slave第一次和Master进行通信,由于一开始不知道Master的ID,所以传递了 ?;
由于是第一次复制,offset 传递 -1 表示第一次要进行全量复制。

接着Master接收到了Slave传递过来的命令以及相应的参数,一看是? 和 -1 ,那么就知道这个Slave要进行全量的复制,Master会给Slave 发送一个 fullresync 命令,告诉Slave接下来要开始全量复制,并带上自己的 ID,Slave 接收到这两个参数后会保存起来。

发送rdb文件

Master接着就会执行bgsave, fork 子进程,完成rdb文件的生成,生成完rdb文件后,会发送rdb文件给Slave,Slave会接收rdb文件,在进行接收之前,会先清空Slave自己的数据库数据【这个过程是阻塞的】,清空完成后,开始接收rdb文件,接收完成之后,就加载rdb文件到内存中。

这里还有一个问题,就是在接收rdb文件的时候,Master可能会有新的写操作过来,由于rdb是某一时刻的内存快照,所以之后的数据,是无法进行传输的;

这里redis采用了一个 replication_buffer 来解决,在生成rdb开始,新的写请求数据都会放到这个缓冲区一份,等待rdb传输完成之后,Master接着就会传输这个缓冲区的数据到 Slave,Slave开始接收,接收完成,主从数据保持一致了

**只要一个Slave和Master 建立好连接,对应的 replication_buffer 就会建立,如果断开连接,那么这个缓冲区就会释放。每个 Slave 都有一个replication_buffer **

增量复制

全量复制结束后, 就进入命令传播阶段, 通过一个长连接, 持续不断地将主库收到的写命令同步给从机;

命令传播阶段网络中断了,怎么办?

如果网络发生中断,最早的时候会再走一次全量复制。

后来对这个过程做了优化,采用增量复制的机制;

还记得全量复制的时候,会返回给Slave一个偏移量吗?其实Slave在接收数据之后,会增加这个偏移量来记录当前接收Master多少数据了。

如果网络发生了中断,就会重试和Master重新连接,连接之后,会发送自己的offset给Master,Master会根据Slave发送的偏移量来决定是给Slave做增量复制还是做全量复制。

从开始第一次主从复制开始,那么新的写请求在写入replication buffer的同时,也都会写入到一个叫做 repl_backlog_buffer 的缓冲区内,这是一个环形缓冲区,会记录Master接收的写命令和这条命令的偏移量(从第一次开始主从复制开始),这样Slave再重新连接之后,就可以从这里接着发送命令给Slave了。

所有 Slave 共用同一个 backlog_buffer!

在这里插入图片描述

注意连接没有断开的时候,这两个缓冲区是同时存在,如果连接断开,那么对应Slave的replication buffer缓冲区就会被删除

其实就是环形的每段记录着当前命令和偏移量,随着当前写入的offset不断增大,就会覆盖之前的数据

Master 会记录自己接收的写请求的最新偏移量, 当有 Slave 重连的时候, 与 Slave 的同步进度偏移量进行对比, 如果没有超过环形缓冲区长度, 可以用 backlog_ buffer 中的内容做增量复制, 否则做全量;

命令传播

全量同步完成后, 会进入命令传播阶段 ( 增量同步也是通过命令传播实现的 )

slave 默认会以每秒一次的频率,向 master 发送命令:REPLCONF ACK ,其中 reploff 是 slave 当前的复制偏移量。

发送REPLCONF ACK 命令对于主从服务器的作用:

1)检测 master 和 slave 的网络连接状态。

2)汇报自己的复制偏移量,检测命令丢失,master 会对比复制偏移量,如果发现 slave 的复制偏移量小于自己,会从 repl_backlog_buffer 向 slave 发送未同步的数据。

总结

到现在整个redis 主从复制的过程就讲解完成了,现在来做下总结。

主从同步分为两个类型:

全量同步

全量同步redis 会执行bgsave 来生成rdb文件,然后发送给从库,从库接收之前会先清空从库的数据空,防止之前有数据造成数据的污染,接收完rdb文件之后,就会就加载rdb文件到内存,这时同步其实并没有完成,在进行生成rdb文件的时候,还会有新的写请求过来,此时这些写请求会缓存在一个缓冲区内,这个缓冲区叫做 replication buffer,当从库加载完rdb之后,就会接收这个缓冲区的所有写命令了,到此全量复制就结束了。

由于生产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 单机内存越大越好吗? 不, 越大, Fork 子进程的时间越长, 执行 BGSAVE 和 BGREWRITEAOF 时主进程阻塞时间就越长; 主从同步的时候也会涉及到 BGSAVE;
  2. 为什么用 RDB 而不是 AOF ? 文件小, 恢复快;
  3. 如果想减少因为连接断开导致的全量同步, 可以适当增加 back_log 的大小;
  4. 如果 RDB 文件比较大, 或者网速比较慢, replication_buffer 会满, 主库会和从断开连接,删除buffer,如果从再来请求链接,可能会造成恶性循环。可以适当调大;

目前仍存在的问题

主机掉线后需要手动切换从机

  1. 可以用 Sentinel 解决;

主从过期时间不一致;

  1. 由于网络原理, 从机接收到写命令的时间会比主机晚, 使用 expire pexpire 命令设置过期时间的以后, 是以命令执行时间为起点的相对时间;
  2. 就会导致从机键值对的过期时间延迟; 可以使用 expireat, 设置绝对过期时间, 这里需要注意主从时间要同步;

从机挂掉后主机的runId 和 offset 会丢失; 只能全量同步;

  1. 改进: rdb 会记录 runId 和 offset, 这样从机从 rdb 恢复后, 如果来得及, 还是能增量的, 也不会丢失数据;

主机挂掉后, 剩下的从机, 都要重新和新选出来的主机做全量同步; 会有数据丢失, 且效率低下;

  1. PSYNC2.0 进行了改进, 原本的 runId 和 offset 都变成了两个, 这里简称为 id, id2, offset, offset2;
  2. 对于主机, id 是自己的id, id2 是上一任主机的id; 对于从机, id 是 现任主机id, id2 是上一任主机id;
  3. offset 是当前的偏移量, offset2 是上一任主机没挂的时候, 同步的偏移量;
  4. 发生主从切换后, 就可以通过 id2 知道原本都从属于同一个主机, 可以尝试进行增量同步;

数据量大, 写操作频繁时, 可能导致 replication_buffer 溢出, 无法解决海量数据的问题

  1. 用Redis集群解决;

标签:同步,Slave,buffer,Redis,复制,Master,全量,rdb,主从
From: https://blog.csdn.net/wdx7770/article/details/141329495

相关文章

  • 国产操作系统 离线部署MYSQL、NGINX、redis、JDK1.8
    目录1.1、龙蜥操作系统8.4【AnolisOS8.4GA】1.2、安装关键步骤说明2.1、安装必要的系统组件2.2、配置JDK2.3、安装redis2.4、安装nginx2.5、安装mysql3.1、启用防火墙3.2、开放业务端口3.3、修改SSH端口号为100223.4、配置特定端口指定IP访问4.1、网络设置4.2......
  • K8S部署redis集群,并导入单机版redis数据到集群
    可能格式不怎么好看,就是提供一个思路1、编写一个config文件,给挂载到k8s容器里。这个文件是从网上找的,这个脚本没什么改的,redis的配置文件,可以根据自己的需求做修改添加config.yaml文件apiVersion:v1kind:ConfigMapmetadata:name:redis-cluster-configdata:fix-ip.......
  • RedisTemplate常用方法
    RedisTemplate常用方法一、Redis常用的数据类型:StringHashListSetzSetSortedset二、RedisTemplate常用API1.String类型设置当前的key以及value值;redisTemplate.opsForValue().set(key,value);设置当前的key以及value值并且设置过期时间;redisTemplate.opsForV......
  • MySQL 安装与配置教程:单机、主从复制与集群模式
    目录MySQL简介MySQL安装MySQL基础配置MySQL主从复制配置MySQL集群配置总结1.MySQL简介MySQL是一个广泛使用的关系型数据库管理系统,具有高性能、高可靠性和易用性等特点。它支持多种部署模式,包括单机模式、主从复制模式(用于高可用性和读写分离)以及集群模式(用于分......
  • Redis 安装与配置教程:单机、哨兵模式与集群模式
    目录Redis简介Redis安装Redis单机配置Redis哨兵模式配置Redis集群模式配置总结1.Redis简介Redis是一个开源的键值对存储系统,支持丰富的数据结构,如字符串、哈希、列表、集合等。它被广泛用于缓存、会话存储、实时分析等场景。Redis提供了多种部署模式,包括单机模......
  • SpringBoot中使用Redis
    SpringBoot中使用Redis1.在本地或者云端安装redis服务2.项目中使用2.1引入依赖<!--redisstart--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artif......
  • Redis的十大数据类型的常用命令(上)
    目录1.key的操作命令2.String的常用命令案例一:dy点赞案例二:文章的喜欢数3.List的常用命令案例:公众号订阅的消息4.Hash的常用命令案例:早期购物车设计5.Set的常用命令案例一:抽奖小程序案例二:朋友圈点赞案例三:朋友圈点赞6.Zset的常用集合(sortedset)案例一:根据商品......
  • redis 哨兵模式开启方案
    哨兵模式一、配置sentinel模式二、测试sentinel日志输出的状态信息环境准备准备三台系统为CentOS7的主机master:192.168.152.71slave1:192.168.152.72slave2:192.168.152.73.哨兵模式的介绍:Redis哨兵模式(RedisSentinel)用于提供高可用性和监控功能,主要......
  • .MySQL数据库主从复制
    数据库主从复制Mysql的主从架构模式,是很多企业⼴泛使⽤,并且是⼴为熟知的⼀种架构模式,这是DBA所应该熟练掌握的技能。1.mysql主从复制主要⽤途a.⽤于备份,避免影响业务b.实时灾备,⽤于故障切换c.读写分离,提供查询服务2.mysql主从复制存在的问题a.主库宕机后,数据可能丢失......
  • 云端同步:Scratch编程世界的无限可能
    标题:云端同步:Scratch编程世界的无限可能在当今数字化时代,云技术已成为我们生活的一部分。对于教育和编程爱好者来说,Scratch——一款由麻省理工学院媒体实验室开发的视觉编程语言,提供了一个简单易用的编程环境,让孩子们可以轻松地创建自己的互动故事、游戏和动画。然而,Scratc......