【问题标题】:Redis/Jedis not serving properlyRedis/Jedis 服务不正常
【发布时间】:2020-01-10 03:18:04
【问题描述】:

我们在带有 Jedis 的 Spring Java 应用程序中使用 Redis 缓存,在高负载期间缓存卡住并且无法及时响应。

我们已经将 Jedis 连接配置如下:

val clientConfiguration = JedisClientConfiguration
                .builder()
                .readTimeout(Duration.ofSeconds(2L))
                .connectTimeout(Duration.ofSeconds(10L))
                .usePooling()
                .build()

        val configuration = RedisStandaloneConfiguration(redisHost, Integer.parseInt(redisPort))
        configuration.password = RedisPassword.of(redisPassword)

val jedisConnectionFactory = JedisConnectionFactory(configuration, clientConfiguration)
        jedisConnectionFactory.poolConfig.apply {
            maxTotal = 512
            maxIdle = 256
            minIdle = 16
            maxWaitMillis = 2000L
            blockWhenExhausted = true
        }

Redis 服务器似乎没有负载,也没有显示任何错误。我们能看到的唯一问题是在使用jstack 时,有数百个线程卡在RedisCache.get 中:

 java.lang.Thread.State: BLOCKED (on object monitor)
    at org.springframework.data.redis.cache.RedisCache.get(RedisCache.java:117)
    - waiting to lock <0x00000000c00bd5f8> (a org.springframework.data.redis.cache.RedisCache)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:381)
    at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:345)
    at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)

如果服务器没有正确响应,我希望看到一些异常,但绝对没有。我们只能看到超慢的响应。

【问题讨论】:

  • 你试过 Redisson java 客户端吗?它没有这样的问题

标签: spring spring-boot redis jedis


【解决方案1】:

您面临的错误不是因为 redis-server 处于任何负载下,而是 spring-server 耗尽了。在配置中:

jedisConnectionFactory.poolConfig.apply {
            maxTotal = 512
            ...
            ...
            blockWhenExhausted = true
        }

似乎 jedis-pool 已耗尽并阻止新请求。为了尽量减少这种情况,您可以增加池大小并检查是否减少 maxWaitMillis = 2000LreadTimeout(Duration.ofSeconds(2L))connectTimeout(Duration.ofSeconds(10L)) 做了任何改进。

【讨论】:

    【解决方案2】:

    我们发现这实际上是由 Jedis 实现的一个已知问题引起的:

    https://jira.spring.io/projects/DATAREDIS/issues/DATAREDIS-678?filter=allopenissues

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-30
      • 2016-10-08
      • 2013-11-08
      • 1970-01-01
      • 1970-01-01
      • 2012-03-17
      相关资源
      最近更新 更多