基于Spring的Redisson客户端CPU使用率达90%,寻求优化建议
解决Redisson客户端结合Spring Cache导致CPU使用率过高的建议
基于Spring框架,使用AWS ElastiCache Redis 7.0.7、Java 1.8、Redisson 3.16.0客户端,配置如下:
final Config redissonConfig = new Config(); redissonConfig.setNettyThreads(256); redissonConfig.setThreads(128); redissonConfig.useClusterServers() .setKeepAlive(true) .setConnectTimeout(5000) .setRetryAttempts(1) .setRetryInterval(50) .setPingConnectionInterval(10000) .setDnsMonitoringInterval(20000) .addNodeAddress(redisAddress); RedissonClient client = Redisson.create(redissonConfig); return client;
通过@Cacheable实现方法缓存后,CPU使用率上升60%至90%,以下是针对性优化建议:
1. 优化线程池参数配置
当前NettyThreads=256、Threads=128的设置远超出合理范围,Java 8的线程上下文切换开销会随线程数量剧增而飙升。建议根据服务器CPU核心数调整:
NettyThreads(IO线程池):设置为CPU核心数的2倍(例如8核服务器设为16)Threads(业务处理线程池):设置为CPU核心数(例如8核服务器设为8)
调整后配置示例:
redissonConfig.setNettyThreads(16); redissonConfig.setThreads(8);
2. 排查@Cacheable使用合理性
- 缓存命中率检查:若缓存命中率过低,大量请求会穿透至业务方法,叠加Redis请求开销导致CPU飙升。可通过Spring Cache统计功能或Redisson监控工具统计命中率,针对性调整缓存过期时间、补充缓存预热逻辑。
- 序列化/反序列化开销:Redisson默认使用Jackson序列化,复杂对象的序列化操作会占用大量CPU。建议:
- 简化缓存对象结构,仅缓存必要字段
- 切换为更高效的序列化方式,如Kryo,配置示例:
Codec codec = new KryoCodec(); redissonConfig.setCodec(codec);
- 缓存Key生成逻辑:检查是否存在重复生成复杂Key的情况,避免不必要的字符串拼接、哈希计算开销。
3. 调整Redis连接相关配置
- 降低Ping频率:当前
setPingConnectionInterval(10000)(10秒一次)过于频繁,可调整为30000(30秒)或60000(60秒),减少无意义的IO操作:.setPingConnectionInterval(30000) - 启用TCP_NODELAY:开启该选项可减少TCP数据包延迟,降低IO线程的处理开销:
.setTcpNoDelay(true)
4. 升级Redisson客户端版本
Redisson 3.16.0属于较旧版本,存在一些已知的线程调度、序列化性能问题。建议升级至最新稳定版本(如3.20.x系列),修复旧版本的性能瓶颈。
5. 定位CPU消耗热点
使用工具排查具体线程的CPU占用情况:
- 用
jstack命令导出线程栈,分析Netty IO线程、Redisson业务线程、Spring Cache线程的栈信息,定位是否存在线程阻塞、循环调用等问题 - 用
jprofiler或visualvm等工具监控CPU占用热点,明确是序列化、线程切换还是业务方法本身导致的CPU飙升,再针对性优化
内容的提问来源于stack exchange,提问作者Osama Jetawe
相关产品推荐
相关产品推荐

