Redis复制

本文涉及的产品
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
简介:

 在Redis中,用户可以通过执行SLAVEOF命令或者设置slaveof选项,让一个服务器去复制(replicate)另一个服务器,我们称呼被复制的服务器为主服务器(master),而对主服务器进行复制的服务器则被称为从服务器(slave)。

    127.0.0.1:12345> SLAVEOF 127.0.0.1 6379

 

一、旧版(2.8版以前)复制功能的实现

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

    sync:

    当客户端向从服务器发送SLAVEOF命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作,将从服务器的数据库状态更新至主服务器当前所处的数据库状态。同步操作需要通过向主服务器发送SYNC命令来完成,以下是SYNC命令的执行步骤:

    1)从服务器向主服务器发送SYNC命令。

    2)收到SYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件,并使用一个缓冲区记录从现在开始执行的所有写命令。

    3)当主服务器的BGSAVE命令执行完毕时,主服务器会将BGSAVE命令生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,将自己的数据库状态更新至主服务器执行BGSAVE命令时的数据库状态。

    4)主服务器将记录在缓冲区里面的所有命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。

    command propagate:

    在同步操作执行完毕后,主从服务器进入命令传播阶段,主服务器会将自己执行的写命令,发送给从服务器执行(异步),当从服务器执行了相同的写命令后,主从服务器将再次回到一致状态。

    缺陷:

    在2.8版以前,从服务器对主服务器的复制可以分为以下两种情况:

    初次复制:从服务器以前没有复制过任何主服务器,或者从服务器当前要复制的主服务器和上一次复制的主服务器不同。

    断线后重复制:处于命令传播阶段的主从服务器因为网络原因而中断了复制,但从服务器通过自动重连重新连上了主服务器,并继续复制主服务器。

    对于初次复制来说,旧版复制功能能够很好地完成任务,但对于断线后重复制来说,旧版复制功能(全量复制)虽然也能让主从服务器重新回到一致状态,但效率非常低,毕竟SYNC命令是个非常耗费资源的操作。

 

二、新版复制功能的实现

    新版采用PSYNC命令代替SYNC命令来执行复制时的同步操作。PSYNC命令具有完整重同步(full resynchronization)和部分重同步(partial resynchronization)两种模式:

    完整重同步用于处理初次复制情况,执行步骤和SYNC执行步骤基本一样。

    部分重同步则用于处理断线后重复值情况:当从服务器在断线后重新连接主服务器时,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只要接收并执行这些写命令,就可以将数据库更新至主服务器当前所处的状态。

 

    部分重同步的实现:

    部分重同步功能由以下三个部分构成:

    *主服务器的复制偏移量(replication offset)和从服务器的复制偏移量。

    *主服务器的复制积压缓冲区(replication backlog)。

    *服务器的运行ID(run ID)。

 

    执行复制的双方——主服务器和从服务器会分别维护一个复制偏移量:

    *主服务器每次想从服务器传播N个字节的数据时,就将自己的offset+N。

    *从服务器每次收到主服务器传播来的N个字节的数据时,就将自己的offset+N。

    通过对比主从服务器的offset,程序可以很容易知道主从服务器是否处于一致状态。如果因为断线产生offset不一致,主服务器应该对从服务器执行完整重同步还是部分重同步呢?如果执行部分重同步,主服务器又如何补偿从服务器在断线期间丢失的那部分数据呢?以上问题的答案都和复制积压缓冲区有关。

 

    复制积压缓冲区是由主服务器维护的一个固定长度先进先出(FIFO)队列,默认大小为1MB。当主服务器进行命令传播是,它不仅会将写命令发送给所有从服务器,还会将命令入队到复制积压缓冲区里面。因此,主服务器的复制积压缓冲区里面会保存着一部分最近传播的写命令,并且复制积压缓冲区会为队列中的每个字节记录相应的复制偏移量。

    当从服务器重新连上主服务器时,从服务器会通过PSYNC命令将自己的offset发送给主服务器,主服务器会根据这个复制偏移量来决定对从服务器执行何种同步操作:

    如果offset偏移量之后的数据(也即是偏移量offset+1开始的数据)仍然存在于复制积压缓冲区里面,那么主服务器将对从服务器执行部分重同步操作。相反,如果offset偏移量之后的数据已经不存在于复制积压缓存区,那么主服务器将对从服务器执行完整重同步操作。

 

    除了复制偏移量和复制积压缓冲区之外,实现部分重同步还需要用到服务器运行ID,此ID由服务器启动时自动生成,由40个随机的十六进制字符组成。

    当从服务器对主服务器进行初次复制是,主服务器会将自己的运行ID传送给从服务器,而从服务器则会将这个运行ID保存起来。当从服务器断线并重连上一个主服务器时,从服务器将向当前连接的主服务器发送之前保存的运行ID,如果主服务器收到的这个ID与自己的ID相同,主服务器可以继续尝试执行部分重同步操作,否则执行完整重同步操作。

 

