哨兵

Redis的主从复制模式下, 一旦主节点由于故障不能提供服务, 需要人工将从节点晋升为主节点, 同时还要通知应用方更新主节点地址, 对于很多应用场景这种故障处理的方式是无法接受的。 Redis从2.8开始正式提供了Redis Sentinel( 哨兵) 架构来解决这个问题,

基本概念

Redis Sentinel是Redis的高可用实现方案, 在实际的生产环境中, 对提高整个系统的高可用性是非常有帮助的。

哨兵的功能包括两个,一是监控主数据库和从数据库是否正常运行,二是主数据库出现故障时自动将从数据库转换为主数据库.

主从复制的问题

Redis的主从复制模式可以将主节点的数据改变同步给从节点, 这样从节点就可以起到两个作用: 第一, 作为主节点的一个备份, 一旦主节点出了故障不可达的情况, 从节点可以作为后备“顶”上来, 并且保证数据尽量不丢失( 主从复制是最终一致性) 。 第二, 从节点可以扩展主节点的读能力, 一旦主节点不能支撑住大并发量的读操作, 从节点可以在一定程度上帮助主节点分担读压力。

但是主从复制也带来了以下问题

  • 一旦主节点出现故障,需要手动将一个从节点晋升为主节点,同时需要修改应用方的主节点地址, 还需要命令其他从节点去复制新的主节点, 整个过程都需要人工干预。(高可用问题)
  • 主节点的写能力受到单机的限制。(分布式问题)
  • 主节点的存储能力受到单机的限制。(分布式问题)
高可用

Redis主从复制模式下的主节点出现故障后, 故障转移过程如下所示。

1)主节点发生故障后,客户端连接主节点失败,两个从节点与主节点连接失败造成复制中断。

2)如果主节点无法正常启动, 需要选出一个从节点(slave-1),对其执行slaveof no one命令使其成为新的主节点。

3)原来的从节点( slave-1) 成为新的主节点后, 更新应用方的主节点信息, 重新启动应用方。

4)客户端命令另一个从节点( slave-2) 去复制新的主节点( new-master)

5)待原来的主节点恢复后, 让它去复制新的主节点。

上述处理过程就可以认为整个服务或者架构的设计不是高可用的, 因为整个故障转移的过程需要人介入.

Redis 哨兵的高可用性

当主节点出现故障时, Redis Sentinel能自动完成故障发现和故障转移,并通知应用方, 从而实现真正的高可用。

Redis Sentinel是一个分布式架构, 其中包含若干个Sentinel节点和Redis数据节点, 每个Sentinel节点会对数据节点和其余Sentinel节点进行监控, 当它发现节点不可达时, 会对节点做下线标识。 如果被标识的是主节点, 它还会和其他Sentinel节点进行“协商”, 当大多数Sentinel节点都认为主节点不可达时, 它们会选举出一个Sentinel节点来完成自动故障转移的工作, 同时会将这个变化实时通知给Redis应用方。 整个过程完全是自动的, 不需要人工来介入, 所以这套方案很有效地解决了Redis的高可用问题。

集群

Redis Cluster是Redis的分布式解决方案,在3.0版本正式推出,有效地解决了Redis分布式方面的需求。 当遇到单机内存、 并发、 流量等瓶颈时, 可以采用Cluster架构方案达到负载均衡的目的。

数据分布

数据分布理论

分布式数据库首先要解决把整个数据集按照分区规则映射到多个节点的问题, 即把数据集划分到多个节点上, 每个节点负责整体数据的一个子集。

常见的数据分区规则主要有哈希分区和顺序分区两种。Redis Cluster采用哈希分区规则.

常见哈希规则主要有

  • 节点取余分区

使用特定的数据, 如Redis的键或用户ID, 再根据节点数量N使用公式:hash( key) %N计算出哈希值, 用来决定数据映射到哪一个节点上。突出优点是简单性, 常用于数据库的分库分表规则。

  • 一致性哈希分区

一致性哈希分区( Distributed Hash Table) 实现思路是为系统中每个节点分配一个token, 范围一般在0~2^32, 这些token构成一个哈希环。 数据读写执行节点查找操作时, 先根据key计算hash值, 然后顺时针找到第一个大于等于该哈希值的token节点。

  • 虚拟槽分区

虚拟槽分区巧妙地使用了哈希空间, 使用分散度良好的哈希函数把所有数据映射到一个固定范围的整数集合中, 整数定义为槽( slot) 。 这个范围一般远远大于节点数, 比如Redis Cluster槽范围是0~16383。 槽是集群内数据管理和迁移的基本单位。 采用大范围槽的主要目的是为了方便数据拆分和集群扩展。 每个节点会负责一定数量的槽, 如下图所示。当前集群有5个节点, 每个节点平均大约负责3276个槽。 由于采用高质量的哈希算法, 每个槽所映射的数据通常比较均匀, 将数据平均划分到5个节点进行数据分区。 Redis Cluster就是采用虚拟槽分区, 下面就介绍Redis数据分区方法。

Redis Cluser采用虚拟槽分区, 所有的键根据哈希函数映射到0~16383整数槽内, 计算公式: slot=CRC16 (key) &16383。 每一个节点负责维护一部分槽以及槽所映射的键值数据.