专栏首页洁癖是一只狗redis全量复制和部分复制

redis全量复制和部分复制

上一节我们看到了docker搭建集群,今天我们说一些集群数据同步原理

我们在第一次同步数据的时候,redis集群都是进行全量复制,由于全量复制的开销比较大,在2.8版本之后就提出了一种部分复制,我们先看一下全量复制的流程原理。

1.从节点使用命令psysn 参数是主节点runid 和 offset ,这里是第一次不知道主节点的信息,所以使用? 和-1 表示

2.主节点把自己的runid和offset告知从节点

3.从节点保存下来主节点信息 4.主节点bgsave,生成RDB文件

5.主节点把RDB文件同步给从节点

6.主节点在生成RDB文件的时候,同时也会把新来的命令,放到一个叫repl_back_buffer中,相当一个队列,存放新来的命令,保证数据不丢失,默认可以存储1M,最后会把这个buffer也会发给从节点

7.从节点此时也会清空本地数据

8.加载RDB文件和buffer数据,数据同步成功。 现在我们回顾一下上一节验证同步数据的操作是否和我们说的步骤一致。

1.主节点

127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> dbsize
(integer) 1

2.从节点

127.0.0.1:6379> get hello
"world"
127.0.0.1:6379> dbsize
(integer) 1

3.查看从节点日志

root@8469ebae122c:/data# cat redis.log
7:S 09 Oct 13:45:43.719 * Ready to accept connections  
7:S 09 Oct 13:45:43.719 * Connecting to MASTER master:6379  //连接主节点
7:S 09 Oct 13:45:43.719 * MASTER <-> SLAVE sync started  //开始同步数据
7:S 09 Oct 13:45:43.720 * Non blocking connect for SYNC fired the event.
7:S 09 Oct 13:45:43.720 * Master replied to PING, replication can continue... //主节点响应
7:S 09 Oct 13:45:43.721 * Partial resynchronization not possible (no cached master)
7:S 09 Oct 13:45:43.722 * Full resync from master: 1012f0b993083d3ac250a634997ce86827acd939:0 //全量复制
7:S 09 Oct 13:45:43.758 * MASTER <-> SLAVE sync: receiving 176 bytes from master //接受数据
7:S 09 Oct 13:45:43.758 * MASTER <-> SLAVE sync: Flushing old data  //清空从节点数据
7:S 09 Oct 13:45:43.759 * MASTER <-> SLAVE sync: Loading DB in memory //加载数据
7:S 09 Oct 13:45:43.759 * MASTER <-> SLAVE sync: Finished with success //同步成功

4.查看主节点日志

root@8469ebae122c:/data# cat redis.log
19:M 09 Oct 13:35:40.410 * Ready to accept connections  //连接
19:M 09 Oct 13:45:43.721 * Slave 172.17.0.3:6379 asks for synchronization 从节点请求同步数据
19:M 09 Oct 13:45:43.721 * Full resync requested by slave 172.17.0.3:6379 开始同步数据
19:M 09 Oct 13:45:43.721 * Starting BGSAVE for SYNC with target: disk //BGSAVE生成RDB
19:M 09 Oct 13:45:43.721 * Background saving started by pid 24
24:C 09 Oct 13:45:43.726 * DB saved on disk //保存RDB到磁盘
24:C 09 Oct 13:45:43.727 * RDB: 0 MB of memory used by copy-on-write
19:M 09 Oct 13:45:43.757 * Background saving terminated with success
19:M 09 Oct 13:45:43.758 * Synchronization with slave 172.17.0.3:6379 succeeded //同步到从节点数据成功

我们发现打印的日志基本和我们说的过程一致,但是往往全量复制的开销是非常大的,比如

  1. bgsave时间,FORK子进程也会消耗内存
  2. RDB文件网络传输时间
  3. 从节点清空数据,如果数据比较大,开销也会很大。
  4. 从节点接收RDB消耗的时间
  5. 可能的AOF重写,如果开启AOF.

因此我们在2.8版本引入可部分复制,当网络抖动的时候,数据不同步的时候,此时我们就可以使用部分复制,2.8版本之前都是全量复制。

  1. 网络抖动丢失网络
  2. 同时主节点还在把新的命令存放到buffer中,这个buffer相当是一个队列,默认是1M.
  3. 从节点连接主节点
  4. 从节点把自己的runid和offset 发给主节点,然后比较自己的offset是否在主节点buffer存储offset队列范围内,如果在就把从offset以后的数据同步给从节点,如果不在,说明已经丢失了太多数据,只能做全量复制了,我们可以根据业务适当的调整buffer的大小
  5. 主节点说继续
  6. 主节点把数据同步给从节点

集群故障

当集群发生故障的时候,我们怎么办,如何故障转移,如果可以自动转移还好,如果不能自动转移呢,故障转移怎么处理,一般发生故障都发生在晚上,做开发的很庆幸,你要是做运维的,晚上收到故障短信,你就苦逼了

我们看看经常出现的问题

  1. 从节点发生故障

如果上图右下角的salve宕机了我们可以把客户端连接到另外的一个从节点

只要再次重启一下服务就可以,如果只有一个服务使用redis其实还好,如果是十几个服务都要用,就会麻烦一点,并且要考虑的服务的可用性。

