首页 > 数据库 >Redis设计与实现-15.复制

Redis设计与实现-15.复制

时间:2023-12-26 18:14:10浏览次数:40  
标签:同步 15 Redis 命令 Follower 复制 Offset 服务器

redis可以通过SLAVEOF命令去复制(同步)另一台服务器,例如:
当前有两台redis服务器其信息为:

hostname ip port
redis_1 127.0.0.1 6379
redis_2 127.0.0.1 12345

如果redis_2想要同步redis_1的内容,可以在redis_2上执行SLAVEOF 127.0.0.1 6379,进而达到这个效果。

Redis SLAVEOF命令的功能主要通过如下几个命令:

  1. 2.8版本之前主要通过SYNC命令和BGSAVE命令
  2. 2.8版本及之后主要通过PSYNC命令和BGSAVE命令

接下来我们主要介绍SLAVEOF功能的具体实现。

2.8版本之前的SLAVEOF

Redis的复制功能主要通过两个操作完成,分别为同步命令传播:

  1. 同步操作用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态。(保证初始状态一致)
  2. 命令传播操作则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态(最终状态一致)

因此,在SLAVEOF被执行后,从服务器首先对主服务器进行同步,同步完毕后,后续主服务器上执行的命令,会通过命令传播传输到从服务器上。

同步主要通过SYNC命令完成,SYNC命令的执行步骤如下:

  1. 从服务器向主服务器发送SYNC命令
  2. 主服务器收到命令后,开始执行BGSAVE命令,后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令
  3. 当主服务器BGSAVE命令执行完毕后,主服务器会将生成的RDB文件发送给从服务器,从服务器接收并载入这个文件,将数据库更新为主服务器生成RDB文件时的状态。
  4. 主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。

当同步过程完成之后,进入命令传输阶段,一旦主服务器接收到写命令,并且执行完成之后,主服务器会将该命令同步至从服务器,让从服务器也执行该命令。(感觉直接复用AOF日志的逻辑就好)

但是该方法有两个缺陷:

  1. BGSAVE命令是十分低效的,他会将本地所有的数据生成为一个RDB文件,其次由于RDB文件比较大,网络耗时也会比较影响效率
  2. 命令传输阶段如果从服务器停止,主服务器无法将命令同步到从服务器,也需要兼容。

2.8以及以后的SLAVEOF

2.8版本以后,Redis进行了如下改动:

  1. 将负责存储写命令的缓冲区引入到了命令传输阶段,缓冲区大小为1MB
  2. 为各个Redis服务器,无论主从,添加了唯一的Run ID,用于唯一标识Redis服务器
  3. 各个Redis会记录本地同步的offset,master记录已经同步过的数据的offset,Follower记录已经成功同步master的offset。

引入了这三点改动,就解决了上面的问题:

由于2.8以前所有的同步操作都需要使用BGSAVE,导致同步的效率十分低下,为了缓解这个问题,在命令传输阶段,master引入了一个大小为1MB的缓冲区,用于记录已经执行的写命令,并且Master和Follower都记录了自己的唯一ID,并且会记录同步的offset。

  1. 唯一ID保证了Follower和Master中Offset等信息的有效性,如果无法确认各个Redis服务器的身份,存储的offset就没有意义。
  2. Offset负责记录同步进程。
  • 如果Follower断线,又重启后,其最后的Offset+1对应的数据还在缓冲区中,则Master只将缓冲区中的写命令传输给Follower,避免了BGSAVE。
  • 如果Follower断线,又重启后,其最后的Offset+1对应的数据不在缓冲区中,则只能通过BGSAVE的方式+命令传输的方式进行同步
  1. 缓冲区的大小为1MB保证了同步的效率。

如果出现了数据丢失现象:
首先Master的Offset必定大于Follower的Offset,因为Master传输出命令就把Offset增加了,无论Follower是否执行,但是Follower在请求Master的命令同步消息时,会携带自身的Offset,因此Master会将自己的Offset与Follower的Offset中间差距的数据传输给Follower,保证了数据不会丢失。

