参考资料:

《Redis 复制》

《redis:主从复制缓冲区》

《Redis主从复制》

《深入学习Redis:主从复制》

前文:

《Redis:持久化RDB与AOF》

写在开头:本文为学习后的总结,可能有不到位的地方,错误的地方,欢迎各位指正。

目录

一、主从复制简介

1、主从复制是什么

2、主从复制有哪些作用

二、主从复制详解

1、复制方式

2、全量复制

(1)确立主从关系

(2)全量复制的流程

3、增量复制

(1)复制偏移量(replication offset)

(2)复制积压缓冲区(replication backlog)

(3)断开重连的注意点

三、心跳检测

1、检测主从连接状态

2、辅助实现 min-slaves 选项

3、检测命令丢失

四、补充

1、主库建议开启持久化

2、全量复制为什么使用RDB而不是AOF

3、读写分离时怎么删除过期数据


一、主从复制简介

1、主从复制是什么

主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。

从 Redis 2.6 开始, 从服务器支持只读模式, 并且该模式为从服务器的默认模式。只读模式由 redis.conf 文件中的 slave-read-only 选项控制, 也可以通过 CONFIG SET parameter value (opens new window)命令来开启或关闭这个模式。只读从服务器会拒绝执行任何写命令, 所以不会出现因为操作失误而将数据不小心写入到了从服务器的情况。

一个主服务器可以有多个从服务器,一个从服务器只能有一个主服务器,并且不支持主主复制。

不仅主服务器可以有从服务器,从服务器也可以有自己的从服务器, 多个从服务器之间可以构成一个主从链。

2、主从复制有哪些作用

  • 数据备份:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
  • 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复。
  • 读写分离:由主节点提供写服务,由从节点提供读服务,提高Redis服务器的并发量。

实现主从复制后可以将读操作分摊到从节点上:

  • 读操作:主库、从库都可以接收;
  • 写操作:首先到主库执行,然后,主库将写操作同步给从库。

二、主从复制详解

1、复制方式

  • 全量复制:比如第一次同步时
  • 增量复制:只会把主从库网络断连期间主库收到的命令,同步给从库

        Redis在2.8版本之前只有全量复制,而2.8版本后有全量和增量复制。

2、全量复制

(1)确立主从关系

Redis 通过 replicaof host port (5.0前使用slaveof)命令来让一个Redis服务成为另一个Redis服务的从库。

例如,现在有实例 1(ip:172.16.19.3)和实例 2(ip:172.16.19.5),我们在实例 2 上执行以下这个命令后,实例 2 就变成了实例 1 的从库,并从实例 1 上复制数据:

replicaof 172.16.19.3 6379

(2)全量复制的流程

完整复制流程如下:

  • 第一步,从库向主库发送PSYNC ? -1 命令,主动请求进行完整重同步

这一步是主从库间建立连接、协商同步的过程,主要是为全量复制做准备。在这一步,从库和主库建立起连接,并告诉主库即将进行同步,主库确认回复后,主从库间就可以开始同步了。

从库给主库发送 psync 命令,表示要进行数据同步,主库根据这个命令的参数来启动复制。psync 命令包含了主库的 runID 和复制进度 offset 两个参数。

        runID是Redis启动时给每个实例创建的唯一ID,用以标识不同的Redis实例,当从库和主库第一次复制时,因为不知道主库的 runID,所以将 runID 设为“?”。offset则表示复制进度(也叫复制偏移量),主要为增量复制服务,这里因为是全量复制,所以使用-1表示。

  • 第二步,主库向从库发送FULLRESYNC响应命令并带上两个参数:主库 runID 和主库目前的复制进度 offset
  • 第三步,主库执行 bgsave 命令,生成 RDB 文件,并发给从库。

此时,主库为了响应从库的复制请求,会调用bgsave 命令,生成 RDB 文件,接着将文件发给从库。(RDB在此前的持久化内容中已做过介绍,这里不再赘述,不了解的可以看这里《Redis:持久化RDB与AOF》)

