Redis有三种集群模式,分别是主从模式、哨兵集群、分片集群
主从模式上文已经讲过了,这篇文章记录一下哨兵模式和分片模式
一、哨兵集群
哨兵其实也是一个redis节点,但是是多台redis节点组成的一个集群,一般情况下都要部署三台哨兵
哨兵(sentinel)机制主要实现的是主从集群的自动故障回复。哨兵的结构和作用如下:

1、哨兵的作用:
1、**监控:**监控Redis集群的主节点和从节点是否正常
2、自动故障恢复:如果一个主节点故障,哨兵会将一个从节点升级为主节点,当故障恢复后,也会以新的主节点(原来的从节点为主)
3、**通知:**哨兵会充当Redis的服务发现来源,当集群发生故障时,会将最新的信息推送给Redis的客户端,也就是将新的主节点告诉客户端,因为老的主节点已经写不了数据了。
2、哨兵是怎么实现的

哨兵(Sentinel)基于心跳机制监测服务状态,每隔1秒向集群的每个实例发送ping命令,如果收到响应pong则说明节点状态正常,如果收不到节点响应则认为异常
主观下线:就是某一个哨兵节点发现一个Redis节点异常,则认为该节点主观下线
客观下线:当超过半数的哨兵都主观认为该Redis节点异常,那么则认为该节点客观下线;
3、哨兵选主节点规则
如果是主节点异常,那么就会选举新的从节点成为主节点
选主规则如下:
1、首先判断主从节点断开时间的长短,如果超过太长时间的(这个时间在配置文件中设置),则排除这个从节点成为主节点的可能
为什么呢?因为断开时间越长,说明主节点和这个从节点差异的数据越多,自然是要选差异小的从节点
2、然后判断从节点的slave-priority(优先级)的值,越小优先级越高,也是通过配置文件配置的
3、如果每个从节点的slave-priority(优先级)一样,那么就判断从节点的offset值(偏移量,上一片文章有解释),越大说明上一次主从同步的时间越靠后,说明该从节点数据越全
4、最后是判断从节点点的运行id大小,越小优先级越高,相当于根据名称排序了;
4、哨兵模式的脑裂问题

如图所示,
集群脑裂是由于主节点、从节点、哨兵三者,处于不同的网络分区,而如果出现网络问题,使得哨兵没有能够心跳感知到主节点,所以选举了一个从节点为主节点,这样就存在了两个主节点,就像大脑分裂了一样
这样会导致客户端还在老的主节点那里写入数据,新节点无法同步数据,当网络恢复后,哨兵会将老的主节点降为从节点,这时再重新主从同步数据(会把原来老主节点的数据清空),这样原来老主节点,尚未同步到老从节点的数据就会丢失
解决:我们可以修改Redis的配置,可以设置最少的从节点数量以及缩短主从数据同步的延迟时间,达不到要求就拒绝请求,就可以避免大量的数据丢失
mix-replicas-to-write 1
表示最少的从节点数为1个,拒绝没有从节点的Master节点写入数据,这样那个单独的主节点就不能写入数据了,后面降为从节点,也不会有多余的数据
min-replicas-max-lag 5
表示数据复制和同步的延迟不能超过5秒,减少大量数据丢失的可能
二、分片集群
主从模式可以解决高并发读的问题,哨兵模式解决高可用的问题 ,但是还有两个问题没有解决**:**
海量数据存储问题
你进行主从同步,主节点和从节点都保存了完整的数据,这样无法保存大量的数据
高并发写的问题
主从模式和哨兵模式,都只有一台主节点,如果写入Redis的压力太大,一台主节点无法承受
1、分片集群的特征

分片集群有以下特征:
1 、集群中有多个Master主节点,每个Master保存不同数据
海量数据解决:一台Master主节点保存10G的数据,那么三台Master主节点就可以保存30G了
高并发写解决:一台Master主节点写入能力有限,那么三台同时可以承受写的压力,抗压能力大大增加
2、每个Master节点有各自的从节点
有各自的从节点,又解决了高并发读的问题
3、Master之间通过ping监测彼此的健康状态,替代哨兵
这样的话,Master节点通过心跳监测,监控别的Master,也就起到了哨兵的作用,就不需要额外部署哨兵了
2、分片集群如何读写
上面我们说到,redis分片集群,是部署多台Master主节点,以及他们各自的slave从节点;不同的Master保存不同的数据,那么当写入、读取的请求进来时,redis怎么知道这条数据该向哪个Master及其从节点进行读取呢?

解决:
redis分片集群引入了哈希槽的概念,Redis集群有16384个哈希槽,平均分给每个Master节点;
当读写请求进来时,每个key通过CRC16算法hash取得hash值后,再对16384取模来决定放在哪个槽(Master节点)
我上一家公司使用的就是分片集群的模式,三主三从,你通过redis-cli命令获取key时,不止会返回给你这个value,还会显示这个key存在哪个节点