目录
一、Redis主从有两种结构模型:
1.1 主从复制
1.2 级联复制
二、Redis主从关系的建立
三、数据同步
3.1 全量同步
3.2 增量同步
四、主从复制策略
五、告一段落
首页 数据库 Redis 深入了解Redis中的主从同步机制

深入了解Redis中的主从同步机制

Nov 16, 2021 pm 06:54 PM
redis 主从同步

本篇文章带大家了解一下Redis中的主从同步,介绍一下Redis主从的两种结构模型、主从关系的建立、主从复制策略等,希望对大家有所帮助!

深入了解Redis中的主从同步机制

之前的文章中详细分析了redis的特性和核心原理,从本篇开始将对redis的部署结构和运行模式进行分析解读。真正生产环境当中我们基本不会使用单节点的redis来提供服务,至少是主从结构的哨兵或者集群模式,以保障redis服务的可靠性。本篇就来详细解读下redis的主从同步机制。【相关推荐:Redis视频教程

一、Redis主从有两种结构模型:

1.gif

1.1 主从复制

一主N从的这种复制结构复制关系只有一级,也是使用最多的形式,通常搭建哨兵或者集群结构的redis都是采用的这种复制结构,能够通过一级从节点的复制关系很好的保证服务的可用性,做到异常情况主从切换。

1.2 级联复制

级联复制结构的复制关系可以有多级,一个主节点的从节点可以是下属从节点的主节点。级联复制结构的应用相对比较少,这种结构能够在有多个从节点的结构下一定程度上缓解主节点的复制压力。

二、Redis主从关系的建立

redis的主从同步始于命令SLAVEOF host port,通过这个命令能够建立主从关系,SLAVEOF 命令用于在 Redis 运行时动态地修改复制功能的行为。通过执行 SLAVEOF host port 命令,可以将当前服务器转变为指定服务器的从属服务器(slave server)。如果当前服务器已经是某个主服务器(master server)的从属服务器,那么执行 SLAVEOF host port 将使当前服务器停止对旧主服务器的同步,丢弃旧数据集,转而开始对新主服务器进行同步。另外,对一个从属服务器执行命令 SLAVEOF NO ONE 将使得这个从属服务器关闭复制功能,并从从属服务器转变回主服务器,原来同步所得的数据集不会被丢弃。利用 SLAVEOF NO ONE 不会丢弃同步所得数据集这个特性,在没有搭建哨兵和集群的情况下,可以在主服务器失败的时候,将从属服务器用作新的主服务器,从而实现无间断运行。

下图为主从关系建立流程:

2.gif

注意:

根据上执行流程这里有一个需要注意点,当我们对一个已有主从关系的节点执行slaveof命令时,会结束掉现有的主从关系并清空节点下的所以数据,在生成环境当中这是比较威胁的操作。有没有更安全的方式了?上面介绍slavelof命令的时候提到可以传递NO ONE参数,也就是执行SLAVEOF NO ONE命令,这个命令是只会结束主从复制关系不会清空数据的,相对安全很多。

三、数据同步

建立好主从关系后就要进入主从数据同步的过程了,这里主要分三种情况,刚建立主从关系后的数据全量同步;初始化同步完成后的命令传播阶段;主从关系异常中断重连后的同步方式选择,这里会有全量和增量同步两种场景。

3.1 全量同步

  • 当slave节点启动后或断开重连后(重连不满足增量同步条件),会向master数据库发送SYNC命令。

  • master节点收到SYNC命令后会开始在后台保存快照(即RDB持久化,在主从复制时,会无条件触发RDB),并将保存快照期间接收到的命令缓存起来。

  • master节点执行RDB持久化完成后,向所有slave节点发送快照RDB文件,并在发送快照期间继续记录被执行的写命令。

  • slave节点收到快照文件后丢弃所有旧数据(会清空所有数据),载入收到的快照。

  • master节点快照发送完毕、slave节点载入快照完毕后,master节点开始向slave节点发送缓冲区中的写命令。

  • slave节点完成对快照的载入,开始接收命令请求,并执行来自主数据库缓冲区的写命令。(从数据库初始化完成)

  • master节点每执行一个写命令就会向slave节点发送相同的写命令,slave节点接收并执行收到的写命令。(命令传播操作,slave节点初始化完成后的操作)

全量同步流程如下图:

3.gif

在redis2.8之前,从节点无论是初始化还是断线重连后都是采用全量同步的方式,在2.8之后版本,引入PSYNC命令,在从节点断线重连后会判断是否采用增量同步。

3.2 增量同步

PSYNC具备了数据全量重同步和增量同步模式。

  • 全量重同步:跟旧版复制基本是一致的,可以理解为“全量”复制。

  • 部分重同步:salve断开又重新连时,在命令传播阶段,只需要发送与master断开这段时间执行的写命给slave即可,可以理解为“增量”复制。

PSYNC执行过程中比较重要的概念有3个:runid、offset(复制偏移量)以及复制积压缓冲区。