从库接收到 RDB 文件后,会先清空当前数据库,然后加载 RDB 文件。这是因为从库在通过 replicaof 命令开始和主库同步前,可能保存了其他数据。为了避免之前数据的影响,从库需要先把当前数据库清空。

  • 第四步,将发送过程中收到的指令存储到replication buffer中,并发送给从库

就像RDB文件生成过程中Redis不停止提供服务一样,从库在接收并载入RDB文件的过程中,主库仍然可以写入数据,那怎么将这部分数据传给从库呢?

为了处理这部分数据,主库为每个连接进来的从库准备了一个replication buffer缓冲区,这段时间内写入的数据都会被存入这个replication buffer中,等从库载入完RDB文件后,就将replication buffer中的数据推送过去。

        如上,全量复制的完成流程就完成了,后续主库接收到的写命令都会被主库传递给所有从库,以保证数据的一致性。

对于第一次建立主从关系的2台实例,全量复制功能可用很好完成任务;但是对于断线后重复制,由于每次任然需要生成 RDB 并传输。

了解过前文持久化的朋友应该知道,生成RDB文件是比较耗费资源的,同时,主服务器传输 RDB 文件给从服务器,这个操作会耗费主从服务器大量的网络资源,并对主服务器响应时延产生影响。而对从服务器而言,载入 RDB 文件期间,会阻塞其他命令请求,这也会导致响应效率的降低。为此,Redis2.8之后便提供了增量复制的功能以应对这种情况。

3、增量复制

在2.8以前只有全量复制,如果主从库在命令传播时出现了网络闪断,那么,从库就会和主库重新进行一次全量复制,开销非常大。因此 从Redis 2.8 开始提供了增量复制的功能,在网络断了之后,主从库会采用增量复制的方式继续同步。

(1)复制偏移量(replication offset)

主服务器和从服务器会分别维护一个复制偏移量。如果主从服务器的复制偏移量相同,则说明二者的数据库状态一致;反之,则说明二者的数据库状态不一致,此时从库需要使用增量复制来同步缺失的这一部分数据。

(2)复制积压缓冲区(replication backlog)

        主库的写命令,除了传给从库后,还会写入replication backlog(全局唯一),这是一个固定长度的先进先出(FIFO)队列,默认大小为 1MB。其在内存中是一个环形结构。

如上图,主库按照顺时针方向写命令,主库最新写入的位置即为上文提到的主库的偏移量,这里叫master offset。假设从库在set key2 2后断开连接,也就是上图中slave offset的位置,当它重连时,再次给主库发送psync指令时,会带上自己的offset(注意和全量复制的区别,全量复制时offset设置为-1)。根据上文,我们知道主库发现从库的偏移量与自己不一致,需要进行增量复制。此时主库会计算出master offset与slave offset之间的指令,并发送给该为从库准备的replication buffer中,进而发送给从库。从库进行写入后便又恢复到和主库一致的状态。

        上文就是整个增量复制的过程,我们通过下图展示出来

        (3)断开重连的注意点 

        断开重连并不一定总是增量复制

        1、整个replication backlog是个环形结构,也就是说最新的写命令会将最老的写命令覆盖。换句话说,如果从库断开时间太久,环形缓冲区被主库的写命令覆盖了,那么从库连上主库后只能通过全量复制来获取数据了。所以replication backlog配置要尽量大一些,可以降低主从断开后全量复制的概率。

        2、上文中有提到每个实例有自己的RunID,这个值在服务器启动时自动生成,由 40 个随机的十六进制字符组成。从库断开重连时会将之前主库的RunID一起发送过去(这里注意和全量复制(或者说是第一次连接)的区别,全量复制时发送的RunID是“?”),主库会判断这个RunID是否为自己,如果不是,则会和全量复制时一样返回FULLRESYNC响应命令,告知从库需要进行全量复制。

三、心跳检测

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

// replication_offset为从服务器当前的复制偏移量
REPLCONF ACK <replication_offset>

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

  • 检测主从服务器的网络连接状态。
  • 辅助实现 min-slaves 选项。
  • 检测命令丢失

