vlambda博客
学习文章列表

聊聊 Redis 主从同步

今天接着来聊一聊 Redis 里的主从同步。

在持久化里我们讲到,通过开启AOFRDB能保证 Redis 宕机后数据不会丢失。但随着系统业务量不断的增长,单机的存储日益紧张时,更加高可用的 Redis 变得越加重要,而本文就「主从同步」这个话题展开一些讨论。

1.主从同步

「主从同步」是 Redis 高可用的基础。因为 Redis 分片集群也基于此。而 Redis 的高可用方案可分为两种

  • 主从同步集群
  • 分片集群

「主从同步」又是解决什么问题的呢?可以从这么两个方面来思考

  • 单节点就无从谈起是否高可用了
  • 单节点读写压力大,如果能进行读写分离,能大大提高读的能力

先来看一下主从同步的架构图在主从同步里,角色会被划分为masterslavemaster对外提供写,并将写的数据同步给slave节点,而slave则对外提供只读。那他们之间数据又是怎么交互的呢?可分为两步

  • 同步
    • 用于将 master节点状态复制给 slave,即 「全量复制」
  • 命令传播
    • 主要用于同步后, master发生了写操作导致与 slave状态不一致,即 「增量复制」

2.同步

我们来看下同步的流程

  • slave节点一开始启动后向 master节点发送 「sync」命令
  • master收到 「sync」命令后会执行 bgsave命令,同时 fork一个进程来生成 RDB文件。同时会将同步期间发生的 「写操作」记录到缓冲区中
  • 生成完后, master会把 RDB文件发送给 slave,而 slave接收后会将其载入,而这期间 slave是不对外提供服务的
  • 而后 master将记录在缓冲区中的所有 「写操作」发送给 slave,而 slave收到后对其进行重放,以此来达到数据的一致

按照上面的流程来看,顺利的话,一点问题也没有。但如果slave在同步完后挂掉了(或是其他原因)恢复过来后,又会怎么样呢?这个问题根据 Redis 版本不同而不同

  • 2.8 之前
    • 会在进行一遍上面的流程
  • 2.8 之后
    • 使用了 「psync」命令来代替 「sync」命令

3.命令传播

实现「psync」的关键在于主从双方需要共同维护一个offset偏移量。offset可类比「kafka,rocketmq」里的offset。当master节点向slave发送数据时,须带上offset,而slave接收到数据后,也必须更新自己的offset。当slave出现异常中断又恢复过来后,再次连接master时,就可以根据offset来同步挂掉这段时间产生的数据,从而又能达到一致了。按照这个说法,slava挂多少次都是没有关系了?那当然不是了,这取决于slave挂了多久,以及这个offset对应的写操作指令是否还在,这是何意呀?我们需要思考下怎么通过offset找到写操作命令?

我们来看下命令传播的流程

  • 写命令发送给 slave的同时,还会将写命令发送到复制积压缓冲区中,同时与 offset做关联
  • 但是缓冲区大小有限,如果 slave挂了很久,复制积压缓冲区内的指令会不断在变化,如果找不到对应的 offset,将会触发全量同步
  • 如果是 master挂了,在主从同步中, master实例会生成一个唯一的 「runid」(重新后生成新的),而 slave连上 master后,在每次交互中都会带上 「runid」。 master会根据接收到的 「runid」来比对,一致则执行增量同步,不一致则执行全量同步

3.总结

综上,我们可以发现,保证 Redis 的高可用非常重要,而每次触发全量的临界值基本上都跟服务的高可用有关系。好的一面是通过主从同步后,对外能提供非常强力的读能力,但由于写是单点,压力会比较大。而一旦出现主节点挂掉,我们怎么来快速的切换呢?下一篇文章将会来分享下如何使用哨兵模式来管理主从同步集群。

本篇分享先到这里,欢迎关注。

如有收获,点个在看,诚挚感谢