前面我们讲解了Redis实现主从复制的一些基本操作,那么我们接着来看哨兵模式。
经过之前的学习,我们发现,实际上最关键的还是主节点,因为一旦主节点出现问题,那么整个主从系统将无法写入,因此,我们得想一个办法,处理一下主节点故障的情况。实际上我们可以参考之前的服务治理模式,比如Nacos和Eureka,所有的服务都会被实时监控,那么只要出现问题,肯定是可以及时发现的,并且能够采取响应的补救措施,这就是我们即将介绍的哨兵:
注意这里的哨兵不是我们之前学习SpringCloud Alibaba的那个,是专用于Redis的。哨兵会对所有的节点进行监控,如果发现主节点出现问题,那么会立即让从节点进行投票,选举一个新的主节点出来,这样就不会由于主节点的故障导致整个系统不可写(注意要实现这样的功能最小的系统必须是一主一从,再小的话就没有意义了)
那么怎么启动一个哨兵呢?我们只需要稍微修改一下配置文件即可,这里直接删除全部内容,添加:
sentinel monitor lbwnb 127.0.0.1 6001 1
其中第一个和第二个是固定,第三个是为监控对象名称,随意,后面就是主节点的相关信息,包括IP地址和端口,最后一个1我们暂时先不说,然后我们使用此配置文件启动服务器,可以看到启动后:
可以看到以哨兵模式启动后,会自动监控主节点,然后还会显示那些节点是作为从节点存在的。
现在我们直接把主节点关闭,看看会发生什么事情:
可以看到从节点还是正常的在报错,一开始的时候不会直接重新进行选举而是继续尝试重连(因为有可能只是网络小卡一下,没必要这么敏感),但是我们发现,经过一段时间之后,依然无法连接,哨兵输出了以下内容:
可以看到哨兵发现主节点已经有一段时间不可用了,那么就会开始进行重新选举,6003节点被选为了新的主节点,并且之前的主节点6001变成了新的主节点的从节点:
当我们再次启动6001时,会发现,它自动变成了6003的从节点,并且会将数据同步过来:
那么,这个选举规则是怎样的呢?是在所有的从节点中随机选取还是遵循某种规则呢?
replica-priority
配置项(默认是100),越小表示优先级越高。
要是哨兵也挂了咋办?没事,咱们可以多安排几个哨兵,只需要把哨兵的配置复制一下,然后修改端口,这样就可以同时启动多个哨兵了,我们启动3个哨兵(一主二从三哨兵),这里我们吧最后一个值改为2
:
sentinel monitor lbwnb 192.168.0.8 6001 2
这个值实际上代表的是当有几个哨兵认为主节点挂掉时,就判断主节点真的挂掉了
现在我们把6001节点挂掉,看看这三个哨兵会怎么样:
可以看到都显示将master切换为6002节点了。
那么,在哨兵重新选举新的主节点之后,我们Java中的Redis的客户端怎么感知到呢?我们来看看,首先还是导入依赖:
- <dependencies>
- <dependency>
- <groupId>redis.clientsgroupId>
- <artifactId>jedisartifactId>
- <version>4.2.1version>
- dependency>
- dependencies>
- public class Main {
- public static void main(String[] args) {
- //这里我们直接使用JedisSentinelPool来获取Master节点
- //需要把三个哨兵的地址都填入
- try (JedisSentinelPool pool = new JedisSentinelPool("lbwnb",
- new HashSet<>(Arrays.asList("192.168.0.8:26741", "192.168.0.8:26740", "192.168.0.8:26739")))) {
- Jedis jedis = pool.getResource(); //直接询问并得到Jedis对象,这就是连接的Master节点
- jedis.set("test", "114514"); //直接写入即可,实际上就是向Master节点写入
-
- Jedis jedis2 = pool.getResource(); //再次获取
- System.out.println(jedis2.get("test")); //读取操作
- } catch (Exception e) {
- e.printStackTrace();
- }
- }
- }
这样,Jedis对象就可以通过哨兵来获取,当Master节点更新后,也能得到最新的。