1 哨兵
哨兵,sentinel,实现管理,监听功能的特殊redis进程.对主从结构实现的管理监听.
2 哨兵结构
对于一个主从结构已经搭建完成的集群(主从结构中没有分布式,只有一个数据分片,多个主从才能形成分布式),哨兵是额外的进程实现监听管理.
3 管理和监听的原理
哨兵启动时先连接主节点
调用info命令获取详细信息,从中拿到了从节点信息,从而在哨兵管理list中记录所有节点信息
每个1-3秒(默认1秒)给管理的所有主从节点发送心跳检测,从而判断该节点是存活还是宕机
对于宕机的处理
从节点宕机,哨兵只是做记录
主节点宕机,发起投票选举,在从节点中选举一个新的节点作为主节点继续提供功能(主从替换,故障转移)
外界客户端只要通过连接哨兵,就可以知道当前数据分片中谁才是正在提供服务的master
4 哨兵集群启动运行
服务器中配置了3个哨兵监听6382 6383 6384的一个一主二从的redis集群
redis根目录直接运行shell脚本
start-sentinel.sh
这是三个哨兵进程,同时监听一个主从结构,主从结构的名称 mymaster
初始化结构 6382是主节点master 6383 6384挂接的从节点.可以打开一个哨兵的进程日志
5观察日志,理解原理
动态查看日志的尾部信息tail
#tail -f /tmp/sentinel26379.log
启动高可用集群,发现主节点,同时获取从节点信息记录,其他2个哨兵也被发现.
测试从节点宕机
从节点宕机,哨兵通过心跳超时没有相应判断宕机,记录从节点宕机消息
测试主节点宕机
应该由哨兵来实现故障转移和主从替换.
首先有3个哨兵中一个哨兵发现宕机主节点,发起投票,只要投票过半判断主节点确实宕机.
发起投票选举,从主节点的从节点当中选举一个新的master顶替原来的主节点
6382宕机,6383宕机状态,只能选举6384作为新的主节点
还要继续执行逻辑,将6382 和6383记录为6384的从节点
哨兵拥有主从结构的所有决定权,拥有主从结构的所有详细信息.
6 哨兵集群分布式理论结构
7 使用代码连接哨兵集群实现客户端代码高可用
通过jedis连接哨兵集群,当主节点宕机之后,依然可以实现增删查改的操作.
//连接哨兵,实现对一个高可用redis集群操作的功能
@Test
public void test05(){
//代码将不再直接连接任意一个redis 6382 6383 6384 需要连接哨兵
//收集哨兵连接信息 26379 26380 26381
Set<String> infos=new HashSet<>();
infos.add(new HostAndPort("10.9.104.184",26379).toString());
infos.add(new HostAndPort("10.9.104.184",26380).toString());
infos.add(new HostAndPort("10.9.104.184",26381).toString());
//通过哨兵信息,封装一个哨兵连接池
//需要两个参数,一个哨兵集群可以管理多个主从,每个主从名字不同,这里需要指定
//哨兵管理的主从名称 mymaster
JedisSentinelPool pool=new JedisSentinelPool("mymaster",infos);
//从哨兵连接池中就能获取jedis连接对象 当前主节点,还能获取主从一些信息
System.out.println("当前主节点:"+pool.getCurrentHostMaster());
Jedis jedisMaster = pool.getResource();
jedisMaster.set("name","aldjflads");
System.out.println("读取name:"+jedisMaster.get("name"));
}
8 如果实现哨兵分布式有哪些问题
如果使用哨兵实现分布式会有如下难点:
分布式计算方法一致性hash 无法实现顶替后的单调性
一致性hash算法本身的问题,导致数据与节点分片对应关系行程强耦合