集群的演进:

1.主从

一个主多个从, 当主节点 出现问题,需要人工切换到从

缺点:1 需要人工切换,无法实时监控切换; 2. 主节点故障会导致数据丢失无法恢复  3.主从内存的内容都是一样,降低可用性

优点:1, 主从可以实现读写分离,降低主节点压力 2. 当多个从的时候可以实现从从复制,只需要有一个从节点连接主节点做同步

2.哨兵模式

master宕机,哨兵会自动选举master并将其他的slave指向新的master。在主从模式下,redis同时提供了哨兵命令redis-sentinel,哨兵是一个独立的进程,作为进程,它会独立运行。其原理是哨兵进程向所有的redis机器发送命令,等待Redis服务器响应,从而监控运行的多个Redis实例。 哨兵也可以做集群

  2.1 哨兵模式的工作 

1 每个Sentinel(哨兵)进程以每秒钟一次的频率向整个集群中的Master主服务器,Slave从服务器以及其他Sentinel(哨兵)进程发送一个 PING 命令。

2 如果一个实例(instance)距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被 Sentinel(哨兵)进程标记为主观下线(SDOWN)

3 如果一个Master主服务器被标记为主观下线(SDOWN),则正在监视这个Master主服务器的所有 Sentinel(哨兵)进程要以每秒一次的频率确认Master主服务器的确进入了主观下线状态

4 当有足够数量的 Sentinel(哨兵)进程(大于等于配置文件指定的值)在指定的时间范围内确认Master主服务器进入了主观下线状态(SDOWN), 则Master主服务器会被标记为客观下线(ODOWN)

在一般情况下, 每个 Sentinel(哨兵)进程会以每 10 秒一次的频率向集群中的所有Master主服务器、Slave从服务器发送 INFO 命令。

5 当Master主服务器被 Sentinel(哨兵)进程标记为客观下线(ODOWN)时,Sentinel(哨兵)进程向下线的 Master主服务器的所有 Slave从服务器发送 INFO 命令的频率会从 10 秒一次改为每秒一次。

若没有足够数量的 Sentinel(哨兵)进程同意 Master主服务器下线, Master主服务器的客观下线状态就会被移除。若 Master主服务器重新向 Sentinel(哨兵)进程发送 PING 命令返回有效回复,Master主服务器的主观下线状态就会被移除。

优点

  • 哨兵模式是基于主从模式的,所有主从的优点,哨兵模式都具有。
  • 主从可以自动切换,系统更健壮,可用性更高。

缺点

  • 具有主从模式的缺点,每台机器上的数据是一样的,内存的可用性较低。
  • Redis较难支持在线扩容,在集群容量达到上限时在线扩容会变得很复杂。

3 集群模式

Redis的集群模式本身没有使用一致性hash算法,而是使用slots插槽

Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在redis3.0上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,对数据进行分片,也就是说每台 Redis 节点上存储不同的内容

运行机制:

在 Redis 的每一个节点上,都有这么两个东西,一个是插槽(slot),它的的取值范围是:0-16383,可以从上面redis-trib.rb执行的结果看到这16383个slot在三个master上的分布。还有一个就是cluster,可以理解为是一个集群管理的插件,类似的哨兵。

当我们的存取的 Key到达的时候,Redis 会根据 crc16的算法对计算后得出一个结果,然后把结果和16384 求余数,这样每个 key 都会对应一个编号在 0-16383 之间的哈希槽,通过这个值,去找到对应的插槽所对应的节点,然后直接自动跳转到这个对应的节点上进行存取操作。

当数据写入到对应的master节点后,这个数据会同步给这个master对应的所有slave节点。

为了保证高可用,redis-cluster集群引入了主从模式,一个主节点对应一个或者多个从节点。当其它主节点ping主节点master 1时,如果半数以上的主节点与master 1通信超时,那么认为master 1宕机了,就会启用master 1的从节点slave 1,将slave 1变成主节点继续提供服务。(必须有3个主节点,这样才能保证一个主节点挂了,剩下两个主节点能以超过半数以上的同意,推荐奇数个主节点)

如果master 1和它的从节点slave 1都宕机了,整个集群就会进入fail状态,因为集群的slot映射不完整。如果集群超过半数以上的master挂掉,无论是否有slave,集群都会进入fail状态。

redis-cluster采用去中心化的思想,没有中心节点的说法,客户端与Redis节点直连,不需要中间代理层,客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

集群模式的优缺点

优点

采用去中心化思想,数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布;可扩展性:可线性扩展到 1000 多个节点,节点可动态添加或删除;

高可用性:部分节点不可用时,集群仍可用。通过增加 Slave 做 standby 数据副本,能够实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave 到 Master 的角色提升;

降低运维成本,提高系统的扩展性和可用性。

缺点

1.Redis Cluster是无中心节点的集群架构,依靠Goss协议(谣言传播)协同自动化修复集群的状态

但 GosSIp有消息延时和消息冗余的问题,在集群节点数量过多的时候,节点之间需要不断进行 PING/PANG通讯,不必须要的流量占用了大量的网络资源。虽然Reds4.0对此进行了优化,但这个问题仍然存在。

2.数据迁移问题

Redis Cluster可以进行节点的动态扩容缩容,这一过程,在目前实现中,还处于半自动状态,需要人工介入。在扩缩容的时候,需要进行数据迁移。

而 Redis为了保证迁移的一致性,迁移所有操作都是同步操作,执行迁移时,两端的 Redis均会进入时长不等的阻塞状态,对于小Key,该时间可以忽略不计,但如果一旦Key的内存使用过大,严重的时候会接触发集群内的故障转移,造成不必要的切换。

总结

主从模式:master节点挂掉后,需要手动指定新的master,可用性不高,基本不用。

哨兵模式:master节点挂掉后,哨兵进程会主动选举新的master,可用性高,但是每个节点存储的数据是一样的,浪费内存空间。数据量不是很多,集群规模不是很大,需要自动容错容灾的时候使用。

集群模式:数据量比较大,QPS要求较高的时候使用。 Redis Cluster是Redis 3.0以后才正式推出,时间较晚,目前能证明在大规模生产环境下成功的案例还不是很多,需要时间检验。

集群会出现的一些问题:

1. 网络抖动:
   1.在集群中,网络抖动指主节点在短时间内连接不上,会出现选举新的主节点。如果一会马上又恢复了然后又出现网络抖动,这样会产生频繁的选举切换。设置一 个可以合适的time-out 时间,可以防止频繁切换。

  2.主节点一定不能设置宕机马上重启,一般情况下,集群实现读写分离,主节点是不做备份,只负责写,当宕机马上重启就主节点中没人任何内容,然而同步到子节点,就会把子节点的内容都删除了。 所以宕机后,就让集群先选出主节点,再尝试启动原先宕机的主节点。

2.  数据倾斜/访问倾斜

特别是针对cluster 集群模式会出现数据倾斜问题

数据倾斜的原因:

1. 存在bigkey

- 业务层避免bigkey

- 将集合类型的bigkey拆分为多个小集合

2. slot手工分配不均 (每个redis slave分配槽数量不平均)

3. hashtag 导致数据分配到同一个slot

- 避免使用hashtag

访问倾斜的原因:

1. 存在热点数据

- 如果是只读数据,可以使用多副本 key+随机值使数据分配到不同的实例中 或者存储在二级缓存 比如jvm缓存中

- 如果是读写数据, 增加实例配置