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

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

被折叠的 条评论
为什么被折叠?



