前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redis学习笔记(四)主从数据同步

redis学习笔记(四)主从数据同步

作者头像
虞大大
发布2021-01-03 15:10:59
1.1K0
发布2021-01-03 15:10:59
举报
文章被收录于专栏:码云大作战

在redis恢复数据时我们可以依赖于aof日志或rdb日志,但是redis在运行中该如何保证服务的可靠性,就需要依赖redis主从和哨兵集群。

这一篇主要学习下如何通过redis的主从设计来保证服务的高可用。主从模式的思想就在于增加从副本,将一份数据同时保存在主从多个实例上,这样即使有一个实例出现了故障,其他实例也可以继续对外提供服务,不会影响业务的使用。

一、redis主从模式的读写分离

redis通过多实例来保存数据,为了保证redis实例数据的一致性,因此在主从模式下,主从之间采用的是读写分离的方式。

读操作:主、从实例都可以接收命令操作读请求。

写操作:只有主可以执行,主执行完毕后将写操作同步给从库。

以上的方式来解决多实例的一致性,也是比较方便简单的。因为如果主从实例都可以接受写请求,并且假设对同一个key修改了多次,并且每次都是请求到不同的主从实例上,那么最直观的结果可能出现数据不一致的情况。

如果需要强制保持数据一致,那么肯定需要涉及到锁的开销,阻塞住其他读写请求。

因此有了主从模式的读写分离,写命令就只会在主实例中修改,客户端就不用关心从实例,这条写命令会由主实例异步同步给从库。

二、主从模式的第一次数据同步

主从之间通过slaveof命令来将执行该命令的实例变为从库。

比如,有实例1(172.168.19.1)和实例2(172.168.19.2),在实例2中执行命令 - slaveof 172.168.19.1 6379。

接下来,实例2就变成了实例1的从库,然后会从实例1中复制数据。

· 第一次同步数据时的步骤

(1)主从建立连接,准备进行全量复制。从库发送psync请求告诉主库,要开始同步数据,主库确认回复后,主从库开始同步数据。

(2)主库将所有数据同步给从库,从库收到数据后在本地完成数据加载。在加载主库的数据主要是通过主库的rdb快照文件来直接加载数据,并且在加载前会先清空当前从库中的数据。

(3)主从同步期间新的请求处理,主库会在内存中生成一个缓冲区(replication buffer)来记录主从同步期间的新的写操作。

(4)从库获取主库发送过来的replicatio buffer缓冲区,开始执行新的写请求,同步数据。

以上就是主从第一次同步数据时的过程。第一次同步数据主要依赖于主库的rdb日志文件,后续的数据同步主要依赖于replication buffer缓冲区。

同步数据流程图如下所示:

以上就是第一次主从同步数据的总体流程,在图中我们可看到主实例接受到psync请求后,会进行FULLRESYNC响应,该响应传递了两个参数:

{runID}:主库的唯一标记。

{offset}:复制进度,如果是-1表示第一次复制。

replication buffer注意点:

主实例会为每一个从实例都分配一个复制缓冲区,并不是所有的从实例共用一个缓冲区。

缓冲区的设置需要合理,因为这是一个复制缓冲区所以毕竟会有大小限制,复制缓冲区如果一旦因为写入的命令过多导致溢出,那么主实例会直接关闭和从实例的连接,导致主从同步失败。

出现复制缓冲区溢出情况,可能在于全量复制时,从库中加载主库的rdb文件较慢,同时主节点接收了大量的写命令,导致写命令积累大小超过了缓冲区大小出现溢出。

解决方案:

(1)控制主节点数据的大小,一般将主节点的数据量控制在2~4GB即可,可以让从节点加载全量的rdb文件时执行的快些。

(2)合理设置复制缓冲区大小,命令 - config set client-output-buffer-limit slave 512mb 128mb 60

第一个参数512mb表示缓冲区大小的上限为512mb。

第二个、第三个参数128mb和60表示如果连续60秒内的写入量超过128mb也会造成缓冲区溢出。

可以根据以上命令来推断负载情况,来合理设置缓冲区大小。比如上述命令(假设每条命令大小是1kb):

复制缓冲区可以接受512mb / 1kb * 1000 = 512K条写命令。

可接受的写命令速率上限为128mb / 1kb * 1000 / 60s = 2000条/s。

(3)避免出现规模太大的从节点集群。因为主节点上复制缓冲区的总内存开销 = 所有从节点的缓冲区内存之和,从而减少主节点的使用内存。

三、主从从模式的数据同步

为什么需要主从从模式?我们先来分析下,主从集群下会有什么性能瓶颈。

对于一个主从库来说,需要完成两个耗时操作,生成rdb文件和传输rdb文件。虽然rdb文件是异步生成的,但是还是得通过主线程来fork一个子进程来异步创建rdb文件,但是fork这个步骤会阻塞主线程,如果从实例很多的情况下,并每个从结点都需要进行全量复制,那么这个fork就会变的很慢了。

