redis实战第五篇 jedis 连接 redis sentinel详解
jedis针对redis sentinel给出了一个JedisSentinelPool,jedis给出了很多的构造方法,其中比较全的是下面这个,注意:这个连接池争对的连接还是主节点:
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)
具体参数含义如下: masterName——主节点名。 sentinels——Sentinel节点集合。 poolConfig——common-pool连接池配置。 connectTimeout——连接超时。 soTimeout——读写超时。 password——主节点密码。(这个是主节点密码,而不是redis sentinel的密码) database——当前数据库索引 clientName——客户端名
但是通常我们会使用更简单的构造方法:
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName,sentinelSet, poolConfig, timeout, password);
此时timeout既代表连接超时又代表读写超时。
样例代码如下所示:
package com.gildata.duplicateandtagtest.redis;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;
/**
* Created by LiChao on 2019/2/11
*/
public class SentinelJedisPool {
private static JedisSentinelPool pool = null;
//可用连接实例的最大数目,默认为8;
//如果赋值为-1,则表示不限制,如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
private static Integer MAX_TOTAL = 1024;
//控制一个pool最多有多少个状态为idle(空闲)的jedis实例,默认值是8
private static Integer MAX_IDLE = 200;
//等待可用连接的最大时间,单位是毫秒,默认值为-1,表示永不超时。
//如果超过等待时间,则直接抛出JedisConnectionException
private static Integer MAX_WAIT_MILLIS = 10000;
//客户端超时时间配置
private static Integer TIMEOUT = 10000;
//在borrow(用)一个jedis实例时,是否提前进行validate(验证)操作;
//如果为true,则得到的jedis实例均是可用的
private static Boolean TEST_ON_BORROW = true;
//在空闲时检查有效性, 默认false
private static Boolean TEST_WHILE_IDLE = true;
//是否进行有效性检查
private static Boolean TEST_ON_RETURN = true;
/**
* 创建连接池
*/
private static void createJedisPool() {
JedisPoolConfig config = new JedisPoolConfig();
/*注意:
在高版本的jedis jar包,比如本版本2.9.0,JedisPoolConfig没有setMaxActive和setMaxWait属性了
这是因为高版本中官方废弃了此方法,用以下两个属性替换。
maxActive ==> maxTotal
maxWait==> maxWaitMillis
*/
config.setMaxTotal(MAX_TOTAL);
config.setMaxIdle(MAX_IDLE);
config.setMaxWaitMillis(MAX_WAIT_MILLIS);
config.setTestOnBorrow(TEST_ON_BORROW);
config.setTestWhileIdle(TEST_WHILE_IDLE);
config.setTestOnReturn(TEST_ON_RETURN);
String masterName = "mymaster";
Set<String> sentinels = new HashSet<String>();
sentinels.add(new HostAndPort("192.168.0.31",26379).toString());
sentinels.add(new HostAndPort("192.168.0.32",26379).toString());
sentinels.add(new HostAndPort("192.168.0.33",26379).toString());
String password = "1234@abcd";
pool = new JedisSentinelPool(masterName, sentinels, config, TIMEOUT,password);
}
private static synchronized void poolInit() {
if (pool == null)
createJedisPool();
}
/**
* 获取一个redis对象
* @return
*/
public static Jedis getJedis() {
if (pool == null)
poolInit();
return pool.getResource();
}
}
注意: 样例代码中的password是主节点的密码,而不是redis sentinel的密码,之前讲过redis sentinel也可以设置密码(传送门),如果使用jedis去连接的redis sentinel带有密码,那么会出现权限不足的问题,因为jedis预留的password参数时争对主节点的,所以如果主节点存在密码,切记在安装redis sentinel的时候不要给redis sentinel设置密码,否则jedis是连接不上的。
测试代码:
@Test
public void testSentinel(){
Jedis jedis = null;
try{
jedis = SentinelJedisPool.getJedis();
jedis.set("sentinel","hello sentinel");
}catch (Exception e){
e.printStackTrace();
} finally {
if(jedis!=null){
jedis.close();
}
}
}
执行日志可以看出,此时的主节点是192.168.0.33
16:15:37.121 [main] INFO redis.clients.jedis.JedisSentinelPool - Trying to find master from available Sentinels...
16:15:37.125 [main] DEBUG redis.clients.jedis.JedisSentinelPool - Connecting to Sentinel 192.168.0.31:26379
16:15:37.170 [main] DEBUG redis.clients.jedis.JedisSentinelPool - Found Redis master at 192.168.0.33:6380
16:15:37.171 [main] INFO redis.clients.jedis.JedisSentinelPool - Redis master running at 192.168.0.33:6380, starting Sentinel listeners...
16:15:37.261 [main] INFO redis.clients.jedis.JedisSentinelPool - Created JedisPool to master at 192.168.0.33:6380
hello sentinel
通过info sentinel查看主节点确实是192.168.0.33
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.33:6380,slaves=2,sentinels=3
手动切换主节点
127.0.0.1:26379> sentinel failover mymaster
OK
127.0.0.1:26379> info sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.0.31:6380,slaves=2,sentinels=3
此时主节点变为了192.168.0.31,再次执行测试用例,执行日志如下:
16:32:53.315 [main] INFO redis.clients.jedis.JedisSentinelPool - Trying to find master from available Sentinels...
16:32:53.320 [main] DEBUG redis.clients.jedis.JedisSentinelPool - Connecting to Sentinel 192.168.0.31:26379
16:32:53.369 [main] DEBUG redis.clients.jedis.JedisSentinelPool - Found Redis master at 192.168.0.31:6380
16:32:53.370 [main] INFO redis.clients.jedis.JedisSentinelPool - Redis master running at 192.168.0.31:6380, starting Sentinel listeners...
16:32:53.463 [main] INFO redis.clients.jedis.JedisSentinelPool - Created JedisPool to master at 192.168.0.31:6380
hello sentinel
主节点变为了192.168.0.31,这就是redis sentinel的好处,它能够主动通知应用程序主节点发生了变更,应用程序不需要做任何变化。
- Spring Cloud Bus整合RabbitMQ
- 结合Scikit-learn介绍几种常用的特征选择方法(下)
- Spring Cloud Bus之RabbitMQ初窥
- 结合Scikit-learn介绍几种常用的特征选择方法(上)
- 判断图片是否加载完成
- Spring Cloud Config客户端配置细节
- Spring Cloud Config服务端配置细节(二)之加密解密
- Redis3 cluster 集群配置测试
- Spring Cloud Config服务端配置细节(一)
- 分布式配置中心Spring Cloud Config初窥
- Git标签管理
- Docker容器如何共享数据
- Git工作区储藏兼谈分支管理中的一个小问题
- 轻量级容器Docker - 创建nginx容器
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 【适合收藏】为了多点时间陪女朋友,我向BAT大佬跪求了这15条JS技巧
- iOS文本尺寸自适应异步计算实现
- CentOS7下系统分析与排障利器sysdig简单介绍
- Faker 一个生成虚拟数据的Python模块
- ICLR 2020 Mogrifier LSTM 解析
- 优秀的程序员是如何利用工具来提升工作效率的?
- webpack实战——一切皆模块
- IntelljJ最新激活教程,有效期到 2089 年!
- 【从0到1学算法】二分查找法
- Spring事务源码分析专题(二)Mybatis的使用及跟Spring整合原理分析
- IIC
- JVM系列之:Contend注解和false-sharing
- FFmpeg 实现视频 封装 与 解封装
- 万物皆可状态机
- ggplot2折线图展示美国和印度COVID-19单日新增确诊人数变化趋势