设计用户画像系统
需求
设计用户画像和标签管理系统,支持:
- 千万级用户的标签计算和存储
- 运营人员自助圈选人群(秒级响应)
- 标签实时更新(如用户刚完成首购,立刻打上"新付费用户"标签)
架构设计
标签体系
| 标签层级 | 说明 | 更新频率 | 示例 |
|---|---|---|---|
| 基础属性 | 用户注册信息 | 准实时 | 性别、年龄、城市 |
| 行为标签 | 统计类行为指标 | T+1 | 近 30 天登录次数、购买次数 |
| 偏好标签 | 兴趣和偏好 | T+1 | 偏好品类、价格敏感度 |
| 预测标签 | ML 模型输出 | T+1/周 | 流失概率、付费意愿 |
| 实时标签 | 实时计算 | 秒级 | 当前在线、刚加购 |
标签计算
-- 离线标签:用户 RFM 分层(Spark SQL)
INSERT OVERWRITE TABLE user_tags PARTITION (tag_type = 'rfm')
SELECT
user_id,
CASE
WHEN recency_score >= 4 AND frequency_score >= 4 AND monetary_score >= 4 THEN '高价值活跃'
WHEN recency_score <= 2 AND frequency_score >= 3 THEN '沉睡用户'
WHEN recency_score >= 4 AND frequency_score <= 2 THEN '新用户'
ELSE '普通用户'
END AS tag_value,
CURRENT_DATE AS update_date
FROM (
SELECT
user_id,
NTILE(5) OVER (ORDER BY DATEDIFF(CURRENT_DATE, last_order_date)) AS recency_score,
NTILE(5) OVER (ORDER BY order_count) AS frequency_score,
NTILE(5) OVER (ORDER BY total_amount) AS monetary_score
FROM user_order_summary
);
人群圈选引擎
| 方案 | 适用场景 | 响应时间 | 存储 |
|---|---|---|---|
| Bitmap | 固定标签交并差 | 毫秒级 | Redis Bitmap |
| 倒排索引 | 多条件组合查询 | 秒级 | Elasticsearch |
| 预计算Cube | 固定维度组合 | 毫秒级 | ClickHouse |
| 即时计算 | 自定义复杂条件 | 10秒+ | Spark/Presto |
# Bitmap 人群交集示例
# 标签存储为 Redis Bitmap,用户 ID 为 bit 位
# 圈选 "女性 AND 近30天活跃 AND 高价值" 的用户
import redis
r = redis.Redis()
# 三个标签的 Bitmap 取交集
r.bitop('AND', 'result:target_users',
'tag:gender:female',
'tag:active:30d',
'tag:value:high')
# 统计人群数量
count = r.bitcount('result:target_users')
常见面试问题
Q1: 标签膨胀如何处理?
答案:
- 标签分级:核心标签(必须维护) vs 衍生标签(按需生成)
- TTL 过期:设置标签有效期,过期自动清理
- 使用率监控:定期清理 30 天内无人查询的标签
- 模板化:通过标签模板 + 参数化生成,避免大量相似标签
Q2: 实时标签和离线标签如何统一?
答案:
- 双写架构:实时标签写 Redis,离线标签写 HBase
- 查询合并:查询时优先取实时标签,回退到离线标签
- 定期校准:每日离线任务覆盖实时标签,保证一致性