今⽇日头条 User Profile
系统架构实践
丁海峰
推荐系统是怎样⼯工作的
• ⾼高质量的⽤用户特征是做好推荐的关键之⼀一
什么是好的推荐效果
• 点击率,但不仅是点击率
• 内容⾼高质量,丰富多样,有惊喜感,能够帮助⽤用
户探索兴趣,快速反馈⼜又不能过度灵敏,etc.
• ⻓长期⺫⽬目标
• ⽤用户:有兴趣,有收获,愿意⻓长期使⽤用
• ⽣生态:⿎鼓励良币,驱逐劣币
需要怎样的⽤用户特征
• ⼈人⼝口学:性别、年龄、地域,etc.
• 内容特征:category, topic, keyword, entity, etc.
• 喜欢 & 不喜欢
• 短期 & ⻓长期
• 协同特征:相似⽤用户
• 其它:. 逼格
My Profile
算法
• 点击加权 & 未点击惩罚
• 热⻔门点击降权
• 时间衰减
• 噪声过滤:spam,标题党等
• 其它精细的调优
System Overview
Our Challenges
• 存量⽤用户量⼤大,⽤用户⾏行为数据量巨⼤大
• 期望快速反馈
• Online serving storage: 读写吞吐⾼高,时延低且可
预期
⼀一些数字
• ⽤用户⾏行为数据
• 历史存量:500TB+ (压缩后)
• 每⽇日新增:1TB+ (压缩后)
• ⾼高峰时段:400K msg/s (Overall)
• Profile Server
• feature 数量:200+
• 容量:单副本 12TB
• 请求次数: qps
Batch Approach
• Batch 计算,MySQL 存储
• Daily Mapreduce Workflow
• 对每⽇日活跃⽤用户,抽取该⽤用户过去两个⽉月的展
⽰示和动作,从0开始重建该⽤用户的 user profile
问题
• CPU 密集,⼤大量重复计算
• ⾼高写⼊入吞吐,MySQL 瓶颈
• 更新不及时,⽤用户动作反馈到 user profile 可能会
⻓长达两天
Streaming Approach
• A Storm Topology
• mini-batch processing
• 固定 10 min 时间窗⼝口
• 获取⽤用户上⼀一次 profile 状态作为 base
• 做时间衰减
• 使⽤用新增的展⽰示和动作更新 profile
Pros.
• ⽤用户动作反馈周期⼤大⼤大缩短:2天 -> 10分钟
• 减少重复计算,节省⼤大量计算资源
Cons.
• 统计类特征会有延迟,即时值 不等于 最终值
• 点击延迟:⽤用户可能在展⽰示之后⼀一段时间才会点击
• 热点⽂文章点击降权:热点⽂文章,在⽂文章发布初期点击的⽤用户被
错误的认为点击了冷⻔门⽂文章
• ⽂文本特征延迟:spam 标题党等特征判定会有延迟
• 算法上线可能会有异常,需要回滚 user profile
• batch 更容易,覆盖新数据即可
• streaming 计算需要 replay ⻓长时间的历史数据,开销反⽽而更⼤大
Hybrid Approach
• 在 Streaming 更新的基础上,引⼊入周级的 Batch
校准
• 以上⼀一次 Batch 计算产出的 user profile 快照作为
base,replay 其后产⽣生的⽤用户展⽰示、动作并更新
user profile
Data pipeline
算法接⼝口抽象
• Storm & Mapreduce 计算模型有差异,但核⼼心算
法⼀一致
• 抽象核⼼心算法接⼝口,算法实现保持⼀一致,避免维
护两份不同的 Code
• update_profile(base_profile, impressions, actions)
=> new_profile
• Re-thinking: Spark & Spark Streaming
UserActionStore
• 基于 HBase 实现的,实时、可随机读写、可扩展
的⽤用户⾏行为存储
• 以 (hash, user_id, timestamp) 为 RowKey
• 访问接⼝口
• _impressions(uid, start_time, end_time)
• _actions(uid, start_time, end_time)
ProfileStore
• 需求
• 读请求稳定低延迟:serve 在线访问请求
• ⾼高写⼊入吞吐:batch/流式更新
• 数据多副本
• 数据量巨⼤大,需要可⽔水平扩展
Springdb
• twemproxy + rocksdb
• 主从同步 双副本
• twemproxy reload 配置实现主从切换
• 重写 compaction 策略,降低写放⼤大系数
• latency ⻓长尾调优,减少超时
LSM-Tree Compaction
Fight with Write-Amp
• rocksdb: LSM-Tree, compaction, 写放⼤大10x~, SSD 寿命
• Our Solution:
• 限制只使⽤用 L0~L1,减少 compaction 层次
• Customized Level Style Compaction
• L0 ⼩小⽂文件 compaction => L0
• L0 ⼤大⽂文件 full compaction => L1
• 写放⼤大 10x~ => 2~3x,读放⼤大、空间放⼤大可接受
•
Performance
• 数据量:压缩后 12TB 数据 x 2副本
• QPS:read 140K,write 55K (cache 后)
• 时延:avg 500us, pct99 5ms
• 机器:16台机器,SSD,存储瓶颈
Lessons we learned
• Batch + Streaming 是⼀一种常⽤用的模式
• 合适的基础设施和业务抽象,减少重复
• 深⼊入理解 workload,选择合适的存储系统
• Rocksdb on SSD rocks!
Thanks for listening.
Joint work with many others.
Q&A Time