三、心跳检测

    在命令传播阶段,从服务器默认会以每秒一次的频率,向主服务器发送命令:

    REPLCONF ACK <replication_offset>

    其中replication_offset是从服务器当前的复制偏移量。

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

    *检测主从服务器的网络连接状态。如果主服务器超过一秒没收到REPLCONF ACK命令,主服务器就知道主从服务器之间的连接出问题了。

    *辅助实现min-slaves。

    Redis的min-slaves-to-write和min-slaves-max-lag两个选项可以防止主服务器在不安全的情况下执行写命令。举个例子,如果我们向主服务器提供以下设置:

    min-slaves-to-write 3

    min-slaves-max-lag 10

    那么在从服务器的数量少于3个,或者三个从服务器的延迟(lag)值都大于或等于10秒时,主服务器将拒绝执行写命令,这里的延迟值就是INFO replication命令返回的lag值。

    *检测命令丢失

    如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失,那么当从服务器向主服务器发送REPLCONF ACK命令时,主服务器将发觉从服务器当前的复制偏移量少于自己的复制便宜量,然后主服务器就会根据从服务器提交的复制偏移量,在复制积压缓冲区里面找到从服务器缺少的数据,并将这些数据重新发送给从服务器。


原文链接:[http://wely.iteye.com/blog/2363980]

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
存储 运维 负载均衡
Redis Cluster集群原理+三主三从交叉复制实战+故障切换
Redis Cluster集群原理+三主三从交叉复制实战+故障切换
1207 0
Redis Cluster集群原理+三主三从交叉复制实战+故障切换
|
NoSQL Redis
Redis下Lua脚本的复制模式
假设我们的Redis选择了主从架构, 和AOF持久化方式。我们执行一条写命令时, 该条命令会被发送到从服务器, 和追加到AOF文件中。当我们执行的不是一条命令, 而是Lua脚本时, 默认情况下, 整个Lua脚本的内容会进行复制, 但是存在一些特殊情况。
1933 0
Redis下Lua脚本的复制模式
|
存储 缓存 NoSQL
Redis学习 - 复制以及三种部署模式(下)
Redis学习 - 复制以及三种部署模式(下)
122 0
|
存储 运维 监控
Redis学习 - 复制以及三种部署模式(上)
Redis学习 - 复制以及三种部署模式(上)
137 0
|
存储 NoSQL Redis
​Redis:在集合中复制键
问题描述: 由于某种原因,我必须需要将某个集合的键(Key)复制一份副本。并移动到目标库
183 0
​Redis:在集合中复制键
|
存储 NoSQL Redis
【Redis】全量复制和部分复制
【Redis】全量复制和部分复制
311 0
【Redis】全量复制和部分复制
|
JSON NoSQL 关系型数据库
JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
无论MySQL还是Redis,自身都带有数据同步的机制,像比较常用的 MySQL的Master/Slave模式 ,就是由Slave端分析Master的binlog来实现的,这样的数据复制其实还是一个异步过程,只不过当服务器都在同一内网时,异步的延迟几乎可以忽略。
247 0
JAVA通过Gearman实现MySQL到Redis的数据同步(异步复制)
|
NoSQL Shell Redis
shell脚本一键部署——Redis(直接复制执行)亲测100% 有效
首先所需软件包拖进目录,然后编辑一个脚本,复制一下脚本,source执行一下即可
shell脚本一键部署——Redis(直接复制执行)亲测100% 有效
|
存储 运维 负载均衡
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)
Redis Cluster集群原理+实战+故障切换 文章目录 Redis Cluster集群原理+实战+故障切换 1.redis cluster原理概念 1.1.cluster架构概念 1.2.redis cluster不合理的架构图 1.3.部署一个cluster三主三从集群具体步骤 1.4.环境准备 2.部署redis cluster节点 2.1.redis-1配置 2.2.redis-2配置 2.3.redis-3配置 2.4.查看redis cluster进程 2.5.查看集群信息文件内容 3.配置cluster集群互相发现 3.1.互相发现概念 3.2.将集群的所有节点进行互相发现
1910 0
Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)