springboo连接redis哨兵集群原理

springboo连接redis哨兵集群原理,第1张

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等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9656806.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-30
下一篇2023-04-30

发表评论

登录后才能评论

评论列表(0条)

    保存