Redis之Sentinel应用及源码分析

本文深入探讨了Redis Sentinel的工作机制,包括如何通过Sentinel集群找到并监控主节点,以及在主节点故障转移时如何自动更新客户端连接。通过源码分析,详细解释了JedisSentinelPool如何初始化和维护连接池,以及MasterListener如何监听Sentinel的发布订阅消息,确保客户端始终连接到正确的主节点。

Jedis 有4 种工作模式:单节点、分片(Sharded)、哨兵(Sentinel)、集群(Cluster)。上一篇我们通过实际应用的例子进行了源码剖析,本文将通过实际的例子对Redis的Sentinel进行源码剖析。

分片(Sharded)、集群(Cluster)请参考:

Redis之Sharded应用及源码分析

Redis之Cluster应用及源码分析

1、环境:

对于Redis Sentinel的搭建请参考一篇学会Redis Sentinel的集群搭建

1、操作系统:Centos7.7

2、服务器配置如下:(本文采用了在单台机子上部署多个实例来模拟多机部署)

主机 ip 角色和端口
master 132.232.125.196 6380
slave1 132.232.125.196 6381
slave2 132.232.125.196 6382
Sentinel 132.232.125.196 16380
Sentinel 132.232.125.196 16381
Sentinel 132.232.125.196 16382

2、启动redis和Sentinel服务

[root@m logs]# ps -ef|grep redis
root     13037     1  0 18:07 ?        00:00:00 /usr/local/soft/redis-5.0.8/src/redis-server *:6380
root     13042     1  0 18:07 ?        00:00:00 /usr/local/soft/redis-5.0.8/src/redis-server *:6381
root     13049     1  0 18:07 ?        00:00:00 /usr/local/soft/redis-5.0.8/src/redis-server *:6382
root     13942     1  0 18:07 ?        00:00:00 /usr/local/soft/redis-5.0.8/src/redis-sentinel *:16380 [`sentinel`]
root     13947     1  0 18:07 ?        00:00:00 /usr/local/soft/redis-5.0.8/src/redis-sentinel *:16381 [`sentinel`]
root     13952     1  0 18:07 ?        00:00:00 /usr/local/soft/redis-5.0.8/src/redis-sentinel *:16382 [`sentinel`]
root     14019   937  0 18:07 ?        00:00:00 [redis-server] <defunct>
root     14021 21486  0 18:07 pts/1    00:00:00 grep --color=auto redis

3、测试代码

package nci.henry;

import org.junit.Before;
import org.junit.Test;
import redis.clients.jedis.JedisSentinelPool;

import java.util.HashSet;
import java.util.Set;

/**
 * @Author: henry
 * @Date: 2020/4/18 15:43
 * @Description: 测试Sentinel
 */
public class JedisSentinelTest {
   
   


    private JedisSentinelPool pool;

    @Before
    public void initJedis(){
   
   
        // master的名字是sentinel.conf配置文件里面的名称
        String masterName = "mymaster";
        Set<String> sentinels = new HashSet<String>();
        sentinels.add("132.232.115.96:16380");
        sentinels.add("132.232.115.96:16381");
        sentinels.add("132.232.115.96:16382");
        pool = new JedisSentinelPool(masterName, sentinels);
    }

    @Test
    public void testGet(){
   
   
        try {
   
   
            pool.getResource().set("henry", "time:" + new Date());
            System.out.println(pool.getResource().get("henry"));
        } catch (Exception e) {
   
   
            e.printStackTrace();
        }
    }
}

执行 testGet()方法,结果如下:

time:Sat Apr 18 18:32:27 CST 2020

疑问

Jedis 连接Sentinel 的时候,我们配置的是全部哨兵的地址。Sentinel 是如何返回可用的master 地址的呢?下面我们通过分析源码,看一下Sentinel 具体实现方式。

4、源码分析

4.1 原理

1)、客户端连接到哨兵集群后,通过发送Protocol.SENTINEL_GET_MASTER_ADDR_BY_NAME命令;

2)、从哨兵机器中询问master节点的信息,拿到master节点的ip端口号以后,再到客户端发起连接。

3)、建立连接以后,需要在客户端建立监听机制,当master重新选举之后,客户端需要重新连接到新的master节点。

4.2 JedisSentinelPool构造方法

pool = new JedisSentinelPool(masterName, sentinels);

先来看下JedisSentinelPool的构造方法:

public JedisSentinelPool(String masterName, Set<String> sentinels,
      final GenericObjectPoolConfig poolConfig, final int connectionTimeout, final int soTimeout,
      final String password, final int database, final String clientName,
      final int sentinelConnectionTimeout, final int sentinelSoTimeout, 
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值