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