Redis 复制过程详解

Redis 的复制功能分为同步( sync )和命令传播( command propagate )两个步骤:

  • 同步用于将从服务器的数据库状态更新至主服务器当前所处的数据库状态。
  • 命令传播则用于在主服务器的数据库状态被修改,导致主从服务器的数据库状态出现不一致时,让主从服务器的数据库重新回到一致状态。

同步

Redis 使用 psync 命令完成主从数据同步,同步过程分为:全量复制和部分复制。

全量复制:一般用于初次复制场景,它会把主节点全部数据一次性发送给从节点发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。

部分复制:用于处理在主从复制中因网络闪断等原因造成的网络丢失场景,当从节点再次连接上主节点后,如果条件允许,主节点会补发丢失数据给从节点。因为补发的数据远远小于全量数据,可以有效避免全量复制的过高开销。

psync 命令运行需要以下组件支持:

  • 主从节点各自复制偏移量
  • 主节点复制积压缓冲区
  • 主节点运行 id

参与复制的从节点都会维护自身复制偏移量。主节点在处理完写命令后,会把命令的字节长度做累加记录,统计在 info replication 中的 masterreploffset 指标中。 从节点在接收到主节点发送的命令后,也会累加记录自身的偏移量,并且会每秒钟上报自身的复制偏移量给主节点。 通过对比主从节点的复制偏移量,可以判断主从节点数据是否一致。

复制积压缓冲区是保存在主节点的一个固定长度的队列,默认大小为 1MB,当主节点有连接的从节点时被创建。主节点响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓冲区中。

复制积压缓冲区大小有限,只能保存最近的复制数据,用于部分复制和复制命令丢失时的数据补救。

每个 Redis 节点启动后都会动态分配一个 40 位的十六进制字符串作为运行 ID。运行 ID 的主要作用是用来唯一标识 Redis 节点,比如说从节点保存主节点的运行 ID 来识别自己正在复制的时哪个主节点。

全量同步

slaveof 命令的执行

  • 1) 从节点发送 psync 命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量和主节点的运行ID,所以发送的命令时 PSYNC ? -1。
  • 2) 主节点根据 PSYNC ? -1 解析出当前为全量复制,回复 + FULLRESYNC 响应。
  • 3) 从节点接收主节点的响应数据保存运行 ID 和偏移量 offset。
  • 4) 主节点执行 bgsave 保存 RDB 文件到本地,有关 RDB 的知识可以查看《Redis RDB 持久化详解》
  • 5) 主节点发送 RDB 文件给从节点,从节点把接收的 RDB 文件保存在本地并直接作为从节点的数据文件,接收完 RDB 后从节点打印相关日志,可以在日志中查看主节点发送的数据量。

需要注意,对于数据量较大的主节点,比如生成的 RDB 文件超过 6GB 以上时要格外小心。如果传输 RDB 的时间超过 repl-timeout 所配置的值,从节点将发起接收 RDB 文件并清理已经下载的临时文件,导致全量复制失败。

  • 6) 对于主节点开始保存 RDB 快照到从节点接收完成期间,主节点仍然响应读命令,因此主节点会把这期间写命令保存在复制客户端缓冲区内,当从节点加载完 RDB 文件后,主节点再把缓冲区内的数据发送给从节点,保证主从之间数据一致性。

如果主节点创建和传输 RDB 的时间过长,可能会出现主节点复制客户端缓冲区溢出。默认配置为 client-output-buffer-limit slave 256MB 64MB 60,如果60s内缓冲区消耗持续大于64MB或者直接超过256MB时,主节点将直接关闭复制客户端连接,造成全量同步失败。

  • 7) 从节点接收完主节点传送来的全部数据后会清空自身旧数据,该步骤对应如下日志。
  • 8) 从节点清空数据后开始加载 RDB 文件,对于加大的 RDB 文件,这一步操作依然比较耗时,可以通过计算日志之间的时间差来判断加载 RDB 的总耗时。
  • 9) 收到 SYNC 命令的主服务器执行 BGSAVE 命令,在后台生成一个 RDB 文件,并使用一个缓冲区记录从现在开始执行的所有写命令。
  • 10) 当主服务器的 BGSAVE 命令执行完毕时,主服务器会将 GBSAVE 命令生成的 RDB 文件发送给从服务器,从服务器接收并载入这个 RDB 文件,将自己的数据库状态更新至主服务器执行 BGSAVE 命令时的数据库状态。
  • 11) 主服务器将记录在缓冲区里边的所有写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。

