Redis集群方案

最开始 redis 是单机的,如果部署 redis 的服务器出现问题,那么整个 redis 服务都会不可用(单点问题)。在一些对可用性要求比较高的场景,工程师们开始研究如何实现 redis 高可用,即实现 redis 集群部署。

reids 官方目前支持主从模式、哨兵模式和 Redis-Cluster,第三方也有类似 Codis 等中间件,来实现这一目标。


redis 主从模式

主从模式比较好理解,就是在有了一台 redis 主机的基础上,再搭一个 redis 从机(从机可以有多个)。客户端写请求会跟主机交互,主机写入完成后,异步地将数据刷到从机。当然,为了降低主机的压力,从机也可以承担一部分读请求。主从模式实现了读写分离。但并不具备自动容错和恢复功能,当主机或从机某一台宕机,需要人工干预,将从机设置为主机,这期间可能导致数据不一致的问题。


redis 哨兵模式

Redis 2.8 开始,官方提供了哨兵工具来实现自动化的系统监控和故障恢复功能。哨兵工具的作用:

  1. 监控主机和从机否正常运行
  2. 当主机出现故障时自动将从机转换为主机(主从切换)

哨兵模式实现了自动恢复,但当redis容量达到瓶颈事,不方便在线扩容。


Redis-Cluster

Redis-Cluster 是 redis 官方推出的集群方案。简而言之,Redis-Cluster 集成了主从和哨兵的功能,并支持在线扩容。假设我们有 3 台服务器,在上面分别部署 Redis-Cluster,每台服务器我们称之为一个节点(node),客户端发过来的 key 会被分配到不同的节点上去。

分片

具体的方案是:将整个 Redis Cluster 集群分为 16384 个 哈希槽(hash slots),每个节点会承担一部分槽的存储,客户端 key 通过 CRC16 算法计算出要落到哪个槽。例如:

  • 节点 A 承担 0 到 5500.
  • 节点 B 承担 5501 到 11000.
  • 节点 C 承担 11001 到 16383.

当需要扩容时,只需要往集群中加入一个 节点D,只需要将 A、B、C 的一部分 hash slots 分给 D 即可。删减节点也是类似。

主从

为了实现高可用,除了 3 台主服务器,我们还需要 3 台从服务器,形成一个 3主3从 的架构,分别为主节点 A、B、C 和 从节点 A1、B1、C1。 当主节点 B 挂掉了, B1 可以顶上继续提供服务。 A 和 A1、 B 和 B1、 C 和 C1 持有相同的数据。

一致性保证

按官方的说法,Redis-Cluster 不保证强一致性。在一定的条件下,可能会造成写丢失,因为 主节点到从节点的复制是异步的 ,例如,当主节点B写入成功并给客户端返回成功标志,但还未复制到从节点B1时,主节点B宕机了,此时从节点B1提升为主节点,但却不持有刚刚写入的那份数据。当然,Redis-Cluster也支持主从复制改成同步,但依然可能存在写丢失,尽管概率很低。

多 key 操作

Redis-Cluster 对多 key 操作的支持十分有限,仅支持同一哈希槽的多 key 操作。官方给出的方案是,假如你要对某一类的 key 进行 多 key 操作,可以通过 Hash tags 标签将这类 key 都打到某个固定的槽上去。但是在实际生产环境中,这个方案可能带来数据倾斜的问题,即某一个槽的 key 非常多。


Codis

Codis 是由豌豆荚团队开发并开源的一个 redis 中间件。跟 mycat 类似,它隐藏了背后的众多 redis 机器,在客户端看来,它跟一个单实例 redis 没有区别。但它承担了将 key 分发到背后真正的 redis 机器上去的功能,来达到横向扩展的目的。


参考: