Redis_Key格式问题修复方案.md 7.16 KB

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行):

count = load_index_file(
    file_path,
    redis_client,
    f"i2i:{i2i_type}",  # ❌ 错误!
    expire_seconds
)

应该是:

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

cd /home/tw/recommendation/offline_tasks

# 运行清理脚本
python3 scripts/fix_redis_keys.py
# 输入 'yes' 确认删除错误格式的key

步骤2: 重新加载数据(使用output_1022的数据)

# 方式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

或者,更简单的方式:

# 创建软链接指向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: 验证修复结果

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}       → 全局热门

查询示例

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. 参数配置问题

排查步骤

# 查看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. 自动化测试

# 建议添加测试用例
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
状态: ✅ 修复方案已就绪,等待执行