项目重构说明-20241017.md 9.33 KB

项目重构说明 - 2024-10-17

✅ 完成的重构

1. 目录结构调整

改动: 将collaboration目录移入offline_tasks

之前:

recommendation/
├── offline_tasks/
│   ├── scripts/
│   └── ...
└── collaboration/          # 外层目录
    ├── src/
    └── run.sh

之后:

recommendation/
└── offline_tasks/
    ├── scripts/
    ├── collaboration/      # 移入内部
    │   ├── src/
    │   └── run.sh
    └── ...

优势:

  • ✅ 统一目录结构,所有离线任务在同一目录
  • ✅ 简化路径配置
  • ✅ 便于统一管理和部署

2. 执行脚本简化

改动: 主执行脚本从run_all.py改为run.sh,直接调用各个脚本

之前的流程:

# run_all.py (Python实现)
run_script('fetch_item_attributes.py')
run_script('generate_session.py')
run_cpp_swing()  # 调用collaboration/run.sh
run_script('i2i_swing.py')
# ...

现在的流程:

# run.sh (Shell实现)
python3 scripts/fetch_item_attributes.py
python3 scripts/generate_session.py
cd collaboration && bash run.sh && cd ..
python3 scripts/i2i_swing.py
# ...

优势:

  • ✅ 代码更简洁,减少抽象层
  • ✅ 直接调用,易于理解和调试
  • ✅ 内存监控、错误处理更灵活
  • ✅ 配置参数集中在顶部,便于修改

3. 路径更新

所有相关路径已更新:

collaboration/run.sh:

  • SESSION_DATA_DIR="../offline_tasks/output""../output"
  • DEBUG_SCRIPT="../offline_tasks/scripts/...""../scripts/..."

文档更新:

  • README.md
  • doc/离线索引数据规范.md
  • doc/Redis数据规范.md
  • doc/系统改进总结-20241017.md

📋 新的项目结构

offline_tasks/
├── scripts/                       # Python脚本
│   ├── fetch_item_attributes.py  # 前置:获取商品属性
│   ├── generate_session.py       # 前置:生成session
│   ├── i2i_swing.py              # Python Swing
│   ├── i2i_session_w2v.py        # Session W2V
│   ├── i2i_deepwalk.py           # DeepWalk
│   ├── i2i_content_similar.py    # 内容相似度
│   ├── interest_aggregation.py   # 兴趣聚合
│   ├── load_index_to_redis.py    # 加载到Redis
│   ├── add_names_to_swing.py     # 添加商品名
│   └── debug_utils.py            # Debug工具
├── collaboration/                 # C++ Swing算法
│   ├── src/
│   │   ├── swing.cc              # Swing实现
│   │   ├── swing_symmetric.cc    # 对称Swing
│   │   ├── icf_simple.cc         # 简单协同
│   │   └── ucf.py                # 用户协同
│   ├── bin/                      # 编译后的二进制
│   ├── include/                  # 头文件
│   ├── utils/                    # 工具函数
│   ├── run.sh                    # C++ Swing执行脚本
│   ├── Makefile                  # 编译配置
│   └── output/                   # 输出目录
├── config/
│   └── offline_config.py         # 配置文件
├── doc/                          # 文档中心
│   ├── README.md
│   ├── 快速开始.md
│   ├── Swing算法使用指南.md
│   ├── 离线索引数据规范.md
│   ├── Redis数据规范.md
│   └── ...
├── output/                       # 输出文件
│   ├── item_attributes_mappings.json
│   ├── session.txt.*
│   └── *.txt
├── logs/                         # 日志文件
├── run.sh                        # ⭐ 主执行脚本(推荐)
├── run_all.py                    # Python版本(保留但简化)
└── README.md

🚀 使用方式

主要方式:run.sh(推荐)

cd /home/tw/recommendation/offline_tasks

# 直接运行(使用默认配置)
bash run.sh

# 修改配置后运行
# 编辑 run.sh 顶部的配置区域
vim run.sh

# 查看帮助
cat run.sh | head -40  # 查看配置说明

run.sh配置项:

# 算法参数
LOOKBACK_DAYS=730
TOP_N=50
DEBUG_MODE="--debug"  # 留空则不开启debug

# Redis配置
REDIS_HOST="localhost"
REDIS_PORT=6379

# 内存监控阈值
MEM_WARN_THRESHOLD=25  # GB
MEM_KILL_THRESHOLD=35  # GB

备用方式:run_all.py(简化版)

cd /home/tw/recommendation/offline_tasks

# 运行(不包括C++ Swing和Redis加载)
python3 run_all.py --debug

注意: run_all.py已简化,只包含:

  • 前置任务(商品属性、session)
  • Python算法任务(Swing、W2V、DeepWalk等)
  • 不包括C++ Swing和Redis加载

