REDIS_DATA_SPEC.md
9.28 KB
Redis数据灌入规范
📋 数据灌入概述
将离线生成的推荐索引加载到Redis,供在线系统实时查询使用。
🔑 Redis Key规范
通用规则
{namespace}:{function}:{algorithm}:{identifier}
namespace: 业务命名空间(item, user, interest等)function: 功能类型(similar, feature, hot等)algorithm: 算法名称(swing, w2v, deepwalk等)identifier: 具体标识(item_id, dimension_key等)
📊 数据灌入规范表
| 模块名称 | 源数据地址 | 格式描述 | RedisKey模板 | RedisValue格式 | TTL |
|---|---|---|---|---|---|
| i2i_swing | output/i2i_swing_YYYYMMDD.txt |
item_id\titem_name\tsimilar_id1:score1,... |
item:similar:swing:{item_id} |
[[similar_id1,score1],[similar_id2,score2],...] |
7天 |
| i2i_session_w2v | output/i2i_session_w2v_YYYYMMDD.txt |
item_id\titem_name\tsimilar_id1:score1,... |
item:similar:w2v:{item_id} |
[[similar_id1,score1],[similar_id2,score2],...] |
7天 |
| i2i_deepwalk | output/i2i_deepwalk_YYYYMMDD.txt |
item_id\titem_name\tsimilar_id1:score1,... |
item:similar:deepwalk:{item_id} |
[[similar_id1,score1],[similar_id2,score2],...] |
7天 |
| i2i_content_name | output/i2i_content_name_YYYYMMDD.txt |
item_id\titem_name\tsimilar_id1:score1,... |
item:similar:content_name:{item_id} |
[[similar_id1,score1],[similar_id2,score2],...] |
30天 |
| i2i_content_pic | output/i2i_content_pic_YYYYMMDD.txt |
item_id\titem_name\tsimilar_id1:score1,... |
item:similar:content_pic:{item_id} |
[[similar_id1,score1],[similar_id2,score2],...] |
30天 |
| interest_hot | output/interest_aggregation_hot_YYYYMMDD.txt |
dimension_key\titem_id1,item_id2,... |
interest:hot:{dimension_key} |
[item_id1,item_id2,item_id3,...] |
3天 |
| interest_cart | output/interest_aggregation_cart_YYYYMMDD.txt |
dimension_key\titem_id1,item_id2,... |
interest:cart:{dimension_key} |
[item_id1,item_id2,item_id3,...] |
3天 |
| interest_new | output/interest_aggregation_new_YYYYMMDD.txt |
dimension_key\titem_id1,item_id2,... |
interest:new:{dimension_key} |
[item_id1,item_id2,item_id3,...] |
3天 |
| interest_global | output/interest_aggregation_global_YYYYMMDD.txt |
dimension_key\titem_id1,item_id2,... |
interest:global:{dimension_key} |
[item_id1,item_id2,item_id3,...] |
7天 |
📝 详细说明
1. i2i相似度索引
源数据格式
12345 香蕉干 67890:0.8567,11223:0.7234,44556:0.6891
Redis存储
Key: item:similar:swing:12345
Value (JSON格式):
[[67890, 0.8567], [11223, 0.7234], [44556, 0.6891]]
Value (序列化后):
import json
value = json.dumps([[67890, 0.8567], [11223, 0.7234], [44556, 0.6891]])
# 存储: "[[67890,0.8567],[11223,0.7234],[44556,0.6891]]"
查询示例
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
# 获取商品12345的相似商品(Swing算法)
similar_items = json.loads(r.get('item:similar:swing:12345'))
# 返回: [[67890, 0.8567], [11223, 0.7234], [44556, 0.6891]]
# 获取Top5相似商品
top_5 = similar_items[:5]
2. 兴趣点聚合索引
源数据格式
platform:pc 12345,67890,11223,44556,22334
category_level2:200 67890,12345,22334,55667,11223
Redis存储
Key: interest:hot:platform:pc
Value (JSON格式):
[12345, 67890, 11223, 44556, 22334]
Value (序列化后):
import json
value = json.dumps([12345, 67890, 11223, 44556, 22334])
# 存储: "[12345,67890,11223,44556,22334]"
查询示例
import redis
import json
r = redis.Redis(host='localhost', port=6379, db=0)
# 获取PC平台的热门商品
hot_items = json.loads(r.get('interest:hot:platform:pc'))
# 返回: [12345, 67890, 11223, 44556, 22334]
# 获取Top10热门商品
top_10 = hot_items[:10]
🔄 数据加载流程
1. 加载i2i索引
def load_i2i_index(file_path, algorithm_name, redis_client, expire_seconds=604800):
"""
加载i2i相似度索引到Redis
Args:
file_path: 索引文件路径
algorithm_name: 算法名称(swing, w2v, deepwalk, content)
redis_client: Redis客户端
expire_seconds: 过期时间(秒),默认7天
"""
import json
count = 0
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
parts = line.strip().split('\t')
if len(parts) < 3:
continue
item_id = parts[0]
similar_str = parts[2] # similar_id1:score1,similar_id2:score2,...
# 解析相似商品
similar_items = []
for pair in similar_str.split(','):
if ':' in pair:
sim_id, score = pair.split(':')
similar_items.append([int(sim_id), float(score)])
# 存储到Redis
redis_key = f"item:similar:{algorithm_name}:{item_id}"
redis_value = json.dumps(similar_items)
redis_client.set(redis_key, redis_value)
redis_client.expire(redis_key, expire_seconds)
count += 1
return count
2. 加载兴趣聚合索引
def load_interest_index(file_path, list_type, redis_client, expire_seconds=259200):
"""
加载兴趣点聚合索引到Redis
Args:
file_path: 索引文件路径
list_type: 列表类型(hot, cart, new, global)
redis_client: Redis客户端
expire_seconds: 过期时间(秒),默认3天
"""
import json
count = 0
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
parts = line.strip().split('\t')
if len(parts) != 2:
continue
dimension_key = parts[0] # platform:pc
item_ids_str = parts[1] # 12345,67890,11223,...
# 解析商品ID列表
item_ids = [int(item_id) for item_id in item_ids_str.split(',')]
# 存储到Redis
redis_key = f"interest:{list_type}:{dimension_key}"
redis_value = json.dumps(item_ids)
redis_client.set(redis_key, redis_value)
redis_client.expire(redis_key, expire_seconds)
count += 1
return count
🚀 快速加载命令
加载所有索引
cd /home/tw/recommendation/offline_tasks
# 加载所有索引(使用今天的数据)
python3 scripts/load_index_to_redis.py --redis-host localhost --redis-port 6379
# 加载指定日期的索引
python3 scripts/load_index_to_redis.py --date 20251016 --redis-host localhost
# 只加载i2i索引
python3 scripts/load_index_to_redis.py --load-i2i --redis-host localhost
# 只加载兴趣聚合索引
python3 scripts/load_index_to_redis.py --load-interest --redis-host localhost
验证数据
# 连接Redis
redis-cli
# 检查key数量
DBSIZE
# 查看某个商品的相似推荐
GET item:similar:swing:12345
# 查看平台热门商品
GET interest:hot:platform:pc
# 查看所有i2i相关的key
KEYS item:similar:*
# 查看所有interest相关的key
KEYS interest:*
# 检查key的过期时间
TTL item:similar:swing:12345
📊 数据统计
Redis内存占用估算
| 索引类型 | Key数量 | 单条Value大小 | 总内存 |
|---|---|---|---|
| i2i_swing | 50,000 | ~500B | ~25MB |
| i2i_w2v | 50,000 | ~500B | ~25MB |
| i2i_deepwalk | 50,000 | ~500B | ~25MB |
| i2i_content_name | 50,000 | ~500B | ~25MB |
| i2i_content_pic | 50,000 | ~500B | ~25MB |
| interest_hot | 10,000 | ~1KB | ~10MB |
| interest_cart | 10,000 | ~1KB | ~10MB |
| interest_new | 5,000 | ~1KB | ~5MB |
| interest_global | 10,000 | ~1KB | ~10MB |
| 总计 | 270,000 | - | ~160MB |
过期策略
| 索引类型 | TTL | 原因 |
|---|---|---|
| i2i行为相似 | 7天 | 用户行为变化快,需要频繁更新 |
| i2i内容相似 | 30天 | 商品属性变化慢,可以保留更久 |
| 热门/加购 | 3天 | 热度变化快,需要及时更新 |
| 新品 | 3天 | 新品概念有时效性 |
| 全局热门 | 7天 | 相对稳定,可以保留更久 |
⚠️ 注意事项
- 原子性: 使用Pipeline批量写入,提高性能
- 过期时间: 合理设置TTL,避免过期数据
- 内存管理: 定期清理过期key,监控内存使用
- 数据版本: 使用日期标记,支持数据回滚
- 容错处理: 加载失败时不影响线上服务
- 监控告警: 监控加载成功率、Redis内存、查询延迟
🔍 监控指标
数据质量指标
# 检查加载成功率
total_keys = redis_client.dbsize()
expected_keys = 245000
success_rate = total_keys / expected_keys * 100
# 检查数据完整性
sample_keys = [
'item:similar:swing:12345',
'interest:hot:platform:pc'
]
for key in sample_keys:
if not redis_client.exists(key):
print(f"Missing key: {key}")
性能指标
- 加载耗时:
- 内存占用:
- 查询延迟:
- 成功率: > 99%
🔗 相关文档
- 离线索引规范:
OFFLINE_INDEX_SPEC.md - API接口文档:
RECOMMENDATION_API.md - 运维手册:
OPERATIONS.md