通过分析全量复制的所有流程,读者会发现全量复制是一个非常耗时费力的操作。它时间开销主要包括:

  • 主节点 bgsave 时间
  • RDB 文件网络传输时间
  • 从节点清空数据时间
  • 从节点加载 RDB 的时间
  • 可能的 AOF 重写时间

全量同步过程中不仅会消耗大量时间,还会进行多次持久化相关操作和网络数据传输,这期间会大量消耗主从节点所在服务器的 CPU、内存和网络资源。所以,除了第一次复制是采用全量同步无法避免,其他场景应该规避全量复制,采取部分同步功能。

部分同步

部分复制主要是 Redis 针对全量复制的过高开销做出的一种优化措施,使用 psync {runId} {offset} 命令实现。当从节点正在复制主节点时,如果出现网络闪断或者命令丢失等异常情况时,从节点会向主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区存在这部分数据则直接发送给从节点,这样就保证了主从节点复制的一致性。补发的这部分数据一般远远小于全量数据,所以开销很小。

  • 1 ) 当主从节点之间网络出现中断时,如果超过了 repl-timeout 时间,主节点会认为从节点故障并中断复制连接。
  • 2) 主从连接中断期间主节点依然响应命令,但因复制连接中断命令无法发送给从节点,不过主节点内部存在复制积压缓冲区( repl-backlog-buffer ),依然可以保存最近一段时间的写命令数据,默认最大缓存 1MB。
  • 3) 当主从节点网络恢复后,从节点会再次连上主节点。
  • 4) 当主从连接恢复后,由于从节点之前保存了自身已复制的偏移量和主节点的运行ID。因此会把它们作为 psync 参数发送给主节点,要求进行补发复制操作。
  • 5) 主节点接到 psync 命令后首先核对参数 runId 是否与自身一致,如果一致,说明之前复制的是当前主节点;之后根据参数 offset 在自身复制积压缓冲区查找,如果偏移量之后的数据存在缓冲区中,则对从节点发送 +CONTINUE 响应,表示可以进行部分复制。
  • 6) 主节点根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态。

心跳检测

主从节点在建立复制后,它们之间维护着长连接并彼此发送心跳命令,如下图所示。

主从心跳判断机制如下所示:

  • 1) 主从节点彼此都有心跳检测机制,各自模拟成对方的客户端进行通信,通过 client list 命令查看复制相关客户端信息,主节点的连接状态为 flags=M,从节点连接状态为 flags=S。
  • 2) 主节点默认每隔 10 秒对从节点发送 ping 命令,判断从节点的存活性和连接状态。可以通过参数 repl-ping-slave-period 控制发送频率。
  • 3) 从节点在主线程中每隔 1 秒发送 replconf ack { offset } 命令,给主节点上报自己当前的复制偏移量。

replconf 命令不仅能实时监测主从节点网络状态,还能上报从节点复制偏移量。主节点会根据从节点上传的偏移量检查复制数据是否丢失,如果从节点数据丢失,再从主节点的复制缓存区中拉取丢失的数据发送给该从节点。

异步复制和命令传播

主节点不但负责数据读写,还负责把写命令同步给从节点。写命令的发送过程是异步完成,也就是说主节点自身处理完写命令后直接返回给客户端,并不等待从节点复制完成。

这个异步过程由命令传播来处理,它不仅会将写命令发送给所有从服务器,还会将写命令入队到复制积压缓冲区里边。

后记

个人博客,欢迎来玩

原文地址:https://www.cnblogs.com/remcarpediem/p/11701234.html

时间: 2024-10-11 22:58:20

Redis 复制过程详解的相关文章

Redis高可用详解:持久化技术及方案选择

Redis高可用详解:持久化技术及方案选择 Java架构师那些事 关注 0.3 2018.08.23 22:55 字数 9774 阅读 542评论 0喜欢 9 前言 本文将先说明上述几种技术分别解决了Redis高可用的什么问题,然后详细介绍Redis的持久化技术,主要是RDB和AOF两种持久化方案.在介绍RDB和AOF方案时,不仅介绍其作用及操作方法,同时还会介绍持久化实现的一些原理细节及需要注意的问题.最后,介绍在实际使用中持久化方案的选择以及经常遇到的问题等内容. 一.Redis高可用概述