1.runid

每个Redis服务器都会有一个表明自己身份的ID。在PSYNC中发送的这个ID是指之前连接的Master的ID,如果没保存这个ID,PSYNC的命令会使用”PSYNC ? -1” 这种形式发送给Master,表示需要全量复制。 

2.offset(复制偏移量)

在主从复制的Master和Slave双方都会各自维持一个offset。Master成功发送N个字节的命令后会将Master里的offset加上N,Slave在接收到N个字节命令后同样会将Slave里的offset增加N。Master和Slave如果状态是一致的那么它的的offset也应该是一致的。

3.复制积压缓冲区

复制积压缓冲区是由Master维护的一个固定长度环形积压队列(FIFO队列),它的作用是缓存已经传播出去的命令。当Master进行命令传播时,不仅将命令发送给所有Slave,还会将命令写入到复制积压缓冲区里面。PSYNC执行过程和SYNC的区别在于:salve连接时,判断是否需要全量同步,全量同步的逻辑过程和SYNC一样。PSYNC执行步骤如下:

  • 客户端向服务器发送SLAVEOF命令,即salve向master发起连接请求时,slave根据自己是否保存Master runid来判断是否是第一次连接。

  • 如果是第一次同步则向Master发送 PSYNC ? -1 命令来进行完整同步;如果是重连接,会向Master发送PSYNC runid offset命令(runid是master的身份ID,offset是从节点同步命令的全局迁移量)。

  • Master接收到PSYNC 命令后,首先判断runid是否和本机的id一致,如果一致则会再次判断offset偏移量和本机的偏移量相差有没有超过复制积压缓冲区大小,如果没有那么就给Slave发送CONTINUE,此时Slave只需要等待Master传回失去连接期间丢失的命令。如果runid和本机id不一致或者offset差距超过了复制积压缓冲区大小,那么就会返回FULLRESYNC runid offset,Slave将runid保存起来,并进行全量同步。

主节点在命令传播时,主数据库会将每一个写命令传递给从数据库的同时,都会将写命令存放到积压队列,并记录当前积压队列中存放命令的全局偏移量offset。当salve重连接时,master会根据从节点传的offset在环形积压队列中找到断开这段时间执行的命令,并同步给salve节点,达到增量同步结果。

PSYNC执行流程如下图:

4.gif

从以上PSYNC的执行流程可以看出当slave节点断线重连以后判断是否采用增量同步的核心是slave的offset偏移量和master的偏移量相差有没有超过复制积压缓冲区大小,那么这个大小是由以下参数来配置的。复制积压缓冲区本质上是一个固定长度的循环队列,默认情况下积压队列的大小为1MB,可以通过配置文件设置队列大小:设置复制积压缓冲区大小,积压队列越大,允许主从数据库断线的时间就越长

repl-backlog-size 1mb
登录后复制

Redis同时也提供了当没有slave需要同步的时候,多久可以释放环形队列,默认一小时,没有salve连接时,多久释放一次复制积压缓冲区

repl-backlog-ttl 3600
登录后复制

四、主从复制策略

Redis采用了乐观复制的策略,也就是在一定程度内容忍主从数据库的内容不一致,但是保持主从数据库数据的最终一致性。具体来说,Redis在主从复制的过程中,本身就是异步的,在主从数据库执行完客户端请求后会立即将结果返回给客户端,并异步的将命令同步给从数据库,但是这里并不会等待从数据库完全同步之后,再返回客户端。这一特性虽然保证了主从复制期间性能不受影响,但是也会产生一个数据不一致的时间窗口,如果在这个时间窗口期间网络突然断开连接,就会导致两者数据不一致。如果不在配置文件中添加其他策略,那就默认会采用这种方式。为了防止主从不一致不可控,redis提供了以下两个参数来做约束:

min-slaves-to-write 3
min-slaves-max-lag 10
登录后复制

当slave数量小于min-slaves-to-write,且延迟小于等于min-slaves-max-lag时,master停止写入操作。

还有一个参数也会影响主从之间的延时:

repl-disable-tcp-nodelay:

设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟,造成master与slave数据不一致。设置成no,则redis master会立即发送同步数据,几乎没有延迟。

Redis的主从同步无论那种场景可以抽象为以下七个步骤:

5.gif

1.建立socket连接

从服务器根据设置的套接字创建连向主服务器的套接字连接,主服务器接收从服务器的套接字连接之后,为该套接字创建响应的客户端状态,并将此时的从服务器看做是主服务器的客户端,也就是该从服务器同时具备服务器与客户端两个身份。

2.发送PING命令

PING命令主要有两种作用:虽然建立了套接字连接,但是还未使用过,通过发送PING命令检查套接字的读写状态是否正常;通过发送PING命令检查主服务器能否正常处理命令请求,能处理主服务器回复PONG。

3.身份验证

