Commit db5781271fc5127ffe323f19c1ab767c2dc1f6f8
1 parent
fb8112e0
offline tasks: mem optimize
Showing
6 changed files
with
1021 additions
and
9 deletions
Show diff stats
| ... | ... | @@ -0,0 +1,155 @@ |
| 1 | +# 最新更新 (2025-10-17) | |
| 2 | + | |
| 3 | +## 🎉 本次更新内容 | |
| 4 | + | |
| 5 | +### 1. ✅ ES向量相似度 + on_sell_days_boost提权 | |
| 6 | + | |
| 7 | +#### 功能 | |
| 8 | +- 基于Elasticsearch向量计算相似度(名称向量 + 图片向量) | |
| 9 | +- 自动应用 `on_sell_days_boost` 提权(0.9~1.1) | |
| 10 | +- 无需任何命令行参数,开箱即用 | |
| 11 | + | |
| 12 | +#### 使用 | |
| 13 | +```bash | |
| 14 | +python scripts/i2i_content_similar.py | |
| 15 | +``` | |
| 16 | + | |
| 17 | +### 2. ✅ 代码规范:统一使用 logger | |
| 18 | + | |
| 19 | +#### 变更 | |
| 20 | +- 移除所有 `print` 语句 | |
| 21 | +- 统一使用 `logger` 记录日志 | |
| 22 | +- 更好的日志级别控制 | |
| 23 | + | |
| 24 | +### 3. ✅ run.sh 内存监控 | |
| 25 | + | |
| 26 | +#### 功能 | |
| 27 | +- **25GB警告**: 打印警告日志,继续运行 | |
| 28 | +- **30GB终止**: 强制kill进程,防止OOM | |
| 29 | +- **每10秒检查**: 实时监控内存使用 | |
| 30 | +- **详细日志**: `logs/memory_monitor.log` | |
| 31 | + | |
| 32 | +#### 使用 | |
| 33 | +```bash | |
| 34 | +./run.sh | |
| 35 | +``` | |
| 36 | + | |
| 37 | +## 📋 快速开始 | |
| 38 | + | |
| 39 | +### 1. 测试ES连接和向量 | |
| 40 | +```bash | |
| 41 | +python scripts/test_es_connection.py | |
| 42 | +``` | |
| 43 | + | |
| 44 | +### 2. 测试内存监控 | |
| 45 | +```bash | |
| 46 | +./test_memory_monitor.sh | |
| 47 | +``` | |
| 48 | + | |
| 49 | +### 3. 运行所有任务(含监控) | |
| 50 | +```bash | |
| 51 | +./run.sh | |
| 52 | +``` | |
| 53 | + | |
| 54 | +### 4. 查看监控日志 | |
| 55 | +```bash | |
| 56 | +tail -f logs/memory_monitor.log | |
| 57 | +``` | |
| 58 | + | |
| 59 | +## 📊 生成的索引 | |
| 60 | + | |
| 61 | +| 索引文件 | Redis Key | 提权 | TTL | | |
| 62 | +|---------|-----------|------|-----| | |
| 63 | +| `i2i_content_name_YYYYMMDD.txt` | `item:similar:content_name:{id}` | ✅ | 30天 | | |
| 64 | +| `i2i_content_pic_YYYYMMDD.txt` | `item:similar:content_pic:{id}` | ✅ | 30天 | | |
| 65 | + | |
| 66 | +## 📚 文档 | |
| 67 | + | |
| 68 | +| 文档 | 说明 | | |
| 69 | +|------|------| | |
| 70 | +| `QUICKSTART_NEW.md` | 5分钟快速开始 | | |
| 71 | +| `ES_VECTOR_SIMILARITY.md` | ES向量技术详解 | | |
| 72 | +| `RUN_SCRIPT_GUIDE.md` | 运行脚本使用指南 | | |
| 73 | +| `MEMORY_MONITORING_UPDATE.md` | 内存监控详细说明 | | |
| 74 | +| `FINAL_SUMMARY.md` | 完整更新总结 | | |
| 75 | + | |
| 76 | +## 🔍 关键特性 | |
| 77 | + | |
| 78 | +### ES向量相似度 | |
| 79 | +```python | |
| 80 | +# 自动应用提权 | |
| 81 | +base_score = knn_result['_score'] | |
| 82 | +boost = knn_result['on_sell_days_boost'] # 0.9~1.1 | |
| 83 | +final_score = base_score * boost | |
| 84 | +``` | |
| 85 | + | |
| 86 | +### 内存监控 | |
| 87 | +```bash | |
| 88 | +# 自动监控每个任务 | |
| 89 | +python3 run_all.py & | |
| 90 | +PID=$! | |
| 91 | +check_memory $PID & # 后台监控 | |
| 92 | + | |
| 93 | +# 日志输出 | |
| 94 | +[2025-10-17 15:20:15] ⚠️ 内存警告!当前使用: 26.45GB (>= 25GB) | |
| 95 | +[2025-10-17 15:24:45] ❌ 内存超限!当前使用: 31.20GB, 强制终止 | |
| 96 | +``` | |
| 97 | + | |
| 98 | +## ⚠️ 重要说明 | |
| 99 | + | |
| 100 | +### 向量相似度 | |
| 101 | +- ✅ 分数已包含 `on_sell_days_boost` 提权 | |
| 102 | +- ✅ 输出到文件和Redis的都是最终分数 | |
| 103 | +- ✅ 应用层无需再次应用提权 | |
| 104 | + | |
| 105 | +### 内存监控 | |
| 106 | +- ⚠️ 默认阈值:25GB警告,30GB终止 | |
| 107 | +- ⚠️ 可在 `run.sh` 中修改阈值 | |
| 108 | +- ⚠️ 监控日志保存在 `logs/memory_monitor.log` | |
| 109 | + | |
| 110 | +### run_all.py 简化 | |
| 111 | +- ❌ 移除了所有 `--only-*`, `--skip-*` 参数 | |
| 112 | +- ✅ 只保留 `--debug` 参数 | |
| 113 | +- ✅ 配置集中在 `offline_config.py` | |
| 114 | + | |
| 115 | +## 🚀 一键运行 | |
| 116 | + | |
| 117 | +```bash | |
| 118 | +# 完整流程(含内存监控) | |
| 119 | +cd /home/tw/recommendation/offline_tasks | |
| 120 | +./run.sh | |
| 121 | + | |
| 122 | +# 输出: | |
| 123 | +# ====================================================================== | |
| 124 | +# 开始运行离线任务 - 2025-10-17 14:00:00 | |
| 125 | +# 内存监控: 警告阈值=25GB, 强制终止阈值=30GB | |
| 126 | +# ====================================================================== | |
| 127 | +# | |
| 128 | +# >>> 步骤1: 调试模式运行(小数据量) | |
| 129 | +# ✓ 调试模式完成 | |
| 130 | +# | |
| 131 | +# >>> 步骤2: 生产模式运行(大数据量) | |
| 132 | +# ✓ 生产模式完成 | |
| 133 | +# | |
| 134 | +# >>> 步骤3: 加载到Redis | |
| 135 | +# ✓ Redis加载完成 | |
| 136 | +# | |
| 137 | +# ====================================================================== | |
| 138 | +# 所有任务完成 - 2025-10-17 16:30:00 | |
| 139 | +# ====================================================================== | |
| 140 | +``` | |
| 141 | + | |
| 142 | +## 🎯 核心改进 | |
| 143 | + | |
| 144 | +1. **更智能**: ES向量 + 上架天数提权 | |
| 145 | +2. **更简单**: 无需参数,一键运行 | |
| 146 | +3. **更安全**: 内存监控保护系统 | |
| 147 | +4. **更规范**: 统一使用logger | |
| 148 | +5. **更完整**: 详细文档和测试工具 | |
| 149 | + | |
| 150 | +--- | |
| 151 | + | |
| 152 | +**更新日期**: 2025-10-17 | |
| 153 | +**版本**: v2.1 | |
| 154 | +**状态**: ✅ 已完成,可投入使用 | |
| 155 | + | ... | ... |
| ... | ... | @@ -0,0 +1,376 @@ |
| 1 | +# 内存监控功能更新 | |
| 2 | + | |
| 3 | +## 更新日期 | |
| 4 | +2025-10-17 | |
| 5 | + | |
| 6 | +## 更新内容 | |
| 7 | + | |
| 8 | +### 1. ✅ 代码规范:移除 print,统一使用 logger | |
| 9 | + | |
| 10 | +#### 检查结果 | |
| 11 | +- ✅ `i2i_content_similar.py` - 已全部使用 logger | |
| 12 | +- ✅ `test_es_connection.py` - print用于测试工具输出(符合预期) | |
| 13 | +- ✅ 所有核心代码已使用 logger | |
| 14 | + | |
| 15 | +### 2. ✅ run.sh 添加内存监控功能 | |
| 16 | + | |
| 17 | +#### 核心功能 | |
| 18 | + | |
| 19 | +**内存监控函数**: | |
| 20 | +```bash | |
| 21 | +check_memory() { | |
| 22 | + local pid=$1 | |
| 23 | + local threshold_warn=25 # 25GB警告阈值 | |
| 24 | + local threshold_kill=30 # 30GB强制kill阈值 | |
| 25 | + | |
| 26 | + while kill -0 $pid 2>/dev/null; do | |
| 27 | + 获取进程内存使用(MB) | |
| 28 | + 转换为GB | |
| 29 | + | |
| 30 | + if 内存 >= 30GB: | |
| 31 | + 打印错误日志到终端和文件 | |
| 32 | + 强制kill进程 | |
| 33 | + break | |
| 34 | + elif 内存 >= 25GB: | |
| 35 | + 打印警告日志到终端和文件 | |
| 36 | + | |
| 37 | + sleep 10秒检查一次 | |
| 38 | + done | |
| 39 | +} | |
| 40 | +``` | |
| 41 | + | |
| 42 | +#### 监控特性 | |
| 43 | + | |
| 44 | +| 特性 | 说明 | | |
| 45 | +|------|------| | |
| 46 | +| **警告阈值** | 25GB - 打印警告但继续运行 | | |
| 47 | +| **终止阈值** | 30GB - 强制kill进程 | | |
| 48 | +| **检查频率** | 每10秒检查一次 | | |
| 49 | +| **日志输出** | 终端 + `logs/memory_monitor.log` | | |
| 50 | +| **自动清理** | 任务完成后自动终止监控 | | |
| 51 | + | |
| 52 | +#### 日志格式 | |
| 53 | + | |
| 54 | +**警告日志**: | |
| 55 | +``` | |
| 56 | +[2025-10-17 14:30:25] ⚠️ 内存警告!当前使用: 26.45GB (>= 25GB), PID=12345 | |
| 57 | +``` | |
| 58 | + | |
| 59 | +**强制终止日志**: | |
| 60 | +``` | |
| 61 | +[2025-10-17 14:35:30] ❌ 内存超限!当前使用: 31.20GB (>= 30GB), 强制终止进程 PID=12345 | |
| 62 | +``` | |
| 63 | + | |
| 64 | +### 3. ✅ 增强的运行流程 | |
| 65 | + | |
| 66 | +#### 更新后的执行流程 | |
| 67 | + | |
| 68 | +```bash | |
| 69 | +#!/bin/bash | |
| 70 | + | |
| 71 | +1. 定义内存监控函数 | |
| 72 | +2. 清理旧进程和输出 | |
| 73 | +3. 创建logs目录 | |
| 74 | +4. 显示开始信息(包含监控阈值) | |
| 75 | + | |
| 76 | +# 调试模式 | |
| 77 | +5. 启动调试任务(后台) | |
| 78 | +6. 启动内存监控(后台) | |
| 79 | +7. 等待任务完成 | |
| 80 | +8. 终止监控进程 | |
| 81 | +9. 检查退出码 | |
| 82 | + | |
| 83 | +# 生产模式 | |
| 84 | +10. 启动生产任务(后台) | |
| 85 | +11. 启动内存监控(后台) | |
| 86 | +12. 等待任务完成 | |
| 87 | +13. 终止监控进程 | |
| 88 | +14. 检查退出码 | |
| 89 | + | |
| 90 | +# 加载Redis | |
| 91 | +15. 加载索引到Redis | |
| 92 | +16. 检查退出码 | |
| 93 | + | |
| 94 | +17. 显示完成信息 | |
| 95 | +``` | |
| 96 | + | |
| 97 | +### 4. ✅ 新增文件 | |
| 98 | + | |
| 99 | +| 文件 | 说明 | | |
| 100 | +|------|------| | |
| 101 | +| `run.sh` | 更新:添加内存监控 | | |
| 102 | +| `RUN_SCRIPT_GUIDE.md` | 新增:运行脚本使用指南 | | |
| 103 | +| `test_memory_monitor.sh` | 新增:内存监控测试脚本 | | |
| 104 | +| `MEMORY_MONITORING_UPDATE.md` | 新增:本文档 | | |
| 105 | + | |
| 106 | +## 使用指南 | |
| 107 | + | |
| 108 | +### 基本使用 | |
| 109 | + | |
| 110 | +```bash | |
| 111 | +# 1. 运行脚本(自动监控内存) | |
| 112 | +cd /home/tw/recommendation/offline_tasks | |
| 113 | +./run.sh | |
| 114 | + | |
| 115 | +# 2. 查看监控日志 | |
| 116 | +tail -f logs/memory_monitor.log | |
| 117 | + | |
| 118 | +# 3. 查看系统内存 | |
| 119 | +free -h | |
| 120 | +``` | |
| 121 | + | |
| 122 | +### 测试监控功能 | |
| 123 | + | |
| 124 | +```bash | |
| 125 | +# 运行测试脚本 | |
| 126 | +./test_memory_monitor.sh | |
| 127 | +``` | |
| 128 | + | |
| 129 | +### 自定义阈值 | |
| 130 | + | |
| 131 | +编辑 `run.sh` 第8-9行: | |
| 132 | +```bash | |
| 133 | +local threshold_warn=25 # 修改警告阈值 | |
| 134 | +local threshold_kill=30 # 修改强制kill阈值 | |
| 135 | +``` | |
| 136 | + | |
| 137 | +## 技术细节 | |
| 138 | + | |
| 139 | +### 内存获取 | |
| 140 | + | |
| 141 | +```bash | |
| 142 | +# 获取进程内存(RSS,单位KB) | |
| 143 | +ps -p $pid -o rss= | |
| 144 | + | |
| 145 | +# 转换为MB | |
| 146 | +mem_mb=$(ps -p $pid -o rss= | awk '{print int($1/1024)}') | |
| 147 | + | |
| 148 | +# 转换为GB | |
| 149 | +mem_gb=$(echo "scale=2; $mem_mb/1024" | bc) | |
| 150 | +``` | |
| 151 | + | |
| 152 | +### 进程检查 | |
| 153 | + | |
| 154 | +```bash | |
| 155 | +# 检查进程是否存在 | |
| 156 | +kill -0 $pid 2>/dev/null | |
| 157 | + | |
| 158 | +# 返回值: | |
| 159 | +# 0 - 进程存在 | |
| 160 | +# 非0 - 进程不存在 | |
| 161 | +``` | |
| 162 | + | |
| 163 | +### 强制终止 | |
| 164 | + | |
| 165 | +```bash | |
| 166 | +# 发送SIGKILL信号 | |
| 167 | +kill -9 $pid | |
| 168 | + | |
| 169 | +# 特点: | |
| 170 | +# - 立即终止,不可捕获 | |
| 171 | +# - 不执行清理代码 | |
| 172 | +# - 确保进程被终止 | |
| 173 | +``` | |
| 174 | + | |
| 175 | +## 输出示例 | |
| 176 | + | |
| 177 | +### 正常运行(内存未超限) | |
| 178 | + | |
| 179 | +``` | |
| 180 | +====================================================================== | |
| 181 | +开始运行离线任务 - 2025-10-17 14:00:00 | |
| 182 | +内存监控: 警告阈值=25GB, 强制终止阈值=30GB | |
| 183 | +====================================================================== | |
| 184 | + | |
| 185 | +>>> 步骤1: 调试模式运行(小数据量) | |
| 186 | +调试任务 PID: 12345 | |
| 187 | +✓ 调试模式完成 | |
| 188 | + | |
| 189 | +>>> 步骤2: 生产模式运行(大数据量) | |
| 190 | +生产任务 PID: 12346 | |
| 191 | +✓ 生产模式完成 | |
| 192 | + | |
| 193 | +>>> 步骤3: 加载到Redis | |
| 194 | +✓ Redis加载完成 | |
| 195 | + | |
| 196 | +====================================================================== | |
| 197 | +所有任务完成 - 2025-10-17 16:30:00 | |
| 198 | +====================================================================== | |
| 199 | +``` | |
| 200 | + | |
| 201 | +### 内存警告(25GB-30GB) | |
| 202 | + | |
| 203 | +``` | |
| 204 | +>>> 步骤2: 生产模式运行(大数据量) | |
| 205 | +生产任务 PID: 12346 | |
| 206 | +[2025-10-17 15:20:15] ⚠️ 内存警告!当前使用: 26.45GB (>= 25GB), PID=12346 | |
| 207 | +[2025-10-17 15:22:30] ⚠️ 内存警告!当前使用: 27.80GB (>= 25GB), PID=12346 | |
| 208 | +[2025-10-17 15:24:45] ⚠️ 内存警告!当前使用: 28.95GB (>= 25GB), PID=12346 | |
| 209 | +✓ 生产模式完成 | |
| 210 | +``` | |
| 211 | + | |
| 212 | +### 内存超限(>=30GB) | |
| 213 | + | |
| 214 | +``` | |
| 215 | +>>> 步骤2: 生产模式运行(大数据量) | |
| 216 | +生产任务 PID: 12346 | |
| 217 | +[2025-10-17 15:20:15] ⚠️ 内存警告!当前使用: 26.45GB (>= 25GB), PID=12346 | |
| 218 | +[2025-10-17 15:22:30] ⚠️ 内存警告!当前使用: 28.80GB (>= 25GB), PID=12346 | |
| 219 | +[2025-10-17 15:24:45] ❌ 内存超限!当前使用: 31.20GB (>= 30GB), 强制终止进程 PID=12346 | |
| 220 | +✗ 生产模式失败,退出码: 137 | |
| 221 | +``` | |
| 222 | + | |
| 223 | +## 监控日志示例 | |
| 224 | + | |
| 225 | +`logs/memory_monitor.log`: | |
| 226 | +``` | |
| 227 | +[2025-10-17 15:20:15] ⚠️ 内存警告!当前使用: 26.45GB (>= 25GB), PID=12346 | |
| 228 | +[2025-10-17 15:22:30] ⚠️ 内存警告!当前使用: 28.80GB (>= 25GB), PID=12346 | |
| 229 | +[2025-10-17 15:24:45] ❌ 内存超限!当前使用: 31.20GB (>= 30GB), 强制终止进程 PID=12346 | |
| 230 | +``` | |
| 231 | + | |
| 232 | +## 故障处理 | |
| 233 | + | |
| 234 | +### 内存持续增长 | |
| 235 | + | |
| 236 | +**现象**: 警告日志频繁出现,内存持续增长 | |
| 237 | + | |
| 238 | +**原因**: | |
| 239 | +- 数据量过大 | |
| 240 | +- 内存泄漏 | |
| 241 | +- 批处理大小不合理 | |
| 242 | + | |
| 243 | +**解决方案**: | |
| 244 | +1. 减小批处理大小 | |
| 245 | +2. 增加垃圾回收频率 | |
| 246 | +3. 优化算法减少内存占用 | |
| 247 | +4. 考虑分批运行 | |
| 248 | + | |
| 249 | +### 进程被误杀 | |
| 250 | + | |
| 251 | +**现象**: 任务未完成就被终止 | |
| 252 | + | |
| 253 | +**原因**: | |
| 254 | +- 阈值设置过低 | |
| 255 | +- 系统其他进程占用内存 | |
| 256 | + | |
| 257 | +**解决方案**: | |
| 258 | +1. 提高阈值(修改 run.sh) | |
| 259 | +2. 优化代码减少内存使用 | |
| 260 | +3. 关闭不必要的系统进程 | |
| 261 | + | |
| 262 | +### 监控不生效 | |
| 263 | + | |
| 264 | +**检查清单**: | |
| 265 | +- [ ] `bc` 命令是否安装:`which bc` | |
| 266 | +- [ ] 脚本是否有执行权限:`ls -l run.sh` | |
| 267 | +- [ ] logs目录是否存在:`ls -ld logs/` | |
| 268 | +- [ ] 进程是否在后台运行:`ps aux | grep run_all` | |
| 269 | + | |
| 270 | +## 性能影响 | |
| 271 | + | |
| 272 | +### 监控开销 | |
| 273 | + | |
| 274 | +| 项目 | 影响 | | |
| 275 | +|------|------| | |
| 276 | +| CPU | < 0.1% (每10秒运行一次ps命令) | | |
| 277 | +| 内存 | < 10MB (监控脚本本身) | | |
| 278 | +| 磁盘I/O | 极小 (仅写日志) | | |
| 279 | + | |
| 280 | +### 建议 | |
| 281 | + | |
| 282 | +- ✅ 检查频率10秒合理,不建议小于5秒 | |
| 283 | +- ✅ 警告阈值25GB为系统总内存的合理比例 | |
| 284 | +- ✅ 终止阈值30GB留有5GB缓冲空间 | |
| 285 | +- ⚠️ 根据实际情况调整阈值 | |
| 286 | + | |
| 287 | +## 最佳实践 | |
| 288 | + | |
| 289 | +### 1. 定期查看日志 | |
| 290 | +```bash | |
| 291 | +# 每天检查 | |
| 292 | +cat logs/memory_monitor.log | |
| 293 | + | |
| 294 | +# 统计警告次数 | |
| 295 | +grep "⚠️" logs/memory_monitor.log | wc -l | |
| 296 | + | |
| 297 | +# 统计终止次数 | |
| 298 | +grep "❌" logs/memory_monitor.log | wc -l | |
| 299 | +``` | |
| 300 | + | |
| 301 | +### 2. 设置定时任务 | |
| 302 | +```bash | |
| 303 | +# 每周一凌晨2点运行 | |
| 304 | +0 2 * * 1 /home/tw/recommendation/offline_tasks/run.sh >> /var/log/offline_tasks.log 2>&1 | |
| 305 | +``` | |
| 306 | + | |
| 307 | +### 3. 配置告警 | |
| 308 | +```bash | |
| 309 | +# 在 run.sh 末尾添加 | |
| 310 | +if grep -q "❌" logs/memory_monitor.log; then | |
| 311 | + echo "内存超限告警" | mail -s "[告警] 离线任务内存超限" admin@example.com | |
| 312 | +fi | |
| 313 | +``` | |
| 314 | + | |
| 315 | +### 4. 监控系统资源 | |
| 316 | +```bash | |
| 317 | +# 安装监控工具 | |
| 318 | +apt install htop sysstat | |
| 319 | + | |
| 320 | +# 实时监控 | |
| 321 | +htop -p $(pgrep -f run_all.py) | |
| 322 | + | |
| 323 | +# 查看历史 | |
| 324 | +sar -r 1 10 # 内存使用情况 | |
| 325 | +``` | |
| 326 | + | |
| 327 | +## 对比 | |
| 328 | + | |
| 329 | +### 更新前 | |
| 330 | +```bash | |
| 331 | +# 无内存监控 | |
| 332 | +python3 run_all.py --lookback_days 730 --top_n 50 | |
| 333 | + | |
| 334 | +# 问题: | |
| 335 | +# - 内存可能无限增长 | |
| 336 | +# - OOM导致系统崩溃 | |
| 337 | +# - 无法及时发现问题 | |
| 338 | +``` | |
| 339 | + | |
| 340 | +### 更新后 | |
| 341 | +```bash | |
| 342 | +# 自动内存监控 | |
| 343 | +./run.sh | |
| 344 | + | |
| 345 | +# 优势: | |
| 346 | +# ✅ 25GB警告提醒 | |
| 347 | +# ✅ 30GB自动终止 | |
| 348 | +# ✅ 详细日志记录 | |
| 349 | +# ✅ 保护系统稳定 | |
| 350 | +``` | |
| 351 | + | |
| 352 | +## 总结 | |
| 353 | + | |
| 354 | +本次更新实现了: | |
| 355 | + | |
| 356 | +1. ✅ **代码规范化**: 统一使用logger,移除print | |
| 357 | +2. ✅ **内存监控**: 25GB警告,30GB强制终止 | |
| 358 | +3. ✅ **自动化运行**: 集成监控到运行流程 | |
| 359 | +4. ✅ **日志记录**: 详细的监控日志 | |
| 360 | +5. ✅ **测试工具**: 提供测试脚本验证功能 | |
| 361 | +6. ✅ **完整文档**: 使用指南和故障处理 | |
| 362 | + | |
| 363 | +### 核心价值 | |
| 364 | + | |
| 365 | +- 🛡️ **保护系统**: 防止内存溢出导致系统崩溃 | |
| 366 | +- 📊 **实时监控**: 每10秒检查一次内存使用 | |
| 367 | +- 🔔 **及时告警**: 25GB警告,30GB终止 | |
| 368 | +- 📝 **日志完整**: 所有监控事件都有记录 | |
| 369 | +- 🔧 **易于调整**: 阈值和频率可轻松修改 | |
| 370 | + | |
| 371 | +--- | |
| 372 | + | |
| 373 | +**更新完成时间**: 2025-10-17 | |
| 374 | +**状态**: ✅ 已完成,可投入使用 | |
| 375 | +**建议**: 先在测试环境验证后再用于生产 | |
| 376 | + | ... | ... |
| ... | ... | @@ -0,0 +1,304 @@ |
| 1 | +# run.sh 运行脚本使用指南 | |
| 2 | + | |
| 3 | +## 概述 | |
| 4 | + | |
| 5 | +`run.sh` 是一个自动化运行脚本,集成了内存监控功能,确保离线任务安全高效运行。 | |
| 6 | + | |
| 7 | +## 主要特性 | |
| 8 | + | |
| 9 | +### 1. 内存监控 | |
| 10 | +- **警告阈值**: 25GB - 打印警告日志 | |
| 11 | +- **强制终止阈值**: 30GB - 自动kill进程 | |
| 12 | +- **检查频率**: 每10秒检查一次 | |
| 13 | +- **日志文件**: `logs/memory_monitor.log` | |
| 14 | + | |
| 15 | +### 2. 任务流程 | |
| 16 | +1. 清理旧进程和输出 | |
| 17 | +2. 运行调试模式(小数据量测试) | |
| 18 | +3. 运行生产模式(大数据量) | |
| 19 | +4. 加载索引到Redis | |
| 20 | + | |
| 21 | +### 3. 错误处理 | |
| 22 | +- 任何步骤失败会立即退出 | |
| 23 | +- 显示详细的退出码 | |
| 24 | +- 保存完整日志 | |
| 25 | + | |
| 26 | +## 使用方法 | |
| 27 | + | |
| 28 | +### 基本运行 | |
| 29 | +```bash | |
| 30 | +cd /home/tw/recommendation/offline_tasks | |
| 31 | +./run.sh | |
| 32 | +``` | |
| 33 | + | |
| 34 | +### 查看实时输出 | |
| 35 | +```bash | |
| 36 | +./run.sh | tee logs/run_$(date +%Y%m%d_%H%M%S).log | |
| 37 | +``` | |
| 38 | + | |
| 39 | +### 后台运行 | |
| 40 | +```bash | |
| 41 | +nohup ./run.sh > logs/run_$(date +%Y%m%d_%H%M%S).log 2>&1 & | |
| 42 | +``` | |
| 43 | + | |
| 44 | +## 内存监控说明 | |
| 45 | + | |
| 46 | +### 监控逻辑 | |
| 47 | + | |
| 48 | +```bash | |
| 49 | +check_memory() { | |
| 50 | + local pid=$1 | |
| 51 | + local threshold_warn=25 # 25GB警告 | |
| 52 | + local threshold_kill=30 # 30GB强制kill | |
| 53 | + | |
| 54 | + while 进程运行中; do | |
| 55 | + 获取内存使用 | |
| 56 | + | |
| 57 | + if 内存 >= 30GB: | |
| 58 | + 打印错误日志 | |
| 59 | + 强制终止进程 | |
| 60 | + break | |
| 61 | + elif 内存 >= 25GB: | |
| 62 | + 打印警告日志 | |
| 63 | + | |
| 64 | + sleep 10秒 | |
| 65 | + done | |
| 66 | +} | |
| 67 | +``` | |
| 68 | + | |
| 69 | +### 日志格式 | |
| 70 | + | |
| 71 | +**警告日志**: | |
| 72 | +``` | |
| 73 | +[2025-10-17 14:30:25] ⚠️ 内存警告!当前使用: 26.45GB (>= 25GB), PID=12345 | |
| 74 | +``` | |
| 75 | + | |
| 76 | +**强制终止日志**: | |
| 77 | +``` | |
| 78 | +[2025-10-17 14:35:30] ❌ 内存超限!当前使用: 31.20GB (>= 30GB), 强制终止进程 PID=12345 | |
| 79 | +``` | |
| 80 | + | |
| 81 | +### 查看监控日志 | |
| 82 | +```bash | |
| 83 | +# 实时查看 | |
| 84 | +tail -f logs/memory_monitor.log | |
| 85 | + | |
| 86 | +# 查看历史 | |
| 87 | +cat logs/memory_monitor.log | |
| 88 | +``` | |
| 89 | + | |
| 90 | +## 运行流程 | |
| 91 | + | |
| 92 | +### 步骤1: 调试模式 | |
| 93 | +```bash | |
| 94 | +python3 run_all.py --debug | |
| 95 | +``` | |
| 96 | +- 使用默认参数(见 `offline_config.py`) | |
| 97 | +- 输出保存到 `output_debug/` | |
| 98 | +- 启动内存监控 | |
| 99 | + | |
| 100 | +### 步骤2: 生产模式 | |
| 101 | +```bash | |
| 102 | +python3 run_all.py --debug | |
| 103 | +``` | |
| 104 | +- 生成完整索引 | |
| 105 | +- 输出保存到 `output/` | |
| 106 | +- 启动内存监控 | |
| 107 | + | |
| 108 | +### 步骤3: 加载Redis | |
| 109 | +```bash | |
| 110 | +python3 scripts/load_index_to_redis.py --redis-host localhost | |
| 111 | +``` | |
| 112 | +- 加载所有生成的索引 | |
| 113 | +- 包括新增的内容相似索引 | |
| 114 | + | |
| 115 | +## 输出示例 | |
| 116 | + | |
| 117 | +``` | |
| 118 | +====================================================================== | |
| 119 | +开始运行离线任务 - 2025-10-17 14:00:00 | |
| 120 | +内存监控: 警告阈值=25GB, 强制终止阈值=30GB | |
| 121 | +====================================================================== | |
| 122 | + | |
| 123 | +>>> 步骤1: 调试模式运行(小数据量) | |
| 124 | +调试任务 PID: 12345 | |
| 125 | +✓ 调试模式完成 | |
| 126 | + | |
| 127 | +>>> 步骤2: 生产模式运行(大数据量) | |
| 128 | +生产任务 PID: 12346 | |
| 129 | +[2025-10-17 14:30:25] ⚠️ 内存警告!当前使用: 26.45GB (>= 25GB), PID=12346 | |
| 130 | +✓ 生产模式完成 | |
| 131 | + | |
| 132 | +>>> 步骤3: 加载到Redis | |
| 133 | +✓ Redis加载完成 | |
| 134 | + | |
| 135 | +====================================================================== | |
| 136 | +所有任务完成 - 2025-10-17 16:30:00 | |
| 137 | +====================================================================== | |
| 138 | +``` | |
| 139 | + | |
| 140 | +## 自定义配置 | |
| 141 | + | |
| 142 | +### 修改内存阈值 | |
| 143 | + | |
| 144 | +编辑 `run.sh` 中的以下行: | |
| 145 | +```bash | |
| 146 | +local threshold_warn=25 # 修改警告阈值 | |
| 147 | +local threshold_kill=30 # 修改强制kill阈值 | |
| 148 | +``` | |
| 149 | + | |
| 150 | +### 修改检查频率 | |
| 151 | + | |
| 152 | +编辑 `run.sh` 中的以下行: | |
| 153 | +```bash | |
| 154 | +sleep 10 # 修改为其他秒数 | |
| 155 | +``` | |
| 156 | + | |
| 157 | +### 跳过调试模式 | |
| 158 | + | |
| 159 | +注释掉步骤1相关代码: | |
| 160 | +```bash | |
| 161 | +# # 3. 调试模式运行(小数据量) | |
| 162 | +# echo "" | |
| 163 | +# echo ">>> 步骤1: 调试模式运行(小数据量)" | |
| 164 | +# python3 run_all.py --debug & | |
| 165 | +# ... | |
| 166 | +``` | |
| 167 | + | |
| 168 | +### 修改Redis配置 | |
| 169 | + | |
| 170 | +修改步骤3的参数: | |
| 171 | +```bash | |
| 172 | +python3 scripts/load_index_to_redis.py \ | |
| 173 | + --redis-host your-redis-host \ | |
| 174 | + --redis-port 6379 \ | |
| 175 | + --redis-db 0 | |
| 176 | +``` | |
| 177 | + | |
| 178 | +## 故障排查 | |
| 179 | + | |
| 180 | +### 内存持续超限 | |
| 181 | + | |
| 182 | +**原因**: | |
| 183 | +- 数据量太大 | |
| 184 | +- 内存泄漏 | |
| 185 | +- 并发任务过多 | |
| 186 | + | |
| 187 | +**解决方案**: | |
| 188 | +1. 增加内存阈值(临时方案) | |
| 189 | +2. 优化代码减少内存占用 | |
| 190 | +3. 分批处理数据 | |
| 191 | +4. 使用增量更新 | |
| 192 | + | |
| 193 | +### 进程被意外终止 | |
| 194 | + | |
| 195 | +**检查日志**: | |
| 196 | +```bash | |
| 197 | +# 查看监控日志 | |
| 198 | +cat logs/memory_monitor.log | |
| 199 | + | |
| 200 | +# 查看任务日志 | |
| 201 | +ls -lht logs/ | |
| 202 | +cat logs/run_all_*.log | |
| 203 | +``` | |
| 204 | + | |
| 205 | +### 任务失败 | |
| 206 | + | |
| 207 | +**查看退出码**: | |
| 208 | +- 0: 成功 | |
| 209 | +- 1: 一般错误 | |
| 210 | +- 137: 被kill信号终止(可能是内存超限) | |
| 211 | +- 其他: 查看具体错误信息 | |
| 212 | + | |
| 213 | +## 监控建议 | |
| 214 | + | |
| 215 | +### 1. 添加系统监控 | |
| 216 | +```bash | |
| 217 | +# 安装监控工具 | |
| 218 | +apt install htop iotop | |
| 219 | + | |
| 220 | +# 实时监控 | |
| 221 | +htop -p $(pgrep -f run_all.py) | |
| 222 | +``` | |
| 223 | + | |
| 224 | +### 2. 设置告警 | |
| 225 | +```bash | |
| 226 | +# 配置邮件告警 | |
| 227 | +if [ $PROD_EXIT_CODE -ne 0 ]; then | |
| 228 | + echo "任务失败" | mail -s "离线任务告警" admin@example.com | |
| 229 | +fi | |
| 230 | +``` | |
| 231 | + | |
| 232 | +### 3. 定时任务 | |
| 233 | +```bash | |
| 234 | +# 添加到crontab | |
| 235 | +0 2 * * * /home/tw/recommendation/offline_tasks/run.sh >> /var/log/offline_tasks.log 2>&1 | |
| 236 | +``` | |
| 237 | + | |
| 238 | +## 性能优化 | |
| 239 | + | |
| 240 | +### 内存优化建议 | |
| 241 | + | |
| 242 | +1. **分批处理** | |
| 243 | + ```python | |
| 244 | + # 在代码中使用batch处理 | |
| 245 | + batch_size = 1000 | |
| 246 | + for i in range(0, len(items), batch_size): | |
| 247 | + batch = items[i:i+batch_size] | |
| 248 | + process(batch) | |
| 249 | + ``` | |
| 250 | + | |
| 251 | +2. **及时释放** | |
| 252 | + ```python | |
| 253 | + import gc | |
| 254 | + del large_object | |
| 255 | + gc.collect() | |
| 256 | + ``` | |
| 257 | + | |
| 258 | +3. **使用生成器** | |
| 259 | + ```python | |
| 260 | + def process_items(): | |
| 261 | + for item in items: | |
| 262 | + yield process(item) | |
| 263 | + ``` | |
| 264 | + | |
| 265 | +## 日志管理 | |
| 266 | + | |
| 267 | +### 日志文件 | |
| 268 | +- `logs/memory_monitor.log` - 内存监控日志 | |
| 269 | +- `logs/run_all_YYYYMMDD.log` - 任务运行日志 | |
| 270 | +- `output/` - 生成的索引文件 | |
| 271 | +- `output_debug/` - 调试模式输出 | |
| 272 | + | |
| 273 | +### 清理旧日志 | |
| 274 | +```bash | |
| 275 | +# 保留最近7天 | |
| 276 | +find logs/ -name "*.log" -mtime +7 -delete | |
| 277 | + | |
| 278 | +# 压缩旧日志 | |
| 279 | +find logs/ -name "*.log" -mtime +3 -exec gzip {} \; | |
| 280 | +``` | |
| 281 | + | |
| 282 | +## 安全注意事项 | |
| 283 | + | |
| 284 | +1. **权限**: 确保脚本有执行权限 `chmod +x run.sh` | |
| 285 | +2. **路径**: 使用绝对路径避免混淆 | |
| 286 | +3. **清理**: 脚本会清理旧进程,确保没有重要进程被误杀 | |
| 287 | +4. **备份**: 脚本会删除output目录,请提前备份重要数据 | |
| 288 | + | |
| 289 | +## 总结 | |
| 290 | + | |
| 291 | +`run.sh` 提供了: | |
| 292 | +- ✅ 自动化运行流程 | |
| 293 | +- ✅ 内存监控保护 | |
| 294 | +- ✅ 详细日志记录 | |
| 295 | +- ✅ 错误处理机制 | |
| 296 | +- ✅ 进度显示 | |
| 297 | + | |
| 298 | +建议在生产环境使用前先在测试环境验证。 | |
| 299 | + | |
| 300 | +--- | |
| 301 | + | |
| 302 | +**更新时间**: 2025-10-17 | |
| 303 | +**版本**: v2.0 | |
| 304 | + | ... | ... |
offline_tasks/run.sh
| 1 | +#!/bin/bash | |
| 2 | + | |
| 1 | 3 | cd /home/tw/recommendation/offline_tasks |
| 2 | 4 | |
| 5 | +# 内存监控函数 | |
| 6 | +check_memory() { | |
| 7 | + local pid=$1 | |
| 8 | + local threshold_warn=25 # 25GB警告阈值 | |
| 9 | + local threshold_kill=30 # 30GB强制kill阈值 | |
| 10 | + | |
| 11 | + while kill -0 $pid 2>/dev/null; do | |
| 12 | + # 获取进程内存使用(MB) | |
| 13 | + local mem_mb=$(ps -p $pid -o rss= 2>/dev/null | awk '{print int($1/1024)}') | |
| 14 | + | |
| 15 | + if [ -n "$mem_mb" ]; then | |
| 16 | + local mem_gb=$(echo "scale=2; $mem_mb/1024" | bc) | |
| 17 | + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') | |
| 18 | + | |
| 19 | + if [ $(echo "$mem_gb >= $threshold_kill" | bc) -eq 1 ]; then | |
| 20 | + echo "[$timestamp] ❌ 内存超限!当前使用: ${mem_gb}GB (>= ${threshold_kill}GB), 强制终止进程 PID=$pid" | tee -a logs/memory_monitor.log | |
| 21 | + kill -9 $pid | |
| 22 | + break | |
| 23 | + elif [ $(echo "$mem_gb >= $threshold_warn" | bc) -eq 1 ]; then | |
| 24 | + echo "[$timestamp] ⚠️ 内存警告!当前使用: ${mem_gb}GB (>= ${threshold_warn}GB), PID=$pid" | tee -a logs/memory_monitor.log | |
| 25 | + fi | |
| 26 | + fi | |
| 27 | + | |
| 28 | + sleep 10 # 每10秒检查一次 | |
| 29 | + done | |
| 30 | +} | |
| 31 | + | |
| 3 | 32 | # # 查看配置指南 |
| 4 | 33 | # cat UPDATE_CONFIG_GUIDE.md |
| 5 | 34 | |
| 6 | 35 | # 2. 测试连接 |
| 7 | 36 | # python3 test_connection.py |
| 8 | 37 | |
| 9 | -ps -ef|grep run_all.py | awk '{print $2}' | xargs kill -9 | |
| 10 | -ps -ef|grep recommendation | awk '{print $2}' | xargs kill -9 | |
| 11 | -rm output/* -rf | |
| 12 | -rm logs/* -rf | |
| 38 | +# 清理旧进程 | |
| 39 | +ps -ef|grep run_all.py | awk '{print $2}' | xargs kill -9 2>/dev/null | |
| 40 | +ps -ef|grep recommendation | awk '{print $2}' | xargs kill -9 2>/dev/null | |
| 41 | +rm output/* -rf 2>/dev/null | |
| 42 | +rm logs/* -rf 2>/dev/null | |
| 43 | +mkdir -p logs | |
| 13 | 44 | |
| 45 | +echo "======================================================================" | |
| 46 | +echo "开始运行离线任务 - $(date '+%Y-%m-%d %H:%M:%S')" | |
| 47 | +echo "内存监控: 警告阈值=25GB, 强制终止阈值=30GB" | |
| 48 | +echo "======================================================================" | |
| 14 | 49 | |
| 15 | 50 | # 3. 调试模式运行(小数据量) |
| 16 | -python3 run_all.py --lookback_days 7 --top_n 10 --debug | |
| 51 | +echo "" | |
| 52 | +echo ">>> 步骤1: 调试模式运行(小数据量)" | |
| 53 | +python3 run_all.py --debug & | |
| 54 | +PID_DEBUG=$! | |
| 55 | +echo "调试任务 PID: $PID_DEBUG" | |
| 56 | + | |
| 57 | +# 启动内存监控 | |
| 58 | +check_memory $PID_DEBUG & | |
| 59 | +MONITOR_PID_1=$! | |
| 60 | + | |
| 61 | +# 等待调试任务完成 | |
| 62 | +wait $PID_DEBUG | |
| 63 | +DEBUG_EXIT_CODE=$? | |
| 64 | +kill $MONITOR_PID_1 2>/dev/null | |
| 65 | + | |
| 66 | +if [ $DEBUG_EXIT_CODE -eq 0 ]; then | |
| 67 | + echo "✓ 调试模式完成" | |
| 68 | + mv output output_debug 2>/dev/null | |
| 69 | + mkdir output | |
| 70 | +else | |
| 71 | + echo "✗ 调试模式失败,退出码: $DEBUG_EXIT_CODE" | |
| 72 | + exit 1 | |
| 73 | +fi | |
| 17 | 74 | |
| 18 | -mv output output_debug | |
| 19 | -mkdir output | |
| 75 | +# 4. 生产模式运行(大数据量) | |
| 76 | +echo "" | |
| 77 | +echo ">>> 步骤2: 生产模式运行(大数据量)" | |
| 78 | +python3 run_all.py --debug & | |
| 79 | +PID_PROD=$! | |
| 80 | +echo "生产任务 PID: $PID_PROD" | |
| 20 | 81 | |
| 21 | -# # 4. 生产模式运行(大数据量) | |
| 22 | -python3 run_all.py --lookback_days 730 --top_n 50 --debug | |
| 82 | +# 启动内存监控 | |
| 83 | +check_memory $PID_PROD & | |
| 84 | +MONITOR_PID_2=$! | |
| 85 | + | |
| 86 | +# 等待生产任务完成 | |
| 87 | +wait $PID_PROD | |
| 88 | +PROD_EXIT_CODE=$? | |
| 89 | +kill $MONITOR_PID_2 2>/dev/null | |
| 90 | + | |
| 91 | +if [ $PROD_EXIT_CODE -eq 0 ]; then | |
| 92 | + echo "✓ 生产模式完成" | |
| 93 | +else | |
| 94 | + echo "✗ 生产模式失败,退出码: $PROD_EXIT_CODE" | |
| 95 | + exit 1 | |
| 96 | +fi | |
| 23 | 97 | |
| 24 | 98 | # 5. 加载到Redis |
| 99 | +echo "" | |
| 100 | +echo ">>> 步骤3: 加载到Redis" | |
| 25 | 101 | python3 scripts/load_index_to_redis.py --redis-host localhost |
| 102 | +LOAD_EXIT_CODE=$? | |
| 103 | + | |
| 104 | +if [ $LOAD_EXIT_CODE -eq 0 ]; then | |
| 105 | + echo "✓ Redis加载完成" | |
| 106 | +else | |
| 107 | + echo "✗ Redis加载失败,退出码: $LOAD_EXIT_CODE" | |
| 108 | + exit 1 | |
| 109 | +fi | |
| 110 | + | |
| 111 | +echo "" | |
| 112 | +echo "======================================================================" | |
| 113 | +echo "所有任务完成 - $(date '+%Y-%m-%d %H:%M:%S')" | |
| 114 | +echo "======================================================================" | |
| 26 | 115 | |
| 27 | 116 | ... | ... |
| ... | ... | @@ -0,0 +1,85 @@ |
| 1 | +#!/bin/bash | |
| 2 | + | |
| 3 | +# 测试内存监控功能 | |
| 4 | + | |
| 5 | +cd /home/tw/recommendation/offline_tasks | |
| 6 | +mkdir -p logs | |
| 7 | + | |
| 8 | +echo "======================================================================" | |
| 9 | +echo "测试内存监控功能" | |
| 10 | +echo "======================================================================" | |
| 11 | + | |
| 12 | +# 内存监控函数(从run.sh复制) | |
| 13 | +check_memory() { | |
| 14 | + local pid=$1 | |
| 15 | + local threshold_warn=25 # 25GB警告阈值 | |
| 16 | + local threshold_kill=30 # 30GB强制kill阈值 | |
| 17 | + | |
| 18 | + echo "启动内存监控: PID=$pid, 警告阈值=${threshold_warn}GB, 终止阈值=${threshold_kill}GB" | |
| 19 | + | |
| 20 | + while kill -0 $pid 2>/dev/null; do | |
| 21 | + # 获取进程内存使用(MB) | |
| 22 | + local mem_mb=$(ps -p $pid -o rss= 2>/dev/null | awk '{print int($1/1024)}') | |
| 23 | + | |
| 24 | + if [ -n "$mem_mb" ]; then | |
| 25 | + local mem_gb=$(echo "scale=2; $mem_mb/1024" | bc) | |
| 26 | + local timestamp=$(date '+%Y-%m-%d %H:%M:%S') | |
| 27 | + | |
| 28 | + # 显示当前内存使用 | |
| 29 | + echo "[$timestamp] 📊 当前内存: ${mem_gb}GB, PID=$pid" | |
| 30 | + | |
| 31 | + if [ $(echo "$mem_gb >= $threshold_kill" | bc) -eq 1 ]; then | |
| 32 | + echo "[$timestamp] ❌ 内存超限!当前使用: ${mem_gb}GB (>= ${threshold_kill}GB), 强制终止进程 PID=$pid" | tee -a logs/memory_monitor.log | |
| 33 | + kill -9 $pid | |
| 34 | + break | |
| 35 | + elif [ $(echo "$mem_gb >= $threshold_warn" | bc) -eq 1 ]; then | |
| 36 | + echo "[$timestamp] ⚠️ 内存警告!当前使用: ${mem_gb}GB (>= ${threshold_warn}GB), PID=$pid" | tee -a logs/memory_monitor.log | |
| 37 | + fi | |
| 38 | + fi | |
| 39 | + | |
| 40 | + sleep 2 # 测试时每2秒检查一次 | |
| 41 | + done | |
| 42 | + | |
| 43 | + echo "内存监控结束: PID=$pid" | |
| 44 | +} | |
| 45 | + | |
| 46 | +# 模拟占用内存的测试进程 | |
| 47 | +echo "" | |
| 48 | +echo ">>> 测试1: 启动一个简单进程(低内存)" | |
| 49 | +sleep 30 & | |
| 50 | +TEST_PID=$! | |
| 51 | +echo "测试进程 PID: $TEST_PID" | |
| 52 | + | |
| 53 | +# 启动监控 | |
| 54 | +check_memory $TEST_PID & | |
| 55 | +MONITOR_PID=$! | |
| 56 | + | |
| 57 | +# 等待测试进程 | |
| 58 | +sleep 5 | |
| 59 | +kill $TEST_PID 2>/dev/null | |
| 60 | +wait $TEST_PID 2>/dev/null | |
| 61 | +kill $MONITOR_PID 2>/dev/null | |
| 62 | + | |
| 63 | +echo "✓ 测试1完成" | |
| 64 | +echo "" | |
| 65 | + | |
| 66 | +# 测试2: 查看当前Python进程内存 | |
| 67 | +echo ">>> 测试2: 查看当前运行的Python进程内存" | |
| 68 | +ps aux | grep python | grep -v grep | awk '{printf "PID: %s, 内存: %.2fGB, 命令: %s\n", $2, $6/1024/1024, $11}' | |
| 69 | +echo "" | |
| 70 | + | |
| 71 | +# 测试3: 显示系统总内存 | |
| 72 | +echo ">>> 测试3: 系统内存信息" | |
| 73 | +free -h | |
| 74 | +echo "" | |
| 75 | + | |
| 76 | +echo "======================================================================" | |
| 77 | +echo "测试完成" | |
| 78 | +echo "======================================================================" | |
| 79 | +echo "" | |
| 80 | +echo "💡 提示:" | |
| 81 | +echo " - 内存监控日志: logs/memory_monitor.log" | |
| 82 | +echo " - 查看实时日志: tail -f logs/memory_monitor.log" | |
| 83 | +echo " - 监控阈值可在 run.sh 中修改" | |
| 84 | +echo "" | |
| 85 | + | ... | ... |