
Caused by: orgspringframeworkdataredisRedisConnectionFailureException: Could not get a resource from the pool; nested exception is redisclientsjedisexceptionsJedisConnectionException: Could not get a resource from the pool
at orgspringframeworkdataredisconnectionjedisJedisExceptionConverterconvert(JedisExceptionConverterjava:67)
at orgspringframeworkdataredisconnectionjedisJedisExceptionConverterconvert(JedisExceptionConverterjava:41)
at orgspringframeworkdataredisPassThroughExceptionTranslationStrategytranslate(PassThroughExceptionTranslationStrategyjava:37)
at orgspringframeworkdataredisconnectionjedisJedisClusterConnectionconvertJedisAccessException(JedisClusterConnectionjava:3999)
at orgspringframeworkdataredisconnectionjedisJedisClusterConnectionsetEx(JedisClusterConnectionjava:717)
at orgspringframeworkdatarediscoreDefaultValueOperations 11doInRedis(DefaultValueOperationsjava:186)
at orgspringframeworkdatarediscoreRedisTemplateexecute(RedisTemplatejava:207)
at orgspringframeworkdatarediscoreRedisTemplateexecute(RedisTemplatejava:169)
at orgspringframeworkdatarediscoreAbstractOperationsexecute(AbstractOperationsjava:91)
at orgspringframeworkdatarediscoreDefaultValueOperationsset(DefaultValueOperationsjava:182)
at iorenrencommonutilsSuppleDataUtilsprovideIcc(SuppleDataUtilsjava:107)
at iorenrenmodulesjobtaskTaskIcctaskFour(TaskIccjava:242)
10 common frames omitted
Caused by: redisclientsjedisexceptionsJedisConnectionException: Could not get a resource from the pool
at redisclientsutilPoolgetResource(Pooljava:53)
at redisclientsjedisJedisPoolgetResource(JedisPooljava:226)
at redisclientsjedisJedisSlotBasedConnectionHandlergetConnectionFromSlot(JedisSlotBasedConnectionHandlerjava:66)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:116)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunWithRetries(JedisClusterCommandjava:141)
at redisclientsjedisJedisClusterCommandrunBinary(JedisClusterCommandjava:60)
at redisclientsjedisBinaryJedisClustersetex(BinaryJedisClusterjava:268)
at orgspringframeworkdataredisconnectionjedisJedisClusterConnectionsetEx(JedisClusterConnectionjava:715)
18 common frames omitted
Caused by: redisclientsjedisexceptionsJedisConnectionException: javanetSocketTimeoutException: connect timed out
at redisclientsjedisConnectionconnect(Connectionjava:207)
at redisclientsjedisBinaryClientconnect(BinaryClientjava:93)
at redisclientsjedisBinaryJedisconnect(BinaryJedisjava:1767)
at redisclientsjedisJedisFactorymakeObject(JedisFactoryjava:106)
at orgapachecommonspool2implGenericObjectPoolcreate(GenericObjectPooljava:868)
at orgapachecommonspool2implGenericObjectPoolborrowObject(GenericObjectPooljava:435)
at orgapachecommonspool2implGenericObjectPoolborrowObject(GenericObjectPooljava:363)
at redisclientsutilPoolgetResource(Pooljava:49)
28 common frames omitted
Caused by: javanetSocketTimeoutException: connect timed out
at javanetDualStackPlainSocketImplwaitForConnect(Native Method)
at javanetDualStackPlainSocketImplsocketConnect(DualStackPlainSocketImpljava:85)
at javanetAbstractPlainSocketImpldoConnect(AbstractPlainSocketImpljava:350)
at javanetAbstractPlainSocketImplconnectToAddress(AbstractPlainSocketImpljava:206)
at javanetAbstractPlainSocketImplconnect(AbstractPlainSocketImpljava:188)
at javanetPlainSocketImplconnect(PlainSocketImpljava:172)
at javanetSocksSocketImplconnect(SocksSocketImpljava:392)
at javanetSocketconnect(Socketjava:589)
at redisclientsjedisConnectionconnect(Connectionjava:184)
35 common frames omitted
最近在本地测试通过springboot基础redis的方式连接redis集群,启动的时候没有报错。
到时当执行保存,查询到redis的 *** 作的时候,报上面的错误。
首先看到错误信息,先是connect timed out后,再出现的Could not get a resource from the pool错误。一开始排查这个错误,由于使用的是默认连接池,debug的时候,也看到有装载连接池,为啥报错呢。本地通过redis-manger工具,连接集群地址也可以连接访问。从日志也看不出还有其他的错误信息。
于是自己写了main方法直接 *** 作JedisCluster的方式来测试,出现的错误跟上面全文一样。用抓包工具wireshark过滤集群的地址,查看连接的消息也是正常的。
另外一个项目使用的reddison客户端,于是测试了deamo用reddison来连接集群地址,启动的时候,发现报如下错误
乖乖,恍然大悟;102871731地址是服务器的内网地址,本机是连不上内网地址的,只有通过外网地址连接。而我配置的是外网地址。然而,客户端在集群同步和心跳检查的时候,是拉取的集群信息,redis集群信息里面的节点的信息
配置的是内网地址。客户端就通过这个内网地址来同步信息了。
再次同wireshark过滤集群102871731,发现有大量的超时重传的包,也没有响应。
redis单机集群搭建好了之后,发现通过外网ip链接不了集群,一直报错。此时需要修改以下内容
bind 改为0000
关闭保护模型
最后也是最重要的一点,启动集群使用外网ip加端口号
并且修改生成的nodesconf文件中myself的内网地址为外网地址
无需要求每个master的slot编号是连续的,只要每个master管理的slot的数量均衡就可以。
我们在上面添加了1000103:6379和1000103:6380两个节点,现在把这两个节点下线
Redis提供了 cluster forget{downNodeId} 命令来通知其他节点忘记下线节点,当节点接收到 cluster forget {down NodeId} 命令后,会把 nodeId 指定的节点加入到禁用列表中,在禁用列表内的节点不再与其他节点发送消息,禁用列表有效期是60秒,超过60秒节点会再次参与消息交换。也就是说当第一次forget命令发出后,我们有60秒的时间让集群内的所有节点忘记下线节点
线上 *** 作不建议直接使用 cluster forget 命令下线节点,这需要跟大量节点进行命令交互,建议使用 redis- tribrb del-node {host:port} {downNodeId} 命令
另外,先下线slave,再下线master可以防止不必要的数据复制
redis-tribrb del-node 还可以自动停止下线节点的服务。
主从模式指的是使用一个Redis实例作为主机,其余的实例作为备份机。一般来说主节点负责写请求,从节点负责读请求,主节点异步的同步给从节点。主节点和从节点保存的数据是相同的,但是因为同步,从节点的数据会有一点延迟。但是主从模式的高可用会有问题。因为主节点挂了之后是没有自动选主机制的,需要人工干预来指定一个从节点作为主节点。
为了解决主从模式不能高可用的问题,哨兵模式就出现了。哨兵模式就是在主从模式的基础上再加一个哨兵集群。每个哨兵都会监控主节点和从节点的状态。如果主节点挂了,就会从从节点中选出一个来作为主节点,以达到高可用的目的。(也就是有了自动选主机制)
哨兵集群中的每个节点都会启动三个定时任务
如果一个 实例(instance)距离最后一次有效回复 PING命令的时间超过 down-after-milliseconds 所指定的值,那么这个实例会被 Sentinel标记为 主观下线 。
如果一个 主服务器 被标记为主观下线,那么正在 监视 这个主服务器的所有 Sentinel 节点,要以 每秒一次的频率确认 该主服务器是否的确进入了主观下线状态。
如果一个主服务器 被标记为主观下线,并且有 足够数量的 Sentinel(至少要达到配置文件指定的数量)在指定的 时间范围 内同意这一判断,那么这个该主服务器被标记为 客观下线。
哨兵模式解决了故障不能自动恢复的问题,但仍存在的问题是:Redis较难支持在线扩容,对于集群,容量达到上限时在线 扩容会变得很复杂 。
Redis Cluster采用虚拟槽分区,所有的键按照哈希函数映射到0~16383槽中,每个Redis节点维护部分槽和槽中的数据。
Spring对Redis的支持是通过Spring Data Redis实现的,JedisConnectionFactory为我们提供了Redis的一种Java客户端Jedis。本文主要为大家介绍使用工厂类获取Jedis的两种方式,以及使用过程中存在的问题,希望能为大家提供一些思路。
工具/材料IntelliJ IDEA
01首先我们需要编辑Spring的配置文件applicationproperties,添加Redis的相关配置,这些配置在代码中需要注入,用来生成JedisConnectionFactory的Bean。
02接下来我们写一个配置类,该配置类上需要添加@Configuration注解,我们在这个类中通过@Value注解注入applicationproperties配置文件中的部分需要的属性,其中{}用于接收属性值,在属性名冒号后面的值是默认值,若读取不到该属性则使用默认值。我们在该类中创建JedisConnectionFactory的Bean,在这个Bean中设置读取到的属性值。
03接下来我们创建一个RedisServer的类,主要用于获取Redis以及实现部分Redis *** 作的方法。在该类中我们可以使用@Autowired注解注入JedisConnectionFactory的Bean。下图中获取Redis客户端Jedis的方法是我们推荐的方法,使用该方法我们既获取到了Jedis实例又使用的连接池,将Jedis实例交由连接池管理,不用太担心并发 *** 作导致的Redis不可用的情况。最后再附上Jedis *** 作存储和获取数据的方法。
04另外,我们还有再介绍一种并不推荐的写法,如下图所示。这种方法每次都创建一个新的Redis连接并且没有关闭连接,在大量并发 *** 作时会带来性能上的开销,由于对连接数没有限制,可能会耗尽Redis的连接,导致Redis连接报错。
05配置完成后我们来测试一下Jedis是否能正常使用,创建一个RedisController类,在该类中注入JedisServer,使用JedisServer提供的存储和读取方法,然后启动服务。
06服务启动后我们在postman中进行测试,首先调用setRedis请求将数据存入Redis中,然后再调用getRedis请求获取数据,如下图所示。
07JedisConnectionFactory在Spring Data Redis 20后就不再推荐上述这种配置方式了,当我们的spring-boot-starter-parent版本设置为2x时,我们可以看到代码中的设置已经被废弃了。
08Spring Data Redis 20推荐使用Standalone、Sentinel、RedisCluster这三种模式的环境配置类,以便于更加灵活的适配更多的业务场景,我们一般自己测试Redis通常使用的都是单机版的,那么以单机版为例,JedisConnectionFactory的配置应写为如下的方式。
特别提示本文只是介绍了一种Redis客户端的使用方式,还是推荐大家使用spring-boot集成Redis做开发,因为spring-boot开箱即用的特性可以大大减少开发工作量。
以上就是关于jedis连接集群报Could not get a resource from the pool错误全部的内容,包括:jedis连接集群报Could not get a resource from the pool错误、JedisCluster连接redis集群一直报Could not get a resource from the pool、015.Redis Cluster集群扩容缩容原理及实战等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)