redis 高可用方案总结(上)

sanlanlan 2020-12-21 标签: redis 浏览:884 评论:0

redis 高可用方案总结

一.redis-sentinel

[sentinel 可以监控主从结构]

sentinel 哨兵 是redis 高可用性解决方案。
sentinel 实例组成的sentinel 系统 可以监视任意多个主服务器,以及主服务器下的所有从服务器

当主服务器下线时长超过用户设定的下线时长上限时,sentinel 系统就会对主服务器做故障转移:
 1.重新挑选新的主服务器
 2.sentinel 系统给所有新的从服务器发送复制命令,让他们成为新主服务器的从服务器
 3.继续监听已下线的主服务器,并在重新上线时,将它设置为新主服务器的从服务器



(1)启动,并初始化 sentinel

redis-server /path/sentinel.conf --sentinel
redis-sentinel /path/sentinel.conf

2个命令效果一样

当sentinel 启动时,需要的步骤:
    1.初始化服务器
     sentinel 本质是运行在特殊模式下的Redis服务器,所以启动第一步就是初始化一个普通的Redis服务器
     初始化sentinel 时不会载入RDB或者AOF 文件,因为它不需要使用数据库
    2.将普通的Redis代码替换成sentinel 专用代码
     比如:
     #define REDIS_SERVERPORT 6379
     sentinel 使用:#define REDIS_SEVTINEL_PORT 6379
    3.初始化sentinel 状态
     在应用了sentinel 代码后,会初始化sentinelState 结构,这个就是初始化状态
     这个结构保存了服务器中所有和sentinel 功能有关的状态
    4.根据给定的配置文件,初始化sentinel 的监视主服务器列表
     sentinel 的masters 字典记录所有被sentinel 监听的主服务器的相关信息
    5.创建连向主服务器的网络连接
     sentinel 会创建2个异步连接,一个命令连接,一个订阅连接


(2)获取主服务器信息
sentinel 会默认10s 一次,向被监视的主服务器发送INFO 命令,
主服务器返回2部分信息:主服务器信息,从服务器信息

(3)向主服务器和从服务器发送信息
sentinel 以2s 一次频率,通过命令连接向所有的被监视的主服务器和从服务器发送命令



3.检测在线状态
(1)主观下线[主服务器]
配置文件中的 down-after-milliseconds 选项指定了 sentinel 判断实例进入主观下线所需的时间长度
如果一个实例在 down-after-milliseconds 毫秒内,连续向sentinel 返回无效回复,那么表示这个实例主观下线

(2)客观下线[从服务器]
当被主服务器判定为主观下线后,sentinel 会向其他sentinel 询问是否也认为这个主服务器主观下线,
如果从其他的sentinel 接收足够多的数量判定已下线,就会将将从服务器判定为客观下线,并将主服务器做故障转移操作
quorum 参数设置了数量


4.选举领头sentinel

当一个主服务器被判断为客观下线后,监听这个下线服务器的各个sentinel 会进行协商,选举出一个领头sentinel,
并由领头sentinel 对下线主服务器执行故障转移操作:
(1)选举规则
 某个sentinel 被半数以上的sentinel设置成局部领头sentinel,那么这个就是领头sentinel
 如果在给定时间内,没有一个sentinel 被选举为领头sentinel,那么会再次执行,直到选举出来


5.故障转移
    3个步骤:
    (1)在已下线主服务器的从服务器中,挑选一个从服务器,并将其转换为主服务器
     向这个从服务器发送 SLAVEOF no one 命令,将从转成主
     选举规则:
         a.领头sentinel 根据从服务器优先级,排序,选优先级最高的
         b.优先级一样,按照从服务器的复制偏移量,选偏移量最大的
    (2)从服务器改为复制新的主服务器
    (3)继续监听已下线的主服务器,并在重新上线时,将它设置为新主服务器的从服务器



二.redis-cluster

[集群是做分片的,利用slot 分]

redis 集群是Redis提供的分布式数据库方案,集群通过分片(sharding)来进行数据库共享,并提供复制和故障转移功能