1、检测主从连接状态

可以通过发送和接收 REPLCONF ACK 命令来检查主从服务器之间的网络连接是否正常:如果主服务器超过一秒没有收到从服务器发来的 REPLCONF ACK 命令,那么主服务器就知道主从服务器之间的连接出现问题了。

可以通过向主服务器发送 INFO replication 命令,在列出的从服务器列表的 lag 一栏中,可以看到从服务器向主服务器发送 REPLCONF ACK 命令已经过去多少秒在一般情况下,lag的值应该在0秒或者1秒之间跳动,如果超过1秒的话,那么说明主从 服务器之间的连接出现了故障。

2、辅助实现 min-slaves 选项

在Redis中,为了避免主从之间产生较大的数据丢失,提供了min-slaves-to-write和min-slaves-max-lag两个选项可以防止主服务器在不安全的情况下执行写命令。

min-slaves-to-write 3
min-slaves-max-lag 10

以上配置表示:从服务器小于 3 个,或三个从服务器的延迟(lag)都大于等于 10 秒时,主服务器将拒绝执行写命令,直至故障恢复。

3、检测命令丢失

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

四、补充

1、主库建议开启持久化

假设主库不开启持久化,那么当主库自动重启后,数据全部丢失,成为空库。此时从库继续复制主库的数据,发现无数据,从库上的复制数据也会被删除。

         因此在允许自动重启的主库中不开启持久化是非常危险的,如果确实有关闭主库持久化的需要,则应禁止实例自动重启。

2、全量复制为什么使用RDB而不是AOF

在前文(《Redis:持久化RDB与AOF》)中,我们介绍了2种持久化的方法RDB与AOF。

AOF实时性更高,但使用的指令追加的方式,且载入数据时需要根据这些指令逐条操作数据来实现从库与主库的数据一致,这其中一些不乏冗余操作,例如一个数据被新增后删除,AOF文件中就会有一条add一条del指令,但这2条指令执行后库中并没有新的数据,完全可以跳过。

以上的缺点导致AOF文件较大,更耗费资源(包括主从库间的网络传输与从库的载入)。

而RDB虽然时效性差了一些,但生成的是主库数据的快照,文件小,载入快,因此比AOF更适合用作做全量复制。

3、主从复制怎么删除过期数据

在前文(《Redis:内存淘汰机制》)中我们介绍了过期数据的删除策略,包括定期删除与惰性删除。

在主从复制场景下,为了保证主从库的数据一致性,从库不会主动删除数据,而是由主库控制从库中过期数据的删除,当主库删除数据时会将del指令传播给从库,进而将从库中的过期数据进行删除。

由于主库的惰性删除和定期删除策略,都不能保证主库及时对过期数据执行删除操作,因此,当客户端通过Redis从库读取数据时,很容易读取到已经过期的数据。 Redis 3.2中,从节点在读取数据时,增加了对数据是否过期的判断:如果该数据已过期,则不返回给客户端;将Redis升级到3.2可以解决数据过期问题。