传输rdb文件在于主实例传输文件到从实例也会占用主库的网络带宽给主库资源带来压力。

所以使用了主从从模式来减少从实例过多带给主实例的影响。

主从从模式的工作图:

将部分从库和其中一个从库建立主从关系,并且那个从库会和主库建立主从关系。这样全量复制时的压力就会被分担到那个有级联主从关系的从库中,减少了主库的压力。

四、增量复制缓冲区

redis引入增量复制缓冲区的概念还是在2.8之前,因为之前如果redis出现了主从之间的网络闪断,那么恢复后,从库需要重新进行一遍全量复制来进行主从同步,增大开销。

有了增量复制缓冲区之后,如果主从之间检测到网络闪断,从库恢复后就通过增量复制缓冲区来找到未同步的位置,来继续同步闪断期间内的数据。

· repl_backlog_buffer

repl_backlog_buffer即增量复制缓冲区,他其实是一个环形的缓冲区,所以会有2个指针分别是主库写的位置和从库读的位置,还有一个偏移量,代表从库还有多少数据没用读取完毕。

刚开始主库写的位置和从库读的位置在同一位置,随着写命令的请求,主库写的位置就会不断变大。每个从库通过从库的读位置来判断从库闪断前的位置,最终从库在后续恢复后复制完写操作命令后,他在缓冲区中的读的位置应该与主库写的位置相等。

如果出现从库闪断前的位置的数据被新一轮写入的数据覆盖 即环形缓冲区被主库的写命令所覆盖了,那么在从库恢复后还是得重新做一次全量的数据主从同步。

我们通常可以适当调大一些repl_backlog_size的参数。

repl_backlog_size = 缓存空间大小 * 2。

缓存空间大小 = 主库写入命令 * 操作大小 - 主从库网络传输命令速度 * 操作大小。

比如,主库每秒写入2000个操作,每个操作大小为1KB,网络每秒能传输1000个操作,那么缓存空间大小 = 2000 * 1 - 1000 * 1 = 1000kb = 1mb。

所以为了应对突发的情况,需要设置repl_backlog_size 为2mb。

· 网络闪断恢复时主从数据同步工作流程

主从库恢复后,从库首先会给主库发送psync命令,并把自己当前的salve_repl_offset(从库在增量复制缓冲区读的位置)发给主库,主库会判断master_repl_offset(主库在增量复制缓冲区写的位置)和salve_repl_offset之间的偏移量,然后把他们之间的命令操作通过复制缓冲区同步给从库。

五、总结

本文主要分析了redis在运行期间通过主从模式来保证高可用。而使用主从模式进行读写分离的好处:避免了加锁的开销。

为了实现redis的高可用性,就会有多个redis实例,为了保证实例数据的最终一致性,主从数据同步中我们需要关心两个缓冲区。

(1)replication buffer:主实例和从实例数据同步时的复制缓冲区。

(2)repl_backlog_buffer:从库断开之后,找到主从差异数据的环形缓冲区(增量复制缓冲区),减少主从闪断恢复时全量恢复数据的开销。

不过单单的采用主从模式来保证高可用还是有很多弊端的,比如主实例故障的情况,因此redis的高可用性还需要哨兵集群来帮助,哨兵机制会在下一篇来进行分析。

问题一:那么主从库间的复制为什么不使用aof文件

假设要使用aof做全量同步,意味着必须打开aof功能,就要选择aof刷盘策略,选择不当会严重影响redis性能,而rdb只有在需要同步时才会触发一次快照,对于一些redis数据不敏感的读缓存模式的业务,其实不需要那么依赖aof。

所以在主从间复制使用aof文件,主要原因在于从库恢复数据特别快,时间成本最低。

另外aof日志文件记录的是每一次写操作的命令,写操作很多文件就会很大。而rdb文件内容是经过压缩的二进制文件数据,文件很小,这也是aof文件在网络传输时候的一个优势。

问题二:replication buffer和repl_backlog_buffer的区别

replication buffer是用在主从之间发送数据时或全量同步数据时的缓冲区,并且每个从库都会生成一个复制缓冲区。

repl_backlog_buffer是用来持续保持写操作的一块缓冲区,多个从库共享一个增量缓冲区,在主库启动后就会创建出来。不同的从库增量复制进度通过从库读取的指针和主库写的指针来控制。

当出现主从闪断,恢复后恢复数据时,如果出现从库需要恢复的历史数据在增量复制缓冲区中已经被覆盖(因为是增量复制缓冲区是环形缓冲区),那么就需要重新进行全量复制。

参考资料 - 《Redis核心技术与实战》(数据同步:主从库如何实现数据一致)

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码云大作战 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis®
腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档