Linux系统启动过程详解

 Linux系统启动过程详解 启动第一步--加载BIOS当你打开计算机电源,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它.这是因为BIOS中包含了CPU的相关信息.设备启动顺序信息.硬盘信息.内存信息.时钟信息.PnP特性等等.在此之后,计算机心里就有谱了,知道应该去读取哪个硬件设备了. 启动第二步--读取MBR众所周知,硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,它的大小是512字节,别看地方不大,

LAMP架构搭建以及基于LAMP架构的主流论坛和博客搭建过程详解

了解网站架构的朋友都知道,现在很多网站的架构都是采用LAMP(Linux+Apache+Mysql/Mariadb+Php)的,至于LAMP架构本身我们就不做过于深入的探讨了,今天我给大家分享的是关于如何搭建LAMP构架,以及如何基于lamp架构去搭建目前国内比较流行的两大开源论坛(phpwind.discuz)一大开源博客(wordpress),通过这个过程也就能让大家明白我们经常上的论坛以及博客,包括包括我们访问的各个网站到底是如何工作起来的. 注意:为了方便给大家展示实验效果,我们就直接关

Hadoop MapReduce执行过程详解(带hadoop例子)

https://my.oschina.net/itblog/blog/275294 摘要: 本文通过一个例子,详细介绍Hadoop 的 MapReduce过程. 分析MapReduce执行过程 MapReduce运行的时候,会通过Mapper运行的任务读取HDFS中的数据文件,然后调用自己的方法,处理数据,最后输出.Reducer任务会接收Mapper任务输出的数据,作为自己的输入数据,调用自己的方法,最后输出到HDFS的文件中.整个流程如图: Mapper任务的执行过程详解 每个Mapper任

PHP Socket 编程过程详解

PHP Socket 编程过程详解 Socket用于进程间通信.进程间通信通常基于客户端—服务端模型.此时,客户端—服务端是可以彼此交互的应用程序.客户端和服务端之间的交互需要连接.Socket编程负责的就是为应用程序之间建立可进行交互的连接. 在本文中,我们将学习如何用PHP创建一个简单的客户端—服务端.我们还将学习如何客户端应用程序如何发送消息到服务端,以及如何从服务端接受消息. 使用代码 目的:开发一个客户端用于发送string消息到服务端,服务端将相同的信息反转后返回给客户端. PHP服

VxWorks启动过程详解(下)

上一节主要是从映像的分类和各种映像的大致加载流程上看VxWorks的启动过程,这一节让我们从函数级看一下VxWorks的启动过程: 1. Boot Image + Loadable Images: 下面是具体的流程图: 其中第一阶段的执行流程使用的是上图的左边的源文件中的那些函数(romInit->romStart->usrInit->sysHwinit->usrKernelinit->usrRoot);第二阶段执行流程使用的是上图中右边源文件中的那些函数(sysInit-&

[转载] Android签名机制之—签名过程详解

本文转载自: http://www.wjdiankong.cn/android%E7%AD%BE%E5%90%8D%E6%9C%BA%E5%88%B6%E4%B9%8B-%E7%AD%BE%E5%90%8D%E8%BF%87%E7%A8%8B%E8%AF%A6%E8%A7%A3/ 一.前言 又是过了好长时间,没写文章的双手都有点难受了.今天是圣诞节,还是得上班.因为前几天有一个之前的同事,在申请微信SDK的时候,遇到签名的问题,问了我一下,结果把我难倒了..我说Android中的签名大家都会熟悉

Android签名机制之---签名过程详解

一.前言 又是过了好长时间,没写文章的双手都有点难受了.今天是圣诞节,还是得上班.因为前几天有一个之前的同事,在申请微信SDK的时候,遇到签名的问题,问了我一下,结果把我难倒了..我说Android中的签名大家都会熟悉的,就是为了安全,不让别人修改你的apk,但是我们真正的有了解多少呢?所以准备两篇文章好好介绍一下Android中签名机制. 在说道Android签名之前,我们需要了解的几个知识点 1.数据摘要(数据指纹).签名文件,证书文件 2.jarsign工具签名和signapk工具签名 3

redis服务简介 && redis.conf配置文件详解

#一.redis服务简介 redis是一个key-value存储系统. 和Memcached类似,它支持存储的value类型相对更多(memcached不支持value类型,只支持key),包括string(字符串).list(链表).set(集合)和zset(有序集 合).这些数据类型都支持push/pop.add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的.在此基础上,redis 支持各种不同方式的排序.与memcached一样,为了保证效率,数据都是缓存在内存中