Redis:主从复制相关推荐

  1. Redis主从复制配置

    环境描述 Redis Master:192.168.1.100 6379(Ubuntu系统) Redis Slave1:192.168.1.101 6380(Ubuntu系统) Redis Slave ...

  2. redis主从复制故障转移

    Redis主从复制与故障切换 目录 目录1 一.概述1 二. 实验目的2 三.试验环境2 四. 说明2 五. 拓扑2 六. 实施步骤2 6.1.分别安装redis2.8.32 6.2.配置主从同步3 ...

  3. redis+主从复制+集群配置

    redis+主从复制+集群配置 redis是一个key-value存储系统.和memcached类似,不过redis支持的value类型更多,主要有:string(字符串).list(链表).set( ...

  4. cxgrid主从表 点+号展开_深入理解Redis主从复制

    一.背景 前面的文章中,我们介绍过Redis的持久化机制,它可以实现Redis实例数据的crash-safe.但是这里有一个问题,就是Redis其实还存在着单点故障问题,比如说Redis的硬盘坏掉了, ...

  5. Redis主从复制下的工作原理

    Redis主从复制下的工作原理 Redis主从复制的配置十分简单,它可以使从服务器是主服务器的完全拷贝.需要清楚Redis主从复制的几点重要内容: 1)Redis使用异步复制.但从Redis 2.8开 ...

  6. php连接redis 主从复制,redis怎么进行主从复制

    redis主从复制同步实现的过程 1.从服务发送一个sync同步命令给主服务要求全量同步 (推荐学习:Redis视频教程) 2.主服务接收到从服务的sync同步命令时,会fork一个子进程后台执行bg ...

  7. redis主从复制如何保证数据一致性_面试官:Redis 主从复制时网络开小差了怎么整?...

    上周因为实在太忙就认认真真写了一篇水文,吹了一下自己过去的经历,反响竟然超出了我的预期,并且后台还有读者留言表示想看续集的.哈哈,果然大家还是对水文更有热情. 这期我们继续回到之前的 Redis 话题 ...

  8. Redis主从复制的搭建与.哨兵.数据持久

    目录 一.redis主从复制 1.主从复制的概述 2.一主一从结构的配置 二.哨兵服务 1. 哨兵服务的简单介绍 2.配置哨兵服务 三.数据持久化 1.RedisDataBase(RDB) 2.App ...

  9. 深入Redis 主从复制原理

    复制原理 1.复制过程 复制的过程步骤如下: 1.从节点执行 slaveof 命令        2.从节点只是保存了 slaveof 命令中主节点的信息,并没有立即发起复制        3.从节点 ...

  10. [转载] 深入剖析 redis 主从复制

    转载自http://www.cnblogs.com/daoluanxiaozi/p/3724299.html 主从概述 redis 支持 master-slave(主从)模式,redis server ...

最新文章

  1. 数据智能是未来商业的核心竞争力之一
  2. python开发中遇到的难题_初学者在Python开发中常见的问题(上)
  3. php模板怎么导入服务器_php项目怎么放到服务器
  4. centos7.5 supervisor +nginx 开机启动设置(实测最有效)以及出现问题思路
  5. 剑指offer面试题25. 合并两个排序的链表(双指针)
  6. iOS UIDatePicker
  7. Java 战国大富翁,中国古代八大富翁,比皇帝还有钱!其中三位是历史上公认的商圣...
  8. java斐波黄金分割_斐波那契(黄金分割)
  9. ios 开发控件中心点_AppCan
  10. 东南亚电商龙头 shopee 社招,校招 内推(长期有效)
  11. css文字背景蒙版_使用CSS创建蒙版的背景效果
  12. shareX截图工具提示:shareX\Tools\ffmpeg.exe不存在。解决方案2020年
  13. seed lab 2020 packet sniffing and spoofing lab
  14. 二、谈谈对数据库中索引的理解
  15. 清单革命:如何持续、正确、安全地把事情做好
  16. idea中没有 program arguments 选项
  17. MySQL INSERT插入条件判断:如果不存在则插入
  18. java ee 物联网 论文_《物联网技术》-科技刊物-中国论文交流中心www.cnlwjl.com
  19. dnsmasq实现dns劫持
  20. 微信第三方授权登录之oauth开发

热门文章

  1. 120帧手机动态壁纸_移动串串烧:用视频制作手机的动态壁纸
  2. java定义一个盒子类box_定义一个Box(盒子)类,在该类定义中包括数据成员: length(长),width(宽)和height(...
  3. split() 方法用于把一个字符串分割成字符串数组
  4. 把前端图片存到数据库,再从数据库取出来显示
  5. word撰写论文秘籍:图表自动编号、公式自动编号、自动页眉、自动参考文献
  6. python动态库反初始化_解决TensorFlow的ImportError: DLL load failed: 动态链接库(DLL)初始化例程失败...
  7. 判断三角形的类型,是何种三角形(等腰,等边,直角)
  8. 在centos7.5中解压.tgz
  9. 初等模型之核军备竞赛
  10. 如何做好项目复盘 - 海星复盘图