
Spring Boot连接Redis哨兵集群的原理如下:
1 Spring Boot使用Jedis客户端连接Redis哨兵集群。Jedis是一个Java Redis客户端,它支持连接Redis哨兵集群。
2 Jedis客户端会向Redis哨兵集群发送SENTINEL get-master-addr-by-name命令,获取当前Redis主节点的IP地址和端口号。
3 Jedis客户端会使用获取到的IP地址和端口号连接Redis主节点,并发送PING命令测试连接是否正常。
4 如果连接正常,Jedis客户端会将连接信息保存在连接池中,以便后续使用。
5 如果连接失败,Jedis客户端会向Redis哨兵集群发送SENTINEL get-master-addr-by-name命令,获取新的Redis主节点的IP地址和端口号,然后重复步骤2-4。
6 如果Redis主节点发生故障,Redis哨兵会自动将从节点升级为主节点,并通知Jedis客户端更新连接信息。
总之,Spring Boot连接Redis哨兵集群的原理是通过Jedis客户端向Redis哨兵集群发送命令获取当前Redis主节点的IP地址和端口号,然后使用获取到的信息连接Redis主节点。如果连接失败,Jedis客户端会重新获取新的Redis主节点的IP地址和端口号,直到连接成功为止。如果Redis主节点发生故障,Redis哨兵会自动将从节点升级为主节点,并通知Jedis客户端更新连接信息。
从机的redis命令行输入slaveofnoone转换为主机,然后要么修改主机ip要么修改java程序中的主机ip地址。
另外建议看下redis sentinel 主从切换(failover)解决方案
预备
jedis-252
commons-pool2-22jar
使用单连接
此方式仅建议用于开发环境做调试用。
// 创建连接
String host = "19216856102";
int port = 6379;
Jedis client = new Jedis(host, port);
// 执行set指令
String result = clientset("key-string", "Hello, Redis!");
Systemoutprintln( Stringformat("set指令执行结果:%s", result) );
// 执行get指令
String value = clientget("key-string");
Systemoutprintln( Stringformat("get指令执行结果:%s", value) );
运行上述代码,控制台输出:
set指令执行结果:OK
get指令执行结果:Hello, Redis!
使用连接池
此方式适用于仅使用单个Redis实例的场景。
// 生成连接池配置信息
JedisPoolConfig config = new JedisPoolConfig();
configsetMaxIdle(10);
configsetMaxTotal(30);
configsetMaxWaitMillis(31000);
// 在应用初始化的时候生成连接池
JedisPool pool = new JedisPool(config, "19216856102", 6379);
// 在业务 *** 作时,从连接池获取连接
Jedis client = poolgetResource();
try {
// 执行指令
String result = clientset("key-string", "Hello, Redis!");
Systemoutprintln( Stringformat("set指令执行结果:%s", result) );
String value = clientget("key-string");
Systemoutprintln( Stringformat("get指令执行结果:%s", value) );
} catch (Exception e) {
// TODO: handle exception
} finally {
// 业务 *** 作完成,将连接返回给连接池
if (null != client) {
poolreturnResource(client);
}
} // end of try block
// 应用关闭时,释放连接池资源
pooldestroy();
运行上述代码,控制台输出:
set指令执行结果:OK
get指令执行结果:Hello, Redis!
使用连接池+分布式
在规模较大的系统中,往往会有多个Redis实例做负载均衡。并且还实现主从备份,当主实例发生故障时,切换至从实例提供服务。
类似于Memcached的客户端,Jedis也提供了客户端分布式 *** 作的方式,采用一致性哈希算法。
// 生成多机连接信息列表
List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
shardsadd( new JedisShardInfo("127001", 6379) );
shardsadd( new JedisShardInfo("19216856102", 6379) );
// 生成连接池配置信息
JedisPoolConfig config = new JedisPoolConfig();
configsetMaxIdle(10);
configsetMaxTotal(30);
configsetMaxWaitMillis(31000);
// 在应用初始化的时候生成连接池
ShardedJedisPool pool = new ShardedJedisPool(config, shards);
// 在业务 *** 作时,从连接池获取连接
ShardedJedis client = poolgetResource();
try {
// 执行指令
String result = clientset("key-string", "Hello, Redis!");
Systemoutprintln( Stringformat("set指令执行结果:%s", result) );
String value = clientget("key-string");
Systemoutprintln( Stringformat("get指令执行结果:%s", value) );
} catch (Exception e) {
// TODO: handle exception
} finally {
// 业务 *** 作完成,将连接返回给连接池
if (null != client) {
poolreturnResource(client);
}
} // end of try block
// 应用关闭时,释放连接池资源
pooldestroy();
运行上述代码,控制台输出:
set指令执行结果:OK
get指令执行结果:Hello, Redis!
JedisCluster是针对RedisCluster的java客户端,它封装了java访问redis集群的各种 *** 作,包括初始化连接、请求重定向等。我们先来看下JedisCluster的类结构:
JedisCluster初始化时,所有的集群连接信息都是封装在JedisClusterInfoCache里,由于jedis本身不是线程安全的,所以使用对象池JedisPool来保证线程安全,在JedisClusterInfoCache中,除了要保存节点和槽的一一对应关系,还要为每个节点建立一个对象池JedisPool,并保存在map。这个类主要用于保存集群的配置信息,并且是JedisCluster初始化部分的核心所在。JedisClusterConnectionHandler是cache类的一个窗口,cache类似数据管理层,而Handler就类似于 *** 控数据提供服务的Service层。
从上图可以看出,Jedis建立集群的过程很清晰,传入节点信息,通过其中一个节点从redis服务器拿到整个集群的信息,包括槽位对应关系,主从节点的信息,将这些信息保存在JedisClusterInfoCache中。
在发送请求时,JedisCluster对象先从初始化得到的集群map中获取key对应的节点连接,即一个可用的Jedis对象。然后通过这个对象发送get key 命令。
通常,根据key计算槽位得到的节点不会报错。所以如果发生connectionException,或者MovedDataException,说明初始化得到的槽位与节点的对应关系有问题,即与实际的对应关系不符,应当重置map。 如果出现ASK异常,说明数据正在迁移,需要临时使用返回消息指定的地址,重新发送命令。在这里,Jedis通过异常反馈,智能地同步了客户端与服务端的集群信息。
ava *** 作redis的jedis的范围查询是怎么写的? 我要从一个范围到另一个范围的区间
我试过了,
List userList = jedislrange("userList", 0, -1);
Set user = jediszrange("user", 0, -1);
这两个范围查询的得到结果,为何都是 0
但是我用 Set str =jediskeys("tes2:");
发现是用完整的数据的,我一次性读取这么多数据,redis直接socket失败了
它是专为 NET 平台设计的一种静态类型编程语言。 Nemerle 中的程序会被编译成中间语言字节码。它支持函数式,命令式以及面向对象编程。
比如前缀为:A两种办法:keys A
因为redis是单线程,所以key太多会导致其他访问redis的应用进入等待状态,所以不推荐使用keys。
scan 0 match A count 10
0 表示当前游标,每次调用scan命令会返回数组,数组中的第一位为下一次遍历的游标
match A 匹配key
count 10 表示每次想要得到多少条数据,但是不一定是10条,只是差不多10条
返回的数据可能会有重复,可以用代码的Map去重
第一步,在windows安装配置好redis数据库。这里我就不再概述了。jedis-242jar,当然最好是最新版本的jar包。这个在下就出来的。后,放在一个文件夹下面,一会会需要到。
第二步。打开eclipse,新建一个java工程。如下图所示:
第三步:在Test这个java工程里面,我们新建一个folder,命名lib,把刚才的jedis-242jar包放在我们新建的lib的包下面,如下图所示:
第四步,在eclipse中,选中jar包,build path下。然后我们再Test这个项目里面我们新建一个class,class名字为TestConnect。
第五步,在类里面,我们输入如下的内容:
// Connecting to Redis server on localhost
//实例化一个客户端
Jedis jedis = new Jedis("localhost");
//=================================================
// check whether server is running or not
//ping下,看看是否通的
Systemoutprintln("Server is running: " + jedisping());
//保存一个
jedisset("leiTest", "localhost Connection sucessfully");
//获取一个
Systemoutprintln("通过key获取value: " + jedisget("leiTest"));
第六步,对刚才的类进行运行,ctrl+f11快捷键运行下,如下图所示:
第七步,进一步验证我们是否在redis上是否保存了数据,并且能够取出来,我们到redis安装包的目录,如下图,打开红色框内的 redis-cliexe,打开后,我们进入下面的第二个的界面。
第八步:我们在redis的客户端的界面 输入 get leiTest 这个指令。leiTest是刚才在eclipse中我们存入redis数据库中的一个String类型的键。如下图,证明我们确实成功了,你也试试吧。
参数名:maxTotal
含义:资源池最大连接数 默认值:8
使用建议:需要考虑以下几点
1业务希望的Redis并发量
2客户端执行命令时间
3Redis资源:例如应用个数(客户端) maxTotal 不能超过Redis服务端的最大连接数(config get maxclients)
4资源开销:例如虽然希望控制空闲连接,但是不希望因为连接池的频繁释放创建连接造成不必要的开销。
举例:
命令平均执行时间01ms = 0001s
业务需要50000 QPS
maxTotal理论值 = 0001 50000 = 50个。实际值要偏大一些。
参数名:maxIdle
含义:资源池允许最大的空闲连接数 默认值:8
使用建议:建议跟maxTotal设置的值一样,这样可以减少创建新连接的开销
参数名:minIdle
含义:资源池确保最少空闲连接数 默认值:0
使用建议:建议第一次开启的时候预热(初始化一个值),减少第一次启动后的新连接开销
参数名:jmxEnabled
含义:是否开启jmx监控,可用于监控资源使用状态 默认值:true
使用建议:开启
参数名:blockWhenExhausted
含义:当资源池用尽后,调用者是否要等待。只有当为true时,配置的maxWaitMillis参数才会生效 默认值:true
使用建议:建议先使用默认值,但这个也要看情况,如果并发量大,可以直接设置false,即每次请求资源时,如果连接资源不够,马上new个新的
参数名:maxWaitMillis
含义:当资源池连接用尽后,调用者最大等待时间(单位为毫秒) 默认-1,表示永不超时
使用建议:不建议使用默认值,再高并发环境下,获取资源不能hand在一个没有超时时间的地方,具体设置根据实际场景 如设置1000即为等待1秒。
参数名:testOnBorrow、testOnReturn
含义:这两个参数是说,客户端向连接池借用或归还时,是否会在内部进行有效性检测(ping),无效的资源将被移除 默认值:false
使用建议:建议false,在高并发场景下,因为这样无形给每次增加了两次ping *** 作,对QPS有影响,如果不是高并发环境,可以考虑开启,或者自己来检测。
无法从连接池中获取连接(超时)
连接池中资源耗尽(最大连接maxTotal和最大空闲连接maxIdle设置不等)
解决思路:
1慢查询阻塞:池子连接都被hang住。
2资源参数不合理:例如QPS高,池子小。
3连接泄露(没有close()):也就是没有归还连接,可以用client list、netstat观察连接的一个增长情况,最重要的是trycatchfinally
以上就是关于springboo连接redis哨兵集群原理全部的内容,包括:springboo连接redis哨兵集群原理、redis主从替换jedis怎么获取新的ip地址、如何用java获取redis的info等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)