从服务器接收到主服务器返回的“PONG”回复,接下来就需要考虑身份验证的事。如果从服务器设置了masterauth选项,那么进行身份验证,如果从服务器没有设置masterauth选项,那么不进行身份验证。

4.发送端口信息

在身份验证步骤之后,从服务器将执行命令REPLCONF listening-port ,向主服务器发送从服务器的监听端口号。

5.数据同步

从服务器向主服务器发送SYNC命令、PSYNC命令,执行同步操作。

6.命令传播

主从服务器就会进入命令传播阶段,主服务器只要将自己执行的写命令发送给从服务器,而从服务器只要一直执行并接收主服务器发来的写命令。

五、告一段落

本篇详细介绍了redis主从同步机制,不同场景下同步策略的选择,这也是redis高可用的基石。在此基础上,下一篇将对redis高可用的实现来进行分析讲解。

更多编程相关知识,请访问:编程视频!!

以上是深入了解Redis中的主从同步机制的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳图形设置
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌
威尔R.E.P.O.有交叉游戏吗?
1 个月前 By 尊渡假赌尊渡假赌尊渡假赌

热工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3汉化版

SublimeText3汉化版

中文版,非常好用

禅工作室 13.0.1

禅工作室 13.0.1

功能强大的PHP集成开发环境

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SublimeText3 Mac版

SublimeText3 Mac版

神级代码编辑软件(SublimeText3)

redis集群模式怎么搭建 redis集群模式怎么搭建 Apr 10, 2025 pm 10:15 PM

Redis集群模式通过分片将Redis实例部署到多个服务器,提高可扩展性和可用性。搭建步骤如下:创建奇数个Redis实例,端口不同;创建3个sentinel实例,监控Redis实例并进行故障转移;配置sentinel配置文件,添加监控Redis实例信息和故障转移设置;配置Redis实例配置文件,启用集群模式并指定集群信息文件路径;创建nodes.conf文件,包含各Redis实例的信息;启动集群,执行create命令创建集群并指定副本数量;登录集群执行CLUSTER INFO命令验证集群状态;使

redis数据怎么清空 redis数据怎么清空 Apr 10, 2025 pm 10:06 PM

如何清空 Redis 数据:使用 FLUSHALL 命令清除所有键值。使用 FLUSHDB 命令清除当前选定数据库的键值。使用 SELECT 切换数据库,再使用 FLUSHDB 清除多个数据库。使用 DEL 命令删除特定键。使用 redis-cli 工具清空数据。

redis指令怎么用 redis指令怎么用 Apr 10, 2025 pm 08:45 PM

使用 Redis 指令需要以下步骤:打开 Redis 客户端。输入指令(动词 键 值)。提供所需参数(因指令而异)。按 Enter 执行指令。Redis 返回响应,指示操作结果(通常为 OK 或 -ERR)。

redis怎么使用锁 redis怎么使用锁 Apr 10, 2025 pm 08:39 PM

使用Redis进行锁操作需要通过SETNX命令获取锁,然后使用EXPIRE命令设置过期时间。具体步骤为:(1) 使用SETNX命令尝试设置一个键值对;(2) 使用EXPIRE命令为锁设置过期时间;(3) 当不再需要锁时,使用DEL命令删除该锁。

redis怎么读取队列 redis怎么读取队列 Apr 10, 2025 pm 10:12 PM

要从 Redis 读取队列,需要获取队列名称、使用 LPOP 命令读取元素,并处理空队列。具体步骤如下:获取队列名称:以 "queue:" 前缀命名,如 "queue:my-queue"。使用 LPOP 命令:从队列头部弹出元素并返回其值,如 LPOP queue:my-queue。处理空队列:如果队列为空,LPOP 返回 nil,可先检查队列是否存在再读取元素。

redis底层怎么实现 redis底层怎么实现 Apr 10, 2025 pm 07:21 PM

Redis 使用哈希表存储数据,支持字符串、列表、哈希表、集合和有序集合等数据结构。Redis 通过快照 (RDB) 和追加只写 (AOF) 机制持久化数据。Redis 使用主从复制来提高数据可用性。Redis 使用单线程事件循环处理连接和命令,保证数据原子性和一致性。Redis 为键设置过期时间,并使用 lazy 删除机制删除过期键。

redis怎么读源码 redis怎么读源码 Apr 10, 2025 pm 08:27 PM

理解 Redis 源码的最佳方法是逐步进行:熟悉 Redis 基础知识。选择一个特定的模块或功能作为起点。从模块或功能的入口点开始,逐行查看代码。通过函数调用链查看代码。熟悉 Redis 使用的底层数据结构。识别 Redis 使用的算法。

redis怎么做消息中间件 redis怎么做消息中间件 Apr 10, 2025 pm 07:51 PM

Redis 作为消息中间件,支持生产-消费模型,可持久化消息并保证可靠交付。使用 Redis 作为消息中间件可实现低延迟、可靠和可扩展的消息传递。

See all articles