6.9 KiB
6.9 KiB
Redis 内存优化实施总结
问题描述
项目中 Redis 运行一段时间后占用大量内存,可能导致系统性能下降或 OOM。
已实施的优化措施
1. 修改 RedisCache 类 - 添加默认过期时间
文件: qaup-common/src/main/java/com/qaup/common/core/redis/RedisCache.java
改动:
setCacheObject(key, value)方法现在默认设置 1 小时过期时间- 新增
setCacheObjectPermanent(key, value)方法用于需要永久缓存的数据 - 防止缓存数据无限期保存导致内存泄漏
影响:
- 所有使用
setCacheObject的地方会自动获得过期时间 - 现有缓存会在 1 小时后自动清理
- 需要永久缓存的数据需要改用新方法
2. 优化 WebSocket 消息缓存
文件: qaup-collision/src/main/java/com/qaup/collision/websocket/cache/MessageCacheService.java
改动:
- 最大缓存消息数: 100 → 50
- 过期时间: 30分钟 → 10分钟
- 减少 50% 的 WebSocket 消息缓存占用
3. 添加内存缓存清理逻辑
文件: qaup-collision/src/main/java/com/qaup/collision/datacollector/service/DataCollectorService.java
新增功能:
- 每 60 秒执行一次内存缓存清理
- 清理 5 分钟未更新的
flightNotificationCache数据 - 监控
activeMovingObjectsCache大小,超过 1000 个对象时发出警告 - 应用关闭时自动清理所有内存缓存
4. 配置 Redis 内存限制
文件:
qaup-admin/src/main/resources/application-dev.yml(开发环境)qaup-admin/src/main/resources/application-prod.yml(生产环境)
新增配置:
redis:
max-memory: 256mb # 开发环境
# max-memory: 1gb # 生产环境
max-memory-policy: volatile-lru
说明:
- 限制 Redis 最大内存使用
- 使用 LRU 算法淘汰设置了过期时间的 key
- 生产环境支持环境变量配置
5. 创建 Redis 缓存清理和监控任务
文件: qaup-framework/src/main/java/com/qaup/framework/task/RedisCacheCleanupTask.java
功能:
-
每天凌晨 2 点执行缓存清理
- 清理验证码等临时缓存
- 为没有过期时间的 key 设置默认 TTL
-
每 5 分钟监控内存使用情况
- 记录当前内存、峰值内存和限制
- 使用率超过 80% 时发出警告
- 使用率超过 90% 时发出错误日志
-
每小时统计 key 数量
- 统计各类型 key 的数量
- 帮助识别异常增长的缓存
6. 创建运维脚本
6.1 Redis 配置脚本
文件: scripts/configure_redis_memory.sh
功能:
- 快速配置 Redis 内存限制
- 提供开发/生产环境预设
- 可选保存到配置文件
- 实时生效,无需重启
使用方法:
cd scripts
./configure_redis_memory.sh
6.2 Redis 诊断脚本
文件: scripts/redis_memory_diagnosis.sh
功能:
- 分析内存使用情况
- 统计 key 数量分布
- 检查没有过期时间的 key
- 提供优化建议
使用方法:
cd scripts
./redis_memory_diagnosis.sh
立即执行的操作步骤
第一步: 运行诊断脚本
cd /Users/tianjianyong/apps/Company/QAUP-Management
./scripts/redis_memory_diagnosis.sh
查看当前 Redis 内存使用情况和问题。
第二步: 配置 Redis 内存限制
./scripts/configure_redis_memory.sh
选择适合的环境配置(开发环境选 1,生产环境选 2)。
第三步: 重新编译和部署应用
# 编译项目
mvn clean install -DskipTests
# 重启应用
./ry.sh restart
第四步: 监控效果
等待应用运行一段时间后,再次运行诊断脚本:
./scripts/redis_memory_diagnosis.sh
预期效果
实施优化后,预期:
- ✅ Redis 内存占用降低 50-70%
- ✅ 内存使用稳定在设置的上限以内
- ✅ 不会出现内存持续增长的情况
- ✅ 系统性能不会受到明显影响
- ✅ 自动清理过期和不活跃的缓存
监控指标
关键日志
应用运行后会输出以下日志:
- 内存缓存清理 (每分钟):
清理不活跃缓存对象: X 个移动对象, Y 个航班通知; 剩余: XX 个移动对象, YY 个航班通知
- Redis 内存监控 (每 5 分钟):
Redis 内存使用情况 - 当前: XXM, 峰值: XXM, 限制: 256M
- Key 数量统计 (每小时):
Redis Key 统计 - 登录Token: XX 个
Redis Key 统计 - WebSocket消息: XX 个
...
需要关注的指标
- Redis 内存使用率保持在 70% 以下
- 没有持续增长的趋势
- Key 数量稳定或有规律的波动
- 无大量没有过期时间的 key
回滚方案
如果优化导致问题,可以快速回滚:
1. 恢复 RedisCache 类
git checkout qaup-common/src/main/java/com/qaup/common/core/redis/RedisCache.java
2. 移除 Redis 内存限制
redis-cli CONFIG SET maxmemory 0
redis-cli CONFIG SET maxmemory-policy noeviction
3. 重新部署
mvn clean install -DskipTests
./ry.sh restart
长期维护建议
1. 定期检查 Redis 内存
每周运行诊断脚本,关注内存使用趋势:
./scripts/redis_memory_diagnosis.sh
2. 审查缓存使用
- 审查所有
setCacheObject调用 - 确保设置了合理的过期时间
- 避免缓存大对象或大量数据
3. 监控和告警
考虑添加:
- Redis 内存使用率告警 (>80%)
- Key 数量异常增长告警
- 应用层缓存监控
4. 数据库层面优化
- 考虑使用 Redis 集群
- 分离不同类型的缓存(如会话、业务数据)
- 评估是否需要持久化
相关文档
- 详细优化指南: doc/redis_optimization_guide.md
- 诊断脚本: scripts/redis_memory_diagnosis.sh
- 配置脚本: scripts/configure_redis_memory.sh
修改清单
修改的文件
qaup-common/src/main/java/com/qaup/common/core/redis/RedisCache.javaqaup-collision/src/main/java/com/qaup/collision/websocket/cache/MessageCacheService.javaqaup-collision/src/main/java/com/qaup/collision/datacollector/service/DataCollectorService.javaqaup-admin/src/main/resources/application-dev.ymlqaup-admin/src/main/resources/application-prod.yml
新增的文件
qaup-framework/src/main/java/com/qaup/framework/task/RedisCacheCleanupTask.javascripts/configure_redis_memory.shscripts/redis_memory_diagnosis.shdoc/redis_optimization_guide.mddoc/redis_optimization_summary.md(本文件)
注意事项
⚠️ 重要提示:
- 生产环境操作前务必备份数据
- 建议先在开发/测试环境验证
- 监控应用性能,确保无异常
- Redis 配置修改可实时生效,但应用需要重启以应用代码修改
技术支持
如有问题,请检查:
- 应用日志:
qaup-admin/app.log - Redis 日志:
/var/log/redis/redis-server.log - 运行诊断脚本获取详细信息
优化完成时间: 2025-10-13 版本: 1.0.0 作者: Claude Code