salve节点故障比较简单,master节点故障就比较麻烦

  1. 我们要使用客户端在从节点使用salveof no one(在右上角从节点执行),使从节点变成主节点
  2. 在另外一个从节点执行 salveof new master,连接新的主节点
  3. 同时也要迁移原从节点只读操作

我们看到非常简单,往往线上问题是很复杂的,导致运维人员手忙脚乱,你也可以做一个脚本进行操作,但是现在往往都是依赖自动故障转移,比如我们下节要说的sentinel,还有一些开源的图像界面进行自动故障转移。

主从复制问题

  1. 读写分离

读流量分摊到从节点,但是可能遇到问题

1.复制数据延迟:网络阻塞,从节点不能及时同步数据

2.读到过期数据:往往redis有两种方式淘汰过期数据,一种是懒惰操作,当使用时候才会判断是否过期,返回客户端为空,另外一种随机抽选淘汰过 . 期数据,由于从节点是不允许删除数据的,当过期数据量远大于淘汰的速 度,就可能读取到脏数据

3.从节点故障:成本是很高的。

规避全量复制

全量复制的开销非常大,产生全量复制的条件

1.第一次全量复制是不可避免的,我们可以到夜间操作或者设置maxmemory(指定Redis最大内存限制,Redis在启动时会把数据加载到内存中,达到最大内存后,Redis会先尝试清除已到期或即将到期的Key)可以让存储的数据小,网路传输RDB以及fork子进程更快

2.当主节点重启,节点运行id就会不一致,就会发生全量复制,但是在4.0版本做了升级,也会使用部分复制,或者直接让从节点升级为主节点

上面我们也说过部分复制的时候,如果从节点的offset 大于缓冲buffer存储的,就会发生全量复制,这说明当我们适当的调大(rel_backlog_size)buffer的大小,可以有效的避免全量复制。

规避复制风暴

1.单主节点复制风暴

主节点重启,有多个从节点要进行全量复制,生成RDB,传输RDB,虽然redis有自己的优化策略,但是这样开销还是非常大的,我们可以更换复制拓扑

上面右图就可以有效的避免大量复制,但是他是有自己的问题,比如第二层的slave宕机,我们要怎么处理,这都是我们考虑的,这些都要结合你的业务场景来调整

2.单机器复制风暴

当下面machine-A机器宕机,我们所有的主节点都要重启,也会产生大量的同步。

我们就可以实现多机器部署主节点,也可以把从节点升级为主节点,避免大面积复制。

本文分享自微信公众号 - 洁癖是一只狗(rookie-dog),作者:洁癖汪

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • redis数据分布

    我们知道redis官方说他是可以支持10万/每秒的并发量,但是如果我们的业务场景需要100万/每秒呢?

    小土豆Yuki
  • 高可用篇之Heartbeat(Heartbeat+HAProxy搭建高可用负载均衡集群)

    上一篇我们介绍了keepalived, 以及使用keepalived+haproxy搭建高可用负载均衡集群。那么今天我们介绍另外一种实现高可用的开源软件hear...

    小土豆Yuki
  • 面试Mybatis之代理模式

    由于上一节我们使用了Mybatis的插件(如果忘记了可以看一下历史文章Mybatis拦截器那一节),他是基于代理模式实现的,因此我们在这一节,讲一下代理模式的原...

    小土豆Yuki
  • 基于关系型数据库的App Inventor网络应用(3)

    第三节 初识Node-RED 开发环境简介 如图8所示,整个浏览器窗口被划分为四个部分: (1) 顶部黑色通栏,左侧显示Node-RED的LOGO,右侧显著位置...

    企鹅号小编
  • 带着问题学习分布式系统之中心化复制集

    假若我说有三个节点(计算机)要维护同一分数据,如果你对分布式系统并不了解,那么你可能会有什么问题呢,我想可能有两个最基本的问题:   为什么同一份数据要保存多...

    用户1263954
  • 【Java】基础篇-排序二叉树

    大家好,最近更新的稍微慢了许多,参加了一些公司和外界的技术培训,也跟一些小伙伴聊了些技术文章,总的来说很不理想,讲的内容高大上,落地的过程踩坑很严重,和没听的效...

    haoming1100
  • 我画了 20 张图,给女朋友讲清楚红黑树

    红黑树是一种常见的自平衡二叉查找树,常用于关联数组、字典,在各种语言的底层实现中被广泛应用,Java 的 TreeMap 和 TreeSet 就是基于红黑树实现...

    五分钟学算法
  • Jenkins+Gogs(git仓库)系列8:节点概述和遇到过的坑提前讲解

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

    MyJie
  • Gephi实战,从零开始

    Gephi 是一款网络分析领域的数据可视化处理软件,开发者对它寄予的希望是:成为 “数据可视化领域的Photoshop” ,可运行在Windows,Linux及...

    咻咻ing
  • 整理得吐血了,二叉树、红黑树、B&B+树超齐全,快速搞定数据结构

    没有必要过度关注本文中二叉树的增删改导致的结构改变,规则操作什么的了解一下就好,看不下去就跳过,本文过多的XX树操作图片纯粹是为了作为规则记录,该文章主要目的是...

    Java程序猿阿谷

扫码关注云+社区

领取腾讯云代金券