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
相关产品推荐
相关产品推荐

