Redis 的高可用需要根据它的部署模式来看看,主要分为「主从模式」和「Cluster 分片模式」两种。

1. 主从模式

主从模式的架构如下:

redis 主从 java客户端 redis主从模式_数据


主从模式即一主多从(一个或者多个从节点),其中主节点主要负责读和写,然后会将数据同步到多个从节点上,Client 也可以对多个从节点发起读请求,这样可以减轻主节点的压力,但和 ZK 一样,由于只有一个主节点,存在单点隐患,所以必须引入第三方仲裁者的机制来判定主节点是否宕机以及在判定主节点宕机后快速选出某个从节点来充当主节点的角色,这个第三方仲裁者在 Redis 中我们一般称其为「哨兵」(sentinel),当然哨兵进程本身也有可能挂掉,所以为了安全起见,需要部署多个哨兵(即哨兵集群)。

redis 主从 java客户端 redis主从模式_数据_02


这些哨兵通过 gossip(流言) 协议来接收关于主服务器是否下线的信息,并在判定主节点宕机后使用 Raft 协议来选举出新的主节点。

Gossip 的中文意思就是流言蜚语,该协议就像流言蜚语一样,利用一种随机、带有传染性的方式,将信息传播到整个网络中,并在一定时间内,使得系统内的所有节点数据一致。这个就是实现了最终一致性的协议。
Gossip 主要有三大功能,直接邮寄、反熵、谣言传播

2.Cluster 集群模式

主从模式存在以下几个问题:

  • 主节点写的压力难以降低:因为只有一个主节点能接收写请求,如果在高并发的情况下,写请求如果很高的话可能会把主节点的网卡打满,造成主节点对外无法服务
  • 主节点的存储能力受到单机存储容量的限制:因为不管是主节点还是从节点,存储的都是全量缓存数据,那么随着业务量的增长,缓存数据很可能直线上升,直到达到存储瓶颈
  • 同步风暴:因为数据都是从 master 同步到 slave 的,如果有多个从节点的话,master 节点的压力会很大

为了解决主从模式的以上问题,分片集群应运而生,所谓分片集群即将数据分片,每一个分片数据由相应的主节点负责读写,这样的话就有多个主节点来分担写的压力,并且每个节点只存储部分数据,也就解决了单机存储瓶颈的问题,但需要注意的是每个主节点都存在单点问题,所以需要针对每个主节点做高可用,整体架构如下:

redis 主从 java客户端 redis主从模式_Redis_03


其原理大概就是:在 Proxy 收到 client 执行的 redis 的读写命令后,首先会对 key 进行计算得出一个值,如果这个值落在相应 master 负责的数值范围(一般将每个数字称为槽,Redis 一共有 16384 个槽)之内,那就把这条 redis 命令发给对应的 master 去执行,可以看到每个 master 节点只负责处理一部分的 redis 数据,同时为了避免每个 master 的单点问题,也为其配备了多个从节点以组成集群,当主节点宕机时,集群会通过 Raft 算法来从从节点中选举出一个主节点。

Redis 集群没有使用一致性hash, 而是引入了哈希槽的概念。
Redis 集群中内置了 16384 个哈希槽,当需要在 Redis 集群中放置一个 key-value时,redis 先对 key 使用 crc16 算法算出一个结果,然后把结果对 16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,redis 会根据节点数量大致均等的将哈希槽映射到不同的节点。

3.高可用设计

redis 主从 java客户端 redis主从模式_redis_04