Redis 核心技术与实战
蒋德钧
中科院计算所副研究员
81696 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 53 讲
开篇词 (1讲)
实践篇 (28讲)
Redis 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

06 | 数据同步:主从库如何实现数据一致?

repl_backlog_size
repl_backlog_buffer
主库发送新写命令给从库
主库同步数据给从库
建立连接、协商同步
写操作
读操作
服务尽量少中断
数据尽量少丢失
增量复制
长连接复制
全量复制
增量复制
Redis 2.8之前的处理方式
分担主库压力
三个阶段的同步
replicaof命令
读写分离
Redis的高可靠性含义
重新读入RDB文件
回放日志
每课一问
小结
网络断连后的解决办法
基于长连接的命令传播
主从级联模式
主从库间的第一次同步
主从库模式
服务不可用问题
AOF和RDB
数据同步:主从库如何实现数据一致?

该思维导图由 AI 生成,仅供参考

你好,我是蒋德钧。
前两节课,我们学习了 AOF 和 RDB,如果 Redis 发生了宕机,它们可以分别通过回放日志和重新读入 RDB 文件的方式恢复数据,从而保证尽量少丢失数据,提升可靠性。
不过,即使用了这两种方法,也依然存在服务不可用的问题。比如说,我们在实际使用时只运行了一个 Redis 实例,那么,如果这个实例宕机了,它在恢复期间,是无法服务新来的数据存取请求的。
那我们总说的 Redis 具有高可靠性,又是什么意思呢?其实,这里有两层含义:一是数据尽量少丢失,二是服务尽量少中断AOF 和 RDB 保证了前者,而对于后者,Redis 的做法就是增加副本冗余量,将一份数据同时保存在多个实例上。即使有一个实例出现了故障,需要过一段时间才能恢复,其他实例也可以对外提供服务,不会影响业务使用。
多实例保存同一份数据,听起来好像很不错,但是,我们必须要考虑一个问题:这么多副本,它们之间的数据如何保持一致呢?数据读写操作可以发给所有的实例吗?
实际上,Redis 提供了主从库模式,以保证数据副本的一致,主从库之间采用的是读写分离的方式。
读操作:主库、从库都可以接收;
写操作:首先到主库执行,然后,主库将写操作同步给从库。
Redis主从库和读写分离
那么,为什么要采用读写分离的方式呢?
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Redis主从库同步是确保数据一致性的重要机制,通过主从库模式实现高可靠性和读写分离。全量复制、基于长连接的命令传播和增量复制是主从库同步的三种模式。增量复制通过repl_backlog_buffer缓冲区实现主从库之间的同步,避免了网络断连时重新进行全量复制的开销。调整repl_backlog_size参数可以降低主从库数据不一致的风险,同时可以考虑使用切片集群来分担单个主库的请求压力。在实际应用中,建议将一个Redis实例的数据库大小控制在几GB级别,以减少全量复制的开销。此外,文章还提到了主从级联模式来缓解主库的压力。在保证数据一致性的同时,还需要关注主库故障后的解决方案,以确保服务的可靠性。文章提出了一个问题,探讨了为什么主从库间的复制不使用AOF。通过这些内容,读者可以快速了解Redis主从库同步的基本原理和技术特点。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Redis 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(203)

  • 最新
  • 精选
  • 健康创客小辉辉
    置顶
    涨知识了
    2022-06-24
    1
    1
  • Geek_121747
    置顶
    老师,我对repl_backlog_buffer有点疑问, 文中描述1:“因为 repl_backlog_buffer 是一个环形缓冲区,所以在缓冲区写满后,主库会继续写入,此时,就会覆盖掉之前写入的操作。如果从库的读取速度比较慢,就有可能导致从库还未读取的操作被主库新写的操作覆盖了,这会导致主从库间的数据不一致。” 文中描述2:我特别建议你留意一下 repl_backlog_size 这个配置参数。如果它配置得过小,在增量复制阶段,可能会导致从库的复制进度赶不上主库,进而导致从库重新进行全量复制。 我的疑问是,如果在网络断开期间,repl_backlog_size环形缓冲区写满之后,从库是会丢失掉那部分被覆盖掉的数据,还是直接进行全量复制呢?

    作者回复: 我看到还有几个同学在问类似的这个问题,大家都思考的很仔细,非常好! 对于这个问题来说,有两个关键点: 1. 一个从库如果和主库断连时间过长,造成它在主库repl_backlog_buffer的slave_repl_offset位置上的数据已经被覆盖掉了,此时从库和主库间将进行全量复制。 2. 每个从库会记录自己的slave_repl_offset,每个从库的复制进度也不一定相同。在和主库重连进行恢复时,从库会通过psync命令把自己记录的slave_repl_offset发给主库,主库会根据从库各自的复制进度,来决定这个从库可以进行增量复制,还是全量复制。

    2020-08-17
    30
    265
  • 不负青春不负己🤘
    我问个问题 psync 这个动作 执行 RDB 全量数据,是直接传输到从库上,还是先落到主redis 磁盘上

    作者回复: Redis在全量复制时,既支持先生成RDB文件,再把RDB文件传给从库,也支持在主库上直接通过socket把数据传给从库,这称为无盘复制。 如果运行主库的机器磁盘性能不太好,但是网络性能不错的话,可以考虑无盘复制。

    2020-08-18
    5
    52
  • Mr.蜜
    我有一个疑问,环形缓冲期再大,也会出问题,那么如果遇到这类问题,导致数据不同步怎么处理?比方说,一个从库长断网以后,长时间没有联网处理。

    作者回复: 没错,环形缓冲区再大,在某些时候,就如你所说的从库长期断网时,也会出问题。 其实从库正常情况下会每秒给主库发送一个replconf ack命令,主库会根据这个命令的达到时间判断和从库的连网情况。如果距离最后一次ack命令收到的时间已经超过了repl_timeout时间,就会和从库断开连接了。 从库再和主库连接时,会发送自己的复制进度,如果要复制内容在缓冲区中已经被覆盖了,那么就不再做增量复制了,而是进行全量复制。

    2020-08-17
    5
    40
  • 祝康力
    老师,主从库的复制,是异步的吗?那就保证不了强一制了,文章没有提及这一点

    作者回复: Redis主从库的复制是异步的,主库收到命令操作后,在本地执行完成后,就会返回给客户端,并不会等到和从库同步完成后才返回给客户端。 如果从库同步较慢的话,例如从库正在执行bigkey操作,那么复制进度就会落后,此时,从库数据不是强一致性保证。

    2020-08-18
    9
    37
  • 我不用网名
    看了课程内容,不看评论绝对是一种损失

    作者回复: 咱们评论区有不少同学的回复都很棒,思考问题非常仔细、周全和深入。 读评论区是一次非常好的再学习过程 :)

    2020-08-17
    2
    23
  • QFY
    课后题: aof记录的是命令,如果是首次主从全量复制,而且如果aof文件还没被重写会存在对一个key的反复操作,那么效率会比较低 疑问: 【repl_backlog_buffer 是一个环形缓冲区,主库会记录自己写到的位置,从库则会记录自己已经读到的位置】针对这一句,这个repl_backlog_buffer是在主库上面,但是他同时要记录master_repl_offset和slave_repl_offset,这个slave_repl_offset是每个从库记录一个还是共用一个?如果是共用一个,那如果有两个从库正在恢复,一个正常恢复把slave_repl_offset往前推了,另一个从库在恢复的过程中又断了,但是再恢复的时候slave_repl_offset已经往前推了,中间就有一部分数据丢失了,这个情况该怎么办了(这个情况可能有点极端)

    作者回复: 善于思考,非常棒! repl_backlog_buffer是所有从库共享的,不过正如文章中说的,slave_repl_offset是由从库自己记录的,这也是因为每个从库的复制进度不一定相同。 从库断连后再恢复时,会给主库发送psync命令,并把自己当前的slave_repl_offset发给主库。所以,在你所说的情况下,正常恢复的从库推进的slave_repl_offset是它自己记录的,不会影响到第二个从库。 第二个从库断连后再恢复,只要slave_repl_offset指向的数据没有被覆盖,就能继续恢复。 希望解答了你的问题 :)

    2020-08-17
    2
    22
  • Geek_33c084
    主从复制的流程:1.建立链接;2.rdb全量复制;2.网络长链接复制。 主-从-从的级联主从复制模式:减少主库的bgsave压力,减少网络传输的压力 断网重连:repl_backlog_size环形缓冲区,存在覆盖情况。主库还可以根据slave_repl_offset判断是全量复制,还是增量复制

    作者回复: 不错的总结!

    2020-08-18
    14
  • heyman
    老师,客户端写入数据只能从主库写入,读数据可以从主库或者从库读取。请问这个是怎么控制的?客户端要自己实现吗?客户端是怎么知道要往哪个节点写?

    作者回复: 这个需要客户端实现(例如Redisson客户端),或者在客户端和集群间增加一个proxy才行,由客户端或proxy先行判断是读操作还是写操作,再把读、写操作发给从库或主库

    2020-08-20
    3
    12
  • 等风来🎧
    如果并大量特别大,增量复制的时候,从库的消费的偏移量仍不在主库的环形缓存池中,应该会进行一次全量复制,这个老师好像没有提到

    作者回复: 咱们有同学问到了类似slave_repl_offset被覆盖的这个问题,你的回复就是答案。 :) 我在文章小结中有提到了一句“通过调大这个参数(repl_backlog_size),可以减少从库在网络断连时全量复制的风险”,这种情况就是因为repl_backlog被覆盖写了,导致从库开始全量复制。不过这句的确不明显,不容易让大家注意,都是我的错。。。

    2020-08-17
    10
收起评论
显示
设置
留言
99+
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部