Redis高可用方案

Redis高可用方案

Redis高可用方案

“高可用性”(High Availability)通常来描述一个系统经过专门的设计,从而减少停工时间,而保持其服务的高度可用性。

CAP的A AP模型

单机的Redis是无法保证高可用性的,当Redis服务器宕机后,即使在有持久化的机制下也无法保证不丢失数据。

所以我们采用Redis多机和集群的方式来保证Redis的高可用性。

单进程+单线程 + 多机 (集群)

主从复制

Redis支持主从复制功能,可以通过执行slaveof(Redis5以后改成replicaof)或者在配置文件中设置slaveof(Redis5以后改成replicaof)来开启复制功能

作用:

读写分离

一主多从,主从同步

主负责写,从负责读

提升Redis的性能和吞吐量

主从的数据一致性问题

数据容灾

从机是主机的备份

主机宕机,从机可读不可写

默认情况下主机宕机后,从机不可为主机

利用哨兵可以实现主从切换,做到高可用

哨兵模式

哨兵(sentinel)是Redis的高可用性(High Availability)的解决方案:

由一个或多个sentinel实例组成sentinel集群可以监视一个或多个主服务器和多个从服务器。

当主服务器进入下线状态时,sentinel可以将该主服务器下的某一从服务器升级为主服务器继续提供服务,从而保证redis的高可用性。

哨兵leader选举

Raft

Raft协议是用来解决分布式系统一致性问题的协议。

Raft协议描述的节点共有三种状态:Leader, Follower, Candidate。

term:Raft协议将时间切分为一个个的Term(任期),可以认为是一种“逻辑时间”。

集群与分区

分区是将数据分布在多个Redis实例(Redis主机)上,以至于每个实例只包含一部分数据。

分区的意义

性能的提升

单机Redis的网络I/O能力和计算资源是有限的,将请求分散到多台机器,充分利用多台机器的计算能力

网络带宽,有助于提高Redis总体的服务能力。

存储能力的横向扩展

即使Redis的服务能力能够满足应用需求,但是随着存储数据的增加,单台机器受限于机器本身的存储
容量,将数据分散到多台机器上存储使得Redis服务可以横向扩展。

分区的方式

范围分区

hash分区

  • 普通Hash
  • 一致性hash

官方cluster分区

在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断的情况,而且哨兵模式只有一个主节点对外提供服务,没法支持很高的并发,且单个主节点内存也不宜设置得过大,否则会导致持久化文件过大,影响数据恢复或主从同步的效率

Redis3.0之后,Redis集群不需要sentinel哨兵∙也能完成节点移除和故障转移的功能。需要将每个节点设置成集群模式,这种集群模式没有中心节点,可水平扩展,据官方文档称可以线性扩展到上万个节点(官方推荐不超过1000个节点)。redis集群的性能和高可用性均优于之前版本的哨兵模式,且集群配置非常简单

Redis官方提供了完整的集群解决方案。

方案采用去中心化的方式,包括:sharding(分区)、replication(复制)、failover(故障转移)。
称为RedisCluster。

Redis5.0前采用redis-trib进行集群的创建和管理,需要ruby支持

Redis5.0可以直接使用Redis-cli进行集群的创建和管理

RedisCluster的优势

高性能

Redis Cluster 的性能与单节点部署是同级别的。

多主节点、负载均衡、读写分离

高可用

Redis Cluster 支持标准的 主从复制配置来保障高可用和高可靠。

failover

Redis Cluster 也实现了一个类似 Raft 的共识方式,来保障整个集群的可用性。

易扩展

向 Redis Cluster 中添加新节点,或者移除节点,都是透明的,不需要停机。

水平、垂直方向都非常容易扩展。

数据分区,海量数据,数据存储

原生部署 Redis Cluster 不需要其他的代理或者工具,而且 Redis Cluster 和单机 Redis 几乎完全兼容。

容灾(failover)

故障检测

集群中的每个节点都会定期地(每秒)向集群中的其他节点发送PING消息如果在一定时间内(cluster-node-timeout),发送ping的节点A没有收到某节点B的pong回应,则A将B标识为pfail。

A在后续发送ping时,会带上B的pfail信息, 通知给其他节点。

如果B被标记为pfail的个数大于集群主节点个数的一半(N/2 + 1)时,B会被标记为fail,A向整个集群广播,该节点已经下线。其他节点收到广播,标记B为fail。

从节点选举raft,每个从节点,都根据自己对master复制数据的offset,来设置一个选举时间,offset越大(复制数据越多)的从节点,选举时间越靠前,优先进行选举。

slave 通过向其他master发送FAILVOER_AUTH_REQUEST 消息发起竞选,
master 收到后回复FAILOVER_AUTH_ACK 消息告知是否同意。

slave 发送FAILOVER_AUTH_REQUEST 前会将currentEpoch 自增,并将最新的Epoch 带入到
FAILOVER_AUTH_REQUEST 消息中,如果自己未投过票,则回复同意,否则回复拒绝。

所有的Master开始slave选举投票,给要进行选举的slave进行投票,如果大部分master node(N/2 +1)都投票给了某个从节点,那么选举通过,那个从节点可以切换成master。

RedisCluster失效的判定:

1、集群中半数以上的主节点都宕机(无法投票)

2、宕机的主节点的从节点也宕机了(slot槽分配不连续)

变更通知

当slave 收到过半的master 同意时,会成为新的master。此时会以最新的Epoch 通过PONG 消息广播自己成为master,让Cluster 的其他节点尽快的更新拓扑结构(node.conf)。