📊 执行流程对比

run.sh(完整流程)

1. 环境准备
   ├─ 清理旧进程
   └─ 创建必要目录

2. 前置任务
   ├─ fetch_item_attributes.py    → 商品属性映射
   ├─ generate_session.py          → 用户session
   └─ collaboration/run.sh         → C++ Swing (高性能)

3. i2i算法任务
   ├─ i2i_swing.py                → Python Swing (日期维度)
   ├─ i2i_session_w2v.py          → Session W2V
   ├─ i2i_deepwalk.py             → DeepWalk
   └─ i2i_content_similar.py      → 内容相似度

4. 兴趣聚合
   └─ interest_aggregation.py     → 多维度聚合

5. 加载Redis
   └─ load_index_to_redis.py      → 导入Redis

6. 完成
   └─ 输出结果文件列表

run_all.py(简化流程)

1. 前置任务
   ├─ fetch_item_attributes.py
   └─ generate_session.py

2. i2i算法任务
   ├─ i2i_swing.py
   ├─ i2i_session_w2v.py
   ├─ i2i_deepwalk.py
   └─ i2i_content_similar.py

3. 兴趣聚合
   └─ interest_aggregation.py

💡 关键改进

1. 代码简化

删除的冗余代码:

  • run_all.py中的run_cpp_swing()函数(45行)
  • 复杂的子进程调用和错误处理

简化效果:

  • run.sh: 直接调用,清晰明了
  • run_all.py: 从270行简化到211行

2. 灵活性提升

run.sh的优势:

# 内存监控(自动)
check_memory $pid "$task_name" &

# 任务函数(统一)
run_task "任务名" "python3 scripts/xxx.py"

# 配置集中(顶部)
LOOKBACK_DAYS=730
DEBUG_MODE="--debug"

3. 错误处理

之前:

  • Python捕获异常,日志分散
  • 失败后需要手动排查

现在:

  • Shell直接显示错误
  • 内存监控自动处理OOM
  • 任务失败继续执行后续任务

🔧 常见操作

修改算法参数

# 编辑 run.sh
vim run.sh

# 修改这些参数
LOOKBACK_DAYS=365  # 回看天数
TOP_N=100          # 推荐数量
DEBUG_MODE=""      # 关闭debug

只运行特定任务

cd /home/tw/recommendation/offline_tasks

# 只运行C++ Swing
cd collaboration && bash run.sh && cd ..

# 只运行Python Swing
python3 scripts/i2i_swing.py --lookback_days 730 --debug

# 只加载Redis
python3 scripts/load_index_to_redis.py --redis-host localhost

查看日志

# 主日志
tail -f logs/run_all_$(date +%Y%m%d).log

# 内存监控日志
tail -f logs/memory_monitor.log

# Debug日志
ls logs/debug/

📝 迁移指南

如果你之前使用python3 run_all.py,现在改用bash run.sh

命令对应关系

之前 现在 说明
python3 run_all.py bash run.sh 完整流程
python3 run_all.py --debug bash run.sh run.sh默认开启debug
无对应命令 bash run.sh 现在包含Redis加载

定时任务更新

旧的crontab:

0 3 * * * cd /home/tw/recommendation/offline_tasks && python3 run_all.py

新的crontab:

0 3 * * * cd /home/tw/recommendation/offline_tasks && bash run.sh >> logs/cron_$(date +\%Y\%m\%d).log 2>&1

⚠️ 注意事项

  1. 路径依赖:

    • 确保在offline_tasks目录下执行bash run.sh
    • 不要在其他目录执行
  2. 内存监控:

    • 默认阈值:警告25GB,终止35GB
    • 根据服务器配置调整MEM_WARN_THRESHOLDMEM_KILL_THRESHOLD
  3. 并行执行:

    • 不建议同时运行多个run.sh实例
    • 脚本会自动清理旧进程
  4. 失败处理:

    • 单个任务失败不会终止整体流程
    • 查看日志确认失败原因

🎯 总结

改进前后对比

方面 改进前 改进后
目录结构 collaboration在外层 统一在offline_tasks内
主执行脚本 run_all.py (Python) run.sh (Shell)
代码复杂度 270行,多层抽象 214行,直接调用
配置方式 参数分散 集中在顶部
内存监控 自动监控+自动终止
错误处理 Python异常捕获 Shell直接显示
包含任务 不含Redis加载 含完整流程

核心改进

  1. 结构简化: collaboration目录移入,统一管理
  2. 代码简化: 去除冗余抽象,直接调用脚本
  3. 功能增强: 添加内存监控、统一任务管理
  4. 易用性: 配置集中、日志清晰、错误明确

📚 相关文档


更新时间: 2024-10-17
状态: ✅ 已完成并测试