向一个节点node 发送cluster meet 命令,可以让node 节点与IP和port所指定的节点进行握手,握手成功,
node 就会将IP和port 所指定的节点添加到node节点当前所在的集群中。[cluster meet <ip> <port> ]

1.启动节点
Redis 服务器启动时会根据cluster-enabled 配置选项是否yes 来决定是否开启服务器集群模式
节点会使用redisServer 结构 保存服务器状态,使用RedisClient结构来保存客户端的状态

2.集群数据结构

clusterNode 结构保存节点当前状态
clusterLink 结构保存节点有关信息
clusterState 结构保存集群的状态,集群信息


3.cluster meet 命令实现
节点握手的过程
屏幕快照 2019-09-08 下午11.19.07.png
      

1.设置从节点
cluster replicate <node_id>

2.故障检测
集群中每个节点都会定期向集群中其他节点发送PING消息,以此来检测对方是否在线


3.故障转移
当一个从节点发现自己正在复制的主节点进入已下线状态,从节点就开始对下线主节点进行故障转移
(1)选举一个从节点作为新的主节点
 选举规则:投票方式,半数以上,规定时间内没选上,继续选,直到产生
(2)被选中的从节点执行 slaveof no one 命令,成为新的主节点
(3)新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己
(4)新的主节点会向集群广播一条PONG 命令,让集群知道它有从节点变成新的主节点
(5)新的主节点开始接收和负责处理槽相关的命令,故障转移完成


redis 3.2版本以后,官方支持使用 cluster 搭建集群,同时集群本身支持sentinel功能,
所以用cluster搭建集群不需要再搭建sentinel集群。

优点:
(1)无需Sentinel哨兵监控,如果Master挂了,Redis Cluster内部自动将Slave切换Master
(2)可以进行水平扩容

缺点:

(1)批量操作是个坑

(2)资源隔离性较差,容易出现相互影响的情况。


三.关于replication 复制
复制步骤:
 
(1)设置主服务器的地址和端口
     客户端向主服务器发送 slaveof ip port
(2)建立socket 连接
(3)发送PING 命令P213
     向主服务器发送PING 命令
     虽然建立起了socket 连接,但双方并未进行通信。发送ping 命令可以检查socket 的读写状态是否正常
     主服务器返回PONG,表示连接正常,否则会断开重连
(4)身份验证
     如果从服务器设置了masterauth选项,那么进行身份验证,没设置则不用。
     要验证的话,从相向主发一条AUTH命令,参数为从服务器masterauth选项的值
     主      从
     AUTH     10086
     127.0.0.1:6379<----------------127.0.0.1:12345

(5)发送端口信息
(6)同步
(7)命令传播


    
 配置文件: 在从服务器的配置文件中加入:slaveof <masterip> <masterport>
 启动命令: redis-server启动命令后加入 --slaveof <masterip> <masterport>
 客户端命令: Redis服务器启动后,直接通过客户端执行命令:slaveof <masterip>
 <masterport>,则该Redis实例成为从节点。

 slaveof no one //取消复制

 //配置方式
 slaveof 127.0.0.1 6379
 slave-read-only yes



四.关于Gossip协议

节点间通信,按照通信协议可以分为几种类型:单对单、广播、Gossip协议等。重点是广播和Gossip的对比。

广播是指向集群内所有节点发送消息;优点是集群的收敛速度快(集群收敛是指集群内所有节点获得的集群信息是一致的),缺点是每条消息都要发送给所有节点,CPU、带宽等消耗较大。

Gossip协议的特点是:在节点数量有限的网络中,每个节点都“随机”的与部分节点通信(并不是真正的随机,而是根据特定的规则选择通信的节点),经过一番杂乱无章的通信,每个节点的状态很快会达到一致。Gossip协议的优点有负载(比广播)低、去中心化、容错性高(因为通信有冗余)等;缺点主要是集群的收敛速度慢。

Redis 集群中各个节点通过Gossip 协议来交换各自关于不同节点的状态消息,其中Gossip 协议有MEET,PING,PONG 三种消息实现。

参考资料:
《Redis 设计与实现》
https://redis.io/topics/cluster-spec
https://redis.io/topics/cluster-tutorial

本文相关标签: redis

发表评论: