Jedis获取数据:JedisConnectionFailureException在很长一段时间内迭代一段代码

时间:2016-04-26 17:12:28

标签: java spring redis spring-data jedis

所以我有一个使用Jedis Client从Redis获取价值的代码。但是,在同一时间,Redis处于最大程度的连接状态,并且这些异常被抛出:

org.springframework.data.redis.RedisConnectionFailureException
Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:140)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:229)
...
org.springframework.data.redis.RedisConnectionFailureException
java.net.SocketTimeoutException: Read timed out; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: java.net.SocketTimeoutException: Read timed out
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:47)
    at org.springframework.data.redis.connection.jedis.JedisExceptionConverter.convert(JedisExceptionConverter.java:36)
...
org.springframework.data.redis.RedisConnectionFailureException
Cannot get Jedis connection; nested exception is redis.clients.jedis.exceptions.JedisConnectionException: Could not get a resource from the pool
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.fetchJedisConnector(JedisConnectionFactory.java:140)
    at org.springframework.data.redis.connection.jedis.JedisConnectionFactory.getConnection(JedisConnectionFactory.java:229)

当我检查这个场景的AppDynamics分析时,我在很长一段时间(1772秒)看到了一些调用的迭代。电话会显示在剪辑中。

First Snip (iteration of Thread:sleep and BinaryJedis:exists

Second Snip (iteration of Thread:sleep and BinaryJedis:exists

任何人都可以解释这里发生的事情吗?为什么Jedis在Timeout设置(500ms)之后没有停止?我可以长期防止这种情况发生吗?

这就是我对Jedis的Bean定义:

<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" p:host-name="100.90.80.70" p:port="6382" p:timeout="500" p:use-pool="true" p:poolConfig-ref="jedisPoolConfig" p:database="3" />

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="1000" />
    <property name="maxIdle" value="10" />
    <property name="maxWaitMillis" value="500" />
    <property name="testOnBorrow" value="true" />
    <property name="testOnReturn" value="true" />
    <property name="testWhileIdle" value="true" />
    <property name="numTestsPerEvictionRun" value="10" />
</bean>

1 个答案:

答案 0 :(得分:1)

我不熟悉AppDynamics输出。我假设这是线程及其睡眠时间的累积视图。因此线程被重用,因此睡眠时间加起来。在某些情况下,Thread直接获取连接,没有任何等待,在另一个调用中,Thread必须等到可以提供连接。等待持续时间取决于连接何时可用或命中等待限制。

让我们有一个实际的例子:

您的屏幕截图显示了一个等待172ms的主题。假设仅在Jedis / Redis调用路径中调用sleep,则线程总共等待172ms以获得连接。

等待530ms的另一个帖子看起来好像第一次尝试获得连接并不成功(这解释了第一个500ms)并且在第二次尝试时,它有等待30ms。它也可能是265ms等待2倍。

旁注:

1000多个连接可能会严重限制可扩展性。 Spring Data Redis还支持其他不需要合并但使用较少连接的驱动程序(请参阅Spring Data Redis Connectorshere)。