Redis之Sentinel应用及源码分析

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

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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, 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值