# Redis Key格式问题修复方案 ## 🔍 问题诊断 ### 发现的问题 经过排查,发现了以下三个关键问题: 1. **Redis Key 格式错误** ❌ - **实际存储**: `i2i:content_name:*`, `i2i:deepwalk:*`, `i2i:session_w2v:*` - **文档定义**: `item:similar:content_name:*`, `item:similar:deepwalk:*`, `item:similar:session_w2v:*` - **影响**: 查询 `KEYS item:similar:*` 返回空,因为key前缀不匹配 2. **C++ Swing 未被加载** ❌ - `collaboration/output/swing_similar.txt` 存在(15,177条记录,6.9MB) - 但加载脚本没有处理这个文件 - 应该存储为: `item:similar:swing_cpp:*` 3. **Python Swing 文件缺失** ⚠️ - `i2i_swing_20251022.txt` 不存在 - Python Swing算法可能执行失败 ### 数据统计 ``` Redis总Key数: 229,710 ├─ i2i:* (错误格式): 176,150 ├─ item:similar:* (正确格式): 0 └─ interest:* (正确格式): 53,560 ✓ C++ Swing输出: 15,177条记录 (未加载) Interest数据: 53,560条 (已正确加载) ✓ ``` **结论**: `interest:*` 有数据是因为它使用了正确的key格式,但 `item:similar:*` 为空是因为数据被错误地存储到了 `i2i:*` 格式。 --- ## 🔧 根本原因 ### 代码问题定位 **文件**: `scripts/load_index_to_redis.py` **错误代码** (第100行): ```python count = load_index_file( file_path, redis_client, f"i2i:{i2i_type}", # ❌ 错误! expire_seconds ) ``` **应该是**: ```python count = load_index_file( file_path, redis_client, f"item:similar:{i2i_type}", # ✓ 正确! expire_seconds ) ``` **缺失功能**: 没有加载 C++ Swing 的函数 --- ## ✅ 修复方案 ### 已完成的修复 ✅ **1. 修复了 `load_index_to_redis.py`** - 修正了key前缀: `i2i:` → `item:similar:` - 添加了 `load_cpp_swing_index()` 函数 - 添加了 `i2i_item_behavior` 到加载列表 ✅ **2. 创建了清理脚本 `fix_redis_keys.py`** - 清理错误格式的 `i2i:*` key - 提供统计信息和确认提示 ### 执行步骤 #### 步骤1: 清理错误的Redis Key ```bash cd /home/tw/recommendation/offline_tasks # 运行清理脚本 python3 scripts/fix_redis_keys.py # 输入 'yes' 确认删除错误格式的key ``` #### 步骤2: 重新加载数据(使用output_1022的数据) ```bash # 方式1: 从output_1022目录加载指定日期的数据 python3 scripts/load_index_to_redis.py \ --date 20251022 \ --redis-host localhost \ --redis-port 6379 \ --expire-days 7 # 注意:确保output目录指向output_1022,或者临时修改OUTPUT_DIR ``` **或者,更简单的方式**: ```bash # 创建软链接指向output_1022 cd /home/tw/recommendation/offline_tasks rm -rf output # 如果当前output是目录 ln -s output_1022/output output # 然后正常加载 python3 scripts/load_index_to_redis.py \ --redis-host localhost \ --redis-port 6379 \ --date 20251022 ``` #### 步骤3: 验证修复结果 ```bash redis-cli # 检查key数量 DBSIZE # 查看正确格式的key KEYS item:similar:* # 查看C++ Swing的key(应该有15177个) KEYS item:similar:swing_cpp:* # 查看其他i2i算法的key KEYS item:similar:deepwalk:* KEYS item:similar:content_name:* KEYS item:similar:session_w2v:* KEYS item:similar:item_behavior:* # 验证interest数据仍然存在 KEYS interest:* # 测试查询具体的key GET item:similar:swing_cpp:3600052 GET interest:hot:platform:essabuy ``` **预期结果**: ``` KEYS item:similar:* 返回数量: ~176,000+ (包括C++ Swing的15,177条) KEYS item:similar:swing_cpp:* 返回数量: 15,177 KEYS item:similar:deepwalk:* 返回数量: ~48,376 KEYS item:similar:content_name:* 返回数量: ~127,720 KEYS interest:* 返回数量: 53,560 (保持不变) ``` --- ## 📊 修复后的数据结构 ### 正确的Redis Key格式 ``` # i2i相似度索引 item:similar:swing_cpp:{item_id} → C++ Swing结果 item:similar:swing:{item_id} → Python Swing结果 item:similar:session_w2v:{item_id} → Session W2V结果 item:similar:deepwalk:{item_id} → DeepWalk结果 item:similar:content_name:{item_id} → 内容相似度(名称) item:similar:content_pic:{item_id} → 内容相似度(图片) item:similar:item_behavior:{item_id} → Item行为相似度 # 兴趣点聚合索引 interest:hot:{dimension_key} → 热门商品 interest:cart:{dimension_key} → 加购商品 interest:new:{dimension_key} → 新品 interest:global:{dimension_key} → 全局热门 ``` ### 查询示例 ```python import redis import json r = redis.Redis(host='localhost', port=6379, db=0, decode_responses=True) # 查询C++ Swing相似商品 similar_items = json.loads(r.get('item:similar:swing_cpp:3600052')) # 返回: [[2704531, 0.00431593], [2503886, 0.00431593], ...] # 查询平台热门商品 hot_items = r.get('interest:hot:platform:essabuy') # 返回: "3090653:70.0000,3509349:70.0000,..." ``` --- ## 🚨 Python Swing 问题 ### 问题描述 `i2i_swing_20251022.txt` 文件不存在,说明Python Swing算法没有成功执行。 ### 可能原因 1. 算法执行失败(内存不足、超时等) 2. Session数据问题 3. 参数配置问题 ### 排查步骤 ```bash # 查看Python Swing的日志 cat /home/tw/recommendation/offline_tasks/output_1022/logs/debug/i2i_swing*.log # 检查session文件 ls -lh /home/tw/recommendation/offline_tasks/output_1022/output/session.txt.* # 手动运行Python Swing测试 cd /home/tw/recommendation/offline_tasks python3 scripts/i2i_swing.py --lookback_days 30 --top_n 10 --debug ``` ### 临时解决方案 由于C++ Swing已经生成且性能更好,可以暂时只使用C++ Swing的结果: - C++ Swing: `item:similar:swing_cpp:*` (15,177条记录) - 文档推荐在生产环境使用C++ Swing --- ## 📝 后续改进建议 ### 1. 代码改进 - ✅ 已修复key格式问题 - ✅ 已添加C++ Swing加载功能 - 建议: 添加单元测试验证key格式 ### 2. 文档更新 - 更新 `Redis数据规范.md` 中的加载示例代码 - 添加故障排查指南 - 标注C++ Swing为生产推荐 ### 3. 监控告警 - 添加Redis key格式验证 - 监控各类索引的数量 - Python Swing执行失败时告警 ### 4. 自动化测试 ```python # 建议添加测试用例 def test_redis_key_format(): """测试Redis key格式是否正确""" keys = redis_client.keys('item:similar:*') assert len(keys) > 0, "item:similar:* should not be empty" # 确保没有错误格式的key wrong_keys = redis_client.keys('i2i:*') assert len(wrong_keys) == 0, f"Found wrong format keys: {wrong_keys[:5]}" ``` --- ## 🎯 总结 ### 问题根源 加载脚本使用了错误的Redis key前缀 `i2i:*` 而不是文档定义的 `item:similar:*` ### 解决方案 1. ✅ 修复了 `load_index_to_redis.py` 的key前缀 2. ✅ 添加了C++ Swing加载功能 3. ✅ 创建了清理脚本清理错误的key 4. ⏳ 需要重新加载数据 ### 后续行动 1. 执行 `fix_redis_keys.py` 清理错误的key 2. 重新运行 `load_index_to_redis.py` 加载数据 3. 验证所有 `item:similar:*` key都能正常查询 4. 排查Python Swing执行失败的原因 --- **创建时间**: 2025-10-22 **版本**: v1.0 **状态**: ✅ 修复方案已就绪,等待执行