聊聊 Redis 主从同步
❝今天接着来聊一聊 Redis 里的主从同步。
❞
在持久化里我们讲到,通过开启AOF
、RDB
能保证 Redis 宕机后数据不会丢失。但随着系统业务量不断的增长,单机的存储日益紧张时,更加高可用的 Redis 变得越加重要,而本文就「主从同步」这个话题展开一些讨论。
1.主从同步
「主从同步」是 Redis 高可用的基础。因为 Redis 分片集群也基于此。而 Redis 的高可用方案可分为两种
-
主从同步集群 -
分片集群
那「主从同步」又是解决什么问题的呢?可以从这么两个方面来思考
-
单节点就无从谈起是否高可用了 -
单节点读写压力大,如果能进行读写分离,能大大提高读的能力
先来看一下主从同步的架构图在主从同步里,角色会被划分为master
、slave
。master
对外提供写,并将写的数据同步给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 的高可用非常重要,而每次触发全量的临界值基本上都跟服务的高可用有关系。好的一面是通过主从同步后,对外能提供非常强力的读能力,但由于写是单点,压力会比较大。而一旦出现主节点挂掉,我们怎么来快速的切换呢?下一篇文章将会来分享下如何使用哨兵模式来管理主从同步集群。
❝本篇分享先到这里,欢迎关注。
❞