标签:同步,15,Redis,命令,Follower,复制,Offset,服务器
From: https://www.cnblogs.com/yanlishao/p/17928393.html

相关文章

  • 这儿有一个基于redis生成订单流水号的工具,拿走不谢!
     1importcn.hutool.core.util.RandomUtil;2importcn.hutool.core.util.StrUtil;3importlombok.extern.slf4j.Slf4j;4importorg.springframework.beans.factory.annotation.Autowired;5importorg.springframework.data.redis.core.RedisTemplate;6import......
  • Codeforces Round 915 (div2) E
    E.TreeQueries[题目链接](https://codeforces.com/contest/1904/problem/EProblem-E-Codeforces)题意概括:给定一棵大小为\(n\)的树,回答如下询问,询问之间相互独立:给定一个点\(x\)与\(k\)个点\(a_i\),求出从\(x\)出发不经过任何一个\(a_i\)的最长简单路径长度......
  • Redis哨兵内存碎片化故障处理
    背景介绍近期研发同学反馈业务响应波动厉害,怀疑是Redis操作key比较慢的缘故。由于该环境是我一手安装部署的,我将进行问题排查。Redis环境以及业务环境都已经使用Prometheus进行了监控。环境说明我们有两套一样的环境来服务不同的客户,另外一套环境中业务一直平稳运行,Redis并没......
  • 文件批量查找与复制
    文件批量查找与复制文件批量查找复制整理有现成的软件,可以在一堆文件中按文件名中关键字查找你需要的那些文件并全部整理复制到指定文件夹下 ......
  • S71500 OPCUA 通讯
    S71500OPCUA通讯(PLC作为OPCUAServer)测试工具:1,博图V172,PLCSIMAdvanced3.03,OPCUAClient测试步骤:博图中的设置1,在博图中新建项目,组态设备,这里要注意,PLCSIMAdvanced3.0支持的CPU版本最高只能到2.8,因此版本选择2.8就可以了2,在项目视图的设备组态中,把这几个地方勾上 3,运行系......
  • Cisco Expressway Release X15.0.0 - 统一通信网关
    CiscoExpresswayReleaseX15.0.0-统一通信网关Expressway&ExpresswaySelect请访问原文链接:https://sysin.org/blog/cisco-expressway-15/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.orgCiscoExpressway系列让协作变得更简单CiscoExpressway可在保证......
  • Cisco Unified Communications Manager (CallManager) 15.0 - 统一通信与协作
    CiscoUnifiedCommunicationsManager(CallManager)15.0-统一通信与协作思科统一通信管理器(CallManager)请访问原文链接:https://sysin.org/blog/cisco-ucm-15/,查看最新版。原创作品,转载请保留出处。作者主页:sysin.org思科统一通信管理器企业统一通信和协作借助思科......
  • Redis系列之事务机制
    什么是Redis事务学习mysql数据库的时候,我们知道了事务的ACID特性,Redis也是支持事务的,不过和数据库的事务又有什么区别?在mysql数据库中,我们使用begin开启事务,提交是commit,回滚是rollback,然后Redis中的事务是怎么一回事?redis的事务其实可以看做是一组命令按照顺序,串行执行队列中的命......
  • Windows下的Redis启动报错Redis service failed to start解决方法
    报错原因:Redis服务没有找到log文件解决方法在Redis安装目录下打开redis.windows-service.conf文件搜索logfile,找到logfile存放目录,一般默认为Logs/redis_log.txt在Redis安装目录创建Logs文件夹,在Logs文件夹下创建redis_log.txt文件重新启动即可解决......
  • mysql 配置主从复制
    主库配置#BinaryLogging.#log-binlog-bin=mysql-bin#[必须]启用二进制日志#ErrorLogging.log-error="mysql-error.log"#ServerId.server-id=200#不同步的数据库,可设置多个binlog-ignore-db=information_schemabinlog-ignore-db=performance_schemabinlo......