You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Redisson MapCacheEvictionTask报错原因排查及解决求助

问题与解决方案

问题详情

开发Java Spring应用时,使用RedissonRegionFactory作为Hibernate二级缓存提供者,Maven依赖如下:

<dependency>
    <groupId>org.redisson</groupId>
    <artifactId>redisson-hibernate-52</artifactId>
    <version>3.17.7</version>
</dependency>

运行项目时抛出Redis响应超时错误:

org.redisson.client.RedisResponseTimeoutException: Redis server response timeout (3000 ms) occured after 0 retry attempts, is non-idempotent command: false Check connection with Redis node: 127.0.0.1/127.0.0.1:6379 for TCP packet drops.  Try to increase nettyThreads and/or timeout settings. Command: (EVAL), params: [if redis.call('setnx', KEYS[6], ARGV[4]) == 0 then return -1;end;redis.call('expire', KEYS[6], ARGV[3]); local expiredKeys1 = redis.call('zrangebyscore', KEYS[2], 0, ARGV[1], 'limit', 0, ARGV[2]); for i, key in ipairs(expiredKeys1) do local v = redis.call('hget', KEYS[1], key); if v ~= false then local t, val = struct.unpack('dLc0', v); local msg = struct.pack('Lc0Lc0', string.len(key), key, string.len(val), val); local listeners = redis.call('publish', KEYS[4], msg); if (listeners == 0) then break;end; end;end;for i=1, #expiredKeys1, 5000 do redis.call('zrem', KEYS[5], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); redis.call('zrem', KEYS[3], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); redis.call('zrem', KEYS[2], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); redis.call('hdel', KEYS[1], unpack(expiredKeys1, i, math.min(i+4999, table.getn(expiredKeys1)))); end; local expiredKeys2 = redis.call('zrangebyscore', KEYS[...]

尝试将连接超时调整为30000ms但未解决问题,配置代码如下:

final Config redissonConfig = new Config();
 redissonConfig.useSingleServer()
            .setKeepAlive(true)
            .setConnectTimeout(30000 )
            .setRetryAttempts(5)
            .setDnsMonitoringInterval(300)
            .setAddress("redis://127.0.0.1:6379");
    return Redisson.create(redissonConfig);

解决办法

1. 修正超时参数配置,区分连接与响应超时

你当前设置的setConnectTimeout是Redis连接超时时间,而报错提示的是命令响应超时,需要添加setTimeout参数(控制命令等待响应的时长),同时调整重试间隔:

final Config redissonConfig = new Config();
redissonConfig.useSingleServer()
        .setKeepAlive(true)
        .setConnectTimeout(30000)
        .setTimeout(30000) // 核心:设置命令响应超时时间
        .setRetryAttempts(5)
        .setRetryInterval(1000) // 增加重试间隔,避免频繁重试加重Redis负载
        .setDnsMonitoringInterval(300)
        .setAddress("redis://127.0.0.1:6379");
return Redisson.create(redissonConfig);

2. 优化Redis服务器性能,减轻脚本执行压力

报错中的EVAL命令是Redisson处理Hibernate缓存过期的Lua脚本,执行耗时过长通常是Redis负载过高导致:

  • 开启Redis慢查询日志:执行config set slowlog-log-slower-than 1000捕获耗时超过1秒的命令,再用slowlog get查看具体慢命令
  • 清理Redis中堆积的过期键,避免脚本一次性处理大量过期数据
  • 检查Redis内存配置,确保内存充足,避免因内存不足频繁触发RDB/AOF持久化阻塞服务

3. 调整Redisson线程池与缓存策略

  • 增加Netty线程数:默认值为CPU核数*2,可根据服务器配置调高,例如:
    redissonConfig.setNettyThreads(16); // 根据服务器CPU核数调整,8核服务器可设为16
    
  • 优化Hibernate二级缓存配置:减少批量处理的过期键数量,或调整缓存过期时间,避免短时间内大量键集中过期
  • 核对版本兼容性:确保redisson-hibernate-52与你使用的Hibernate 5.x版本匹配,版本不兼容也可能引发异常

4. 排查本地网络异常

即使是本地Redis,也可能存在TCP数据包丢失或延迟问题:

  • 用ping 127.0.0.1检测是否有丢包,telnet 127.0.0.1 6379测试端口连通性
  • 暂时关闭本地防火墙、杀毒软件,排除端口拦截的可能

内容的提问来源于stack exchange,提问作者User01

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 17:15:46