Redis主从高可用、集群实现

98 阅读5分钟

一、主从高可用模式

1、部署架构

sentinel是redis高可用解决方案,由一个或多个sentinel实例组成的sentinel系统。可以监视任意多个主服务器,以及这些主服务下属的从服务器。并在被监视的主服务器进入下线状态时,自动将下线的主服务器属下的某个从服务器升级为新的主服务器。

2、Sentinel中的元数据

3、健康检查

sentinel向master发送ping命令,当在down-after-period时间内没有得到有效回复则将自己元数据中的该master结构的flag字段标记为s_down

然后通过*sentinel字段向其他的sentinel节点发送is-master-down-by-addr命令查询该master加点的状态,如果收到半数以上的sentinel把该master标记为了s_down,则将该master更新为o_down。

4、选举领头的sentinel

当系统中的master被标记为o_down后需要进行故障转移,在故障转移之前需要选举出一个领头的sentinel来执行故障转移。

如果响应的leader_epoch、leader_runid和请求的一致则说明投票有效,如果某个sentinel得到半数以上的投票则被任命为领头的sentinel。如果在规定的时间内没有选举成功,所有sentinel则将更新config_epoch纪元进行下一轮次选举。

5、故障转移

从已故障的master节点的slave节点中选择一个执行slaveof no one命令升级为master。从节点过滤规则如下:

1.  删除列表中下线或者断线的从节点
2.  删除列表中最近5秒没有回复过领头sentinel info命令的从节点
3.  删除与主服务器断开时间超过down-after-milliseconds * 10毫秒的服务器
4.  优先选择slave_priority值小的节点
5.  如果仍有多个符合条件的从节点,则会选择slave_repl_offset大的节点
6.  如果仍有多个符合条件的从节点,则对运行id排序,选择运行id最小的服务器

当sentinel监测到下线的主节点上线时,sentinel会为其执行slaveof <new_master_host> <new_master_port>命令将其降级为从节点赋值新主节点数据。

二、redis数据持久化

redis支持RDB、AOF两种日志格式来回复数据库状态。

2.1、RDB持久化

RDB可以将Redis在内存中的的数据库状态保存在磁盘里面(是一个压缩的二进制文件),可以save、bgsave(推荐)命令进行手动生成,数据库本身也会自动生成RDB文件。如图所示:

2.2 AOF持久化

AOF持久化通过保存redis服务器执行的写命令来记录数据库的状态。AOF持久化开启后可以更好的降低Redis宕机丢失数据的风险。

为了避免redis写命令追加过多造成文件过大等问题,AOF会进行重写机制,可以通过bgrewriteaof手动重写aof,系统也会在合适的时间进行自动重写(没有BGSAVE、BGRewriteAOF在执行 且 aof文件大于默认1M 且 aof文件大小和最后一次重写aof大小的增长率超过默认的100%时 会触发自动重写)。

三、主从复制

从节点通过 slaveof 命令从主节点同步数据,如下图所示:

*注:主从服务器断开重新建立连接后,如果从服务器检查masterRunId变更或者master的复制缓冲区没有该偏移量则会执行全量同步流程。

四、分片集群

4.1 分片集群部署架构

分片集群中使用 cluster meet host port 命令将一个节点加入到当前集群,通过cluster replicate nodeid 复制指定节点数据。

4.2 节点元数据

当节点收到cluster meet命令并与目标节点建立连接后会更新当前节点的元数据,并通知集群中的其它节点与目标节点建立连接。

通过cluster addslots 0 1 2 ... 5000 进行槽指派,当16384个槽点分派完毕后节点才会处于上线状态。

4.3 命令的执行

当发送的Key计算到的slot不在目标节点时,clusterNode会返回moved错误告诉客户端转向正确的节点执行命令。当发送的Key计算到的slot正好在目标节点是,目标节点直接执行命令。

4.4 重新分片

redis重新分片可以将任意数量个已经指派的slots指派给另一个节点。重新分片命令:

redis-trib.rb reshard --from a8b3d0f9b12d63dab3b7337d602245d96dd55844 --to f413fb7e6460308b17cdb71442798e1341b56cbc  --slots 200 --yes --pipeline 20 host:port

host:port:必传参数,集群内任意节点地址,用来获取整个集群信息。
-–from:制定源节点的id,如果有多个源节点,使用逗号分隔,如果是all源节点变为集群内所有主节点,在迁移过程中提示用户输入。
-–to:需要迁移的目标节点的id,目标节点只能填写一个,在迁移过程中提示用户输入。
-–slots:需要迁移槽的总数量,在迁移过程中提示用户输入。
-–yes:当打印出reshard执行计划时,是否需要用户输入yes确认后再执行reshard。
–-pipeline:控制每次批量迁移键的数量,默认为10

slot数据迁移流程:

4.5 故障转移

  1. 当一个节点向其他节点发送ping消息未在指定时间内收到有效响应会被判定为 疑似下线
  2. 集群中互相发送消息交换各个节点状态信息,当半数以上负责slot处理的节点都判定为该节点疑似下线,会向集群广播该节点已下线
  1. 从故障节点的从节点中选举一个当主节点,从节点会要求其它具有处理slot能力的节点投票
  2. 获取半数以上票数的节点执行 slaveof no one 升级为主节点,将下线节点的slot全部指派给新主节点并通知集群。