Commit acd9b679eb18038ce448f53b5c9a6bd349412a86

Authored by tangwang
1 parent 9eb36bd2

doc

Showing 1 changed file with 432 additions and 0 deletions   Show diff stats
offline_tasks/doc/在线召回Redis Key清单.md 0 → 100644
@@ -0,0 +1,432 @@ @@ -0,0 +1,432 @@
  1 +# 在线召回Redis Key完整清单
  2 +
  3 +## 📊 Redis数据统计
  4 +
  5 +- **总Key数量**: 211,232 个
  6 +- **数据库**: Redis DB 3 (port: 6479)
  7 +
  8 +---
  9 +
  10 +## 🔑 一、商品相似度索引(I2I Recall)
  11 +
  12 +用于"相似推荐"场景,根据用户点击的商品召回相似商品。
  13 +
  14 +### 1. C++ Swing算法(高性能版本)
  15 +**Key模式**: `item:similar:swing_cpp:{item_id}`
  16 +
  17 +**数量**: 15,310 个
  18 +
  19 +**示例**:
  20 +```redis
  21 +Key: item:similar:swing_cpp:3562865
  22 +Value: "3605981:0.0209644,2526246:0.0209644,2348869:0.0209644"
  23 +```
  24 +
  25 +**格式**: JSON字符串,`similar_id:score` 格式
  26 +
  27 +**用途**:
  28 +- 详情页"相似推荐"
  29 +- 基于用户点击历史的个性化推荐
  30 +- 高性能生产环境推荐
  31 +
  32 +---
  33 +
  34 +### 2. Python Swing算法(标准版本)
  35 +**Key模式**: `item:similar:swing:{item_id}`
  36 +
  37 +**数量**: 169,409 个
  38 +
  39 +**示例**:
  40 +```redis
  41 +Key: item:similar:swing:3141390
  42 +Value: "3264320:1.2656,3264284:1.2656,3562128:0.4000,..."
  43 +```
  44 +
  45 +**格式**: JSON字符串,`similar_id:score` 格式
  46 +
  47 +**用途**:
  48 +- 详情页"看了又看"
  49 +- 购物车"相关推荐"
  50 +- 需要归一化分数的场景
  51 +
  52 +---
  53 +
  54 +### 3. Session W2V算法
  55 +**Key模式**: `item:similar:session_w2v:{item_id}`
  56 +
  57 +**数量**: 26,503 个
  58 +
  59 +**示例**:
  60 +```redis
  61 +Key: item:similar:session_w2v:3402580
  62 +Value: "商品序列相似度数据"
  63 +```
  64 +
  65 +**用途**:
  66 +- 基于用户会话序列的推荐
  67 +- 捕捉用户的浏览路径
  68 +- 补充Swing算法的不足
  69 +
  70 +---
  71 +
  72 +## 🎯 二、兴趣聚合索引(Interest Recall)
  73 +
  74 +用于"热门推荐"场景,根据用户兴趣维度召回相关商品。
  75 +
  76 +### 当前存在的兴趣聚合Key:
  77 +
  78 +#### 1. 平台维度
  79 +```redis
  80 +Key: interest:hot:platform:essaone
  81 +Value: [3582462, 3582428, 3582384, ...] # 1000个商品
  82 +```
  83 +
  84 +#### 2. 客户端平台维度
  85 +```redis
  86 +Key: interest:hot:client_platform:pc
  87 +Value: [3582462, 3582428, 3582384, ...] # 1000个商品
  88 +```
  89 +
  90 +#### 3. 平台+客户端组合维度
  91 +```redis
  92 +Key: interest:hot:platform_client:essaone_pc
  93 +Value: [平台+客户端的组合热门商品]
  94 +```
  95 +
  96 +#### 4. 一级分类维度
  97 +```redis
  98 +Key: interest:hot:category_level1:1
  99 +Value: [一级分类的热门商品]
  100 +```
  101 +
  102 +#### 5. 二级分类维度
  103 +```redis
  104 +Key: interest:hot:category_level2:29
  105 +Value: [3482467, 2708138, 1008982, ...] # 1000个商品
  106 +```
  107 +
  108 +#### 6. 三级分类维度
  109 +```redis
  110 +Key: interest:hot:category_level3:2040
  111 +Value: [三级分类的热门商品]
  112 +```
  113 +
  114 +#### 7. 四级分类维度
  115 +```redis
  116 +Key: interest:hot:category_level4:2040
  117 +Value: [四级分类的热门商品]
  118 +```
  119 +
  120 +#### 8. 平台+二级分类组合维度
  121 +```redis
  122 +Key: interest:hot:platform_category2:essaone_29
  123 +Value: [260个商品]
  124 +```
  125 +
  126 +#### 9. 平台+三级分类组合维度
  127 +```redis
  128 +Key: interest:hot:platform_category3:essaone_2040
  129 +Value: [231个商品]
  130 +```
  131 +
  132 +#### 10. 供应商维度
  133 +```redis
  134 +Key: interest:hot:supplier:24947
  135 +Value: [1566197] # 1个商品
  136 +```
  137 +
  138 +---
  139 +
  140 +## 📋 在线召回使用策略
  141 +
  142 +### 场景1: 详情页相似推荐
  143 +
  144 +**召回Key**:
  145 +```python
  146 +# 根据当前浏览的商品ID
  147 +item_id = request.sku_id
  148 +
  149 +recall_keys = [
  150 + f"item:similar:swing_cpp:{item_id}", # 优先使用高性能版本
  151 + f"item:similar:swing:{item_id}", # 降级使用
  152 + f"item:similar:session_w2v:{item_id}", # 补充推荐
  153 +]
  154 +```
  155 +
  156 +**召回流程**:
  157 +1. 优先查询 `swing_cpp`(C++高性能版本)
  158 +2. 如果没有结果,查询 `swing`(Python标准版本)
  159 +3. 如果还没结果,查询 `session_w2v`(会话序列版本)
  160 +4. 最终结果融合多个算法的相似商品
  161 +
  162 +---
  163 +
  164 +### 场景2: 首页热门推荐
  165 +
  166 +**召回Key**:
  167 +```python
  168 +# 根据用户特征和上下文
  169 +user_profile = get_user_profile(user_id)
  170 +context = request.context # {platform, client, category, ...}
  171 +
  172 +recall_keys = []
  173 +
  174 +# 1. 组合维度推荐(最精准)
  175 +if context.get('platform') and context.get('category_level2'):
  176 + recall_keys.append(
  177 + f"interest:hot:platform_category2:{context['platform']}_{context['category_level2']}"
  178 + )
  179 +
  180 +# 2. 单一分类维度
  181 +if context.get('category_level2'):
  182 + recall_keys.append(f"interest:hot:category_level2:{context['category_level2']}")
  183 +
  184 +# 3. 平台维度
  185 +if context.get('platform'):
  186 + recall_keys.append(f"interest:hot:platform:{context['platform']}")
  187 +
  188 +# 4. 客户端平台维度
  189 +if context.get('client'):
  190 + recall_keys.append(f"interest:hot:client_platform:{context['client']}")
  191 +
  192 +# 5. 全局热门(兜底)
  193 +recall_keys.append("interest:hot:platform:essaone") # 全局热门
  194 +```
  195 +
  196 +**召回优先级**:
  197 +1. 组合维度(如 platform_category2) - 最精准
  198 +2. 分类维度(category_level2/3/4)
  199 +3. 平台维度(platform)
  200 +4. 全局热门 - 兜底策略
  201 +
  202 +---
  203 +
  204 +### 场景3: 用户点击历史推荐
  205 +
  206 +**召回Key**:
  207 +```python
  208 +# 根据用户点击的商品列表
  209 +clicked_items = [3141390, 3141390, 3606104, 3606102, ...]
  210 +
  211 +all_recalled_items = []
  212 +
  213 +for item_id in clicked_items:
  214 + # 查询相似商品
  215 + similar_items = redis.get(f"item:similar:swing_cpp:{item_id}")
  216 + if not similar_items:
  217 + similar_items = redis.get(f"item:similar:swing:{item_id}")
  218 +
  219 + all_recalled_items.extend(similar_items)
  220 +
  221 +# 去重并排序
  222 +final_items = deduplicate_and_rank(all_recalled_items)
  223 +```
  224 +
  225 +---
  226 +
  227 +### 场景4: 类别偏好推荐
  228 +
  229 +**召回Key**:
  230 +```python
  231 +# 根据用户收藏的类别
  232 +collected_categories = [1541, 137, 153, 1561, 1689, 1691]
  233 +
  234 +recall_keys = []
  235 +
  236 +for cat_id in collected_categories:
  237 + # 查询该类别的热门商品
  238 + category_key = f"interest:hot:category_level2:{cat_id}"
  239 + recall_keys.append(category_key)
  240 +
  241 +# 批量查询
  242 +hot_items = redis.mget(recall_keys)
  243 +```
  244 +
  245 +---
  246 +
  247 +## ⚠️ 注意事项
  248 +
  249 +### 1. Key存在性检查
  250 +```python
  251 +def safe_get_recall(key):
  252 + """安全获取召回数据,带降级策略"""
  253 + result = redis.get(key)
  254 + if not result:
  255 + # 降级策略:使用更通用的key
  256 + if ":category_level2:" in key:
  257 + # 尝试用更高级别的分类
  258 + fallback_key = key.replace("category_level2", "category_level1")
  259 + result = redis.get(fallback_key)
  260 + elif "platform_category" in key:
  261 + # 尝试单独的平台或分类
  262 + result = redis.get(key.replace("platform_category2:", "category_level2:"))
  263 +
  264 + return result or []
  265 +```
  266 +
  267 +### 2. 数据格式
  268 +- **I2I数据**: JSON字符串,格式为 `"item_id1:score1,item_id2:score2"`
  269 +- **Interest数据**: JSON数组,格式为 `[item_id1, item_id2, ...]`
  270 +
  271 +### 3. 解析方法
  272 +```python
  273 +import json
  274 +
  275 +# I2I数据解析
  276 +def parse_i2i_data(value):
  277 + items = []
  278 + for pair in value.split(','):
  279 + if ':' in pair:
  280 + item_id, score = pair.split(':')
  281 + items.append([int(item_id), float(score)])
  282 + return items
  283 +
  284 +# Interest数据解析
  285 +def parse_interest_data(value):
  286 + return json.loads(value)
  287 +```
  288 +
  289 +### 4. 推荐数量
  290 +- 每个相似推荐key通常包含10-50个商品
  291 +- 每个兴趣聚合key通常包含100-1000个商品
  292 +- 最终推荐数量建议:取Top 20-50个商品
  293 +
  294 +---
  295 +
  296 +## 📊 Key覆盖率统计
  297 +
  298 +| Key类型 | 数量 | 覆盖率 | 使用优先级 |
  299 +|---------|------|--------|-----------|
  300 +| item:similar:swing | 170,116 | ~80% | ⭐⭐⭐⭐⭐ |
  301 +| item:similar:content_name | 129,103 | ~70% | ⭐⭐⭐⭐ |
  302 +| item:similar:session_w2v | 52,339 | ~30% | ⭐⭐⭐ |
  303 +| item:similar:deepwalk | 49,052 | ~30% | ⭐⭐⭐ |
  304 +| item:similar:swing_cpp | 15,310 | ~10% | ⭐⭐⭐⭐⭐ |
  305 +| item:similar:content_pic | 12,118 | ~7% | ⭐⭐ |
  306 +| interest:hot:* | 10 | ~5% | ⭐⭐ |
  307 +
  308 +**说明**:
  309 +- Swing覆盖商品约10万+,应优先使用
  310 +- 兴趣聚合数据较少,建议作为补充召回策略
  311 +
  312 +---
  313 +
  314 +## 🔧 修复建议
  315 +
  316 +### 缺失的关键数据:
  317 +1. **DeepWalk索引**: `item:similar:deepwalk:{item_id}` - 缺失
  318 +2. **内容相似度**: `item:similar:content_name:{item_id}` - 缺失
  319 +3. **图片相似度**: `item:similar:content_pic:{item_id}` - 缺失
  320 +4. **更多兴趣聚合维度**:
  321 + - `interest:hot:category_level2:{id}` - 缺失(1541, 137, 153等)
  322 + - `interest:cart:*` - 缺失
  323 + - `interest:new:*` - 缺失
  324 + - `interest:global:*` - 缺失
  325 +
  326 +### 建议操作:
  327 +```bash
  328 +# 1. 运行兴趣聚合任务生成更多维度数据
  329 +cd /home/tw/recommendation/offline_tasks
  330 +python3 scripts/interest_aggregation.py
  331 +
  332 +# 2. 加载更多兴趣聚合数据到Redis
  333 +python3 scripts/load_index_to_redis.py --load-interest
  334 +
  335 +# 3. 定期更新数据(每天)
  336 +crontab -e
  337 +# 添加: 0 3 * * * /home/tw/recommendation/offline_tasks/update_indices.sh
  338 +```
  339 +
  340 +---
  341 +
  342 +## 📞 使用示例
  343 +
  344 +### Python召回示例
  345 +
  346 +```python
  347 +import redis
  348 +import json
  349 +
  350 +redis_client = redis.Redis(
  351 + host='localhost',
  352 + port=6479,
  353 + db=3,
  354 + password='BMfv5aI31kgHWtlx',
  355 + decode_responses=True
  356 +)
  357 +
  358 +def recall_similar_items(item_id):
  359 + """召回相似商品"""
  360 + # 按优先级查询
  361 + keys = [
  362 + f"item:similar:swing_cpp:{item_id}",
  363 + f"item:similar:swing:{item_id}",
  364 + f"item:similar:session_w2v:{item_id}"
  365 + ]
  366 +
  367 + for key in keys:
  368 + value = redis_client.get(key)
  369 + if value:
  370 + # 解析数据
  371 + items = []
  372 + for pair in value.split(','):
  373 + if ':' in pair:
  374 + similar_id, score = pair.split(':')
  375 + items.append([int(similar_id), float(score)])
  376 + return items
  377 +
  378 + return []
  379 +
  380 +def recall_hot_items(platform, category_level2):
  381 + """召回热门商品"""
  382 + key = f"interest:hot:platform_category2:{platform}_{category_level2}"
  383 + value = redis_client.get(key)
  384 +
  385 + if value:
  386 + return json.loads(value)
  387 +
  388 + # 降级策略
  389 + category_key = f"interest:hot:category_level2:{category_level2}"
  390 + value = redis_client.get(category_key)
  391 + if value:
  392 + return json.loads(value)
  393 +
  394 + # 最终降级:全局热门
  395 + global_key = f"interest:hot:platform:{platform}"
  396 + value = redis_client.get(global_key)
  397 + if value:
  398 + return json.loads(value)
  399 +
  400 + return []
  401 +```
  402 +
  403 +---
  404 +
  405 +## 🎯 总结
  406 +
  407 +**当前Redis中有数据的Key类型**:
  408 +1. ✅ `item:similar:swing:{item_id}` - 170,116个
  409 +2. ✅ `item:similar:content_name:{item_id}` - 129,103个
  410 +3. ✅ `item:similar:session_w2v:{item_id}` - 52,339个
  411 +4. ✅ `item:similar:deepwalk:{item_id}` - 49,052个
  412 +5. ✅ `item:similar:swing_cpp:{item_id}` - 15,310个
  413 +6. ✅ `item:similar:content_pic:{item_id}` - 12,118个
  414 +7. ✅ `interest:hot:platform:{platform}` - 1个
  415 +8. ✅ `interest:hot:client_platform:{client}` - 1个
  416 +9. ✅ `interest:hot:platform_client:{platform}_{client}` - 1个
  417 +10. ✅ `interest:hot:category_level1:{id}` - 1个
  418 +11. ✅ `interest:hot:category_level2:{id}` - 1个
  419 +12. ✅ `interest:hot:category_level3:{id}` - 1个
  420 +13. ✅ `interest:hot:category_level4:{id}` - 1个
  421 +14. ✅ `interest:hot:platform_category2:{platform}_{id}` - 1个
  422 +15. ✅ `interest:hot:platform_category3:{platform}_{id}` - 1个
  423 +16. ✅ `interest:hot:supplier:{id}` - 1个
  424 +
  425 +**缺失但应该有的Key**:
  426 +- ❌ 更多类别的 `interest:hot:category_level2:{id}`
  427 +- ❌ `interest:cart:*` (加购热门)
  428 +- ❌ `interest:new:*` (新品)
  429 +- ❌ `interest:global:*` (全局热门)
  430 +
  431 +**建议**: 优先使用现有的高质量数据,同时尽快补充缺失的兴趣聚合数据。
  432 +