Redis主从架构,Sentinel机制和Cluster分片原理
一、Redis主从复制
单台Redis缺点:
- 不能满足高可用,宕机数据丢失
- 支持的并发量有限
- 自身内存有限
主从架构
读写分离(主服务器负责写,从服务器负责读)
通过执行SALVEOF命令或者设置salveof选项,让一个服务器去复制(replicate)另一个服务器,被复制的服务器称为master,复制数据发服务器称为slave
复制的两个重要操作
1. 同步 将从服务器的数据库状态更新至主服务器的数据库状态
2. 命令传播 主服务器接收写请求,和从服务器状态不一致,需要重回一致状态
同步过程
初次同步
- 从服务器向主服务器发送PSYNC命令
- 收到PSYNC命令的主服务器执行BGSAVE命令,在后台生成一个RDB文件。并用一个缓冲区来记录从现在开始执行的所有写命令
- 当主服务器的BGSAVE命令执行完后,将生成的RDB文件发送给从服务器,从服务器接收和载入RDB文件。将自己的数据库状态更新至与主服务器执行BGSAVE命令时的状态
- 主服务器将所有缓冲区的写命令发送给从服务器,从服务器执行这些写命令,达到数据最终一致性
小知识
- BGSAVE命令: 用于在后台异步保存当前数据库的数据到磁盘
- slave 会先写入本地磁盘,然后再从本地磁盘加载到内存,在加载RDB过程中会对外不可用
- 初次同步时会全量复制master节点的所有数据
- master node 将 rdb 快照文件发送给 slave node,如果 rdb 复制时间超过 60秒(repl-timeout),那么 slave node 就会认为复制失败,可以适当调大这个参数
- master 在内存中直接创建
RDB
,然后发送给 slave,不会在自己本地落地磁盘了。只需要在配置文件中开启repl-diskless-sync yes
- slave 不会过期 key,只会等待 master 过期 key。如果 master 过期了一个 key,或者通过 LRU 淘汰了一个 key,那么会模拟一条 del 命令发送给 slave
断线同步
处于命令传播阶段的主从服务器因为网络原因中断了复制,从服务器通过自动重连重新连接主服务器,并继续复制主服务器。这种情况下,如果在断线期间,有写请求到主服务器,为了保持数据一致性,redis2.8以前采取还是进行全量复制,2.8以后使用增量复制
由于断线后重连只需要同步缺失的数据,Redis使用offset实现
执行复制的双方都会分别维护一个复制偏移量,主服务器每次传播N个字节,就将自己的复制偏移量加上N,从服务器每次收到主服务器的N个字节,就将自己的复制偏移量加上N,重连后对比偏移量,开启增量复制。
命令传播
当完成了同步之后,主从服务器就会进入命令传播阶段。这时主服务器只要将自己的写命令发送给从服务器,而从服务器接收并执行主服务器发送过来的写命令,就可以保证主从服务器一直保持数据一致
在命令传播阶段,从服务器默认会以每秒一次的频率,检测主从网络状态和发送当前复制的偏移量
二、哨兵机制
Redis在主从架构中,从节点宕机一般影响不大,主节点宕机,Redis就无法正常对外提供服务,这时候就需要启用Redis的哨兵机制(sentinel),进行主备切换
哨兵本身是特殊的Redis服务器,初始化不会加载RDB和AOF文件,它会与主从架构中所有节点保持网络连接,一旦主服务宕机,会自动选举从服务器成为主服务器,一般slave中的offset值较大即数据量较全的会成为master
数据丢失
主备切换数据丢失,在这个过程中,如果master宕机,这个阶段是不对外提供服务的,不会有数据进来,但是由于主从复制是异步的,复制过程中宕机,就会有部分数据丢失
脑裂会导致数据丢失。master和slave由于网络延迟,通信中断,sentinel会进行主备切换,此阶段client可能还会有部分写请求到master,选出新的master后,原master会被作为一个 slave 挂到新的 master 上去,清空自身的数据,导致部分数据丢失
三、Redis cluster分片
Redis Cluster是一种服务器Sharding技术,3.0版本开始正式提供。
Redis使用一致性hash算法进行分片,这里不深究,我的其它文章有介绍。
特点:
- 无中心架构,支持动态扩容
- 具备Sentinel的监控和自动切换能力
- 客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
- 高性能,客户端直连redis服务,不需要使用代理
Redis cluster和主从架构结合,如图:
各个节点之前互联,内部使用二进制协议优化传输速度和带宽。
Redis cluster有固定16384个slot,每次写入,会对key计算CRC16值,然后对16384求模,计算出应该存放slot位置,然后会找到对应的master节点。
假设有三主三从,那么slot在master划分:[0-5460],[5461-10922], [10923-16383],每个key都会找到属于自己的master节点,在master节点中进行主从复制
集群中某个master节点宕机,会进行主备切换,如果主从全部宕机,由于分片,只会影响相邻节点,引发数据迁移,迁移代价很小,而其它节点正常工作,不会因为缓存大面积失效造成缓存雪崩,造成数据库压力过大甚至宕机。
Cluster主备切换原理
主观宕机:一个节点(这里指的都是环上的master节点)认为某个节点失去连接
客观宕机:超过半数以上节点认为某个节点宕机,那么就是真正fail
选举策略
每个从节点,都根据自己对 master 复制数据的 offset,来设置一个选举时间,offset 越大(复制数据越多)的从节点,选举时间越靠前,优先进行选举,半数以上投票通过,该从节点可以切换成为master