推荐系统整体架构:经典分层架构与高可用挑战
大家好,我是你们的老朋友。今天我们来聊聊推荐系统的骨架——整体架构。
很多同学刚接触推荐系统时,总觉得它是个黑盒。用户点一下,系统就推一堆东西出来。其实拆开来看,它就是一个流水线。我习惯把它分成四层:数据层、召回层、排序层、重排层。每一层都有自己的职责,也都有自己的坑。
一、经典分层架构长什么样?
说白了,推荐系统就是个漏斗。从海量候选集,一步步筛选出用户最可能喜欢的那几个。
我画过一张图,大致是这样的流程:
用户请求 → 数据层(特征/画像) → 召回层(粗筛) → 排序层(精排) → 重排层(业务规则) → 返回结果
每一层都在做减法。召回层把千万级候选集砍到几百,排序层再精排到几十,重排层最后做业务兜底。
1. 数据层
这是地基。没有数据,后面全是空中楼阁。
数据层主要管三件事:
- 用户画像:性别、年龄、兴趣标签、历史行为
- 物品画像:类目、属性、标签、内容特征
- 上下文特征:时间、地点、设备、网络环境
我在项目中遇到过最头疼的事——用户画像更新延迟。用户刚点了个“数码产品”,结果画像里还是三天前的“母婴用品”。你想想看,这推荐能准吗?
2. 召回层
召回层的目标很简单:从全量物品里,快速捞出用户可能感兴趣的候选集。
常用的召回策略有:
- 协同过滤:用户喜欢A,也喜欢B,那就推B
- 向量召回:把用户和物品都映射成向量,算相似度
- 热度召回:最近最火的物品,先捞出来
- 多路召回:不同策略并行,最后合并去重
嗯,这里要注意。召回层追求的是“快”和“全”。宁可多召回一些不相关的,也不能漏掉用户可能喜欢的。
3. 排序层
排序层是推荐系统的核心。它负责对召回结果做精细化打分。
常见的排序模型有:
- LR(逻辑回归):简单、可解释性强
- FM/FFM:能处理特征交叉
- DNN(深度神经网络):表达能力更强
- 多目标排序:同时优化点击率、转化率、停留时长
我个人习惯在排序层加一个“粗排”环节。为什么?因为精排模型太慢了。先粗排筛掉明显不行的,再精排打分,性能能提升好几倍。
4. 重排层
重排层是最后一道关卡。它不改变排序分数,但会调整最终展示顺序。
重排层主要做这些事:
- 去重:同一个物品不能出现两次
- 打散:同类型物品不能连续出现
- 多样性:保证推荐结果覆盖多个类目
- 业务规则:比如广告插播、运营强插
我曾经踩过一个坑。重排层把排序结果打散后,用户点击率反而下降了。后来发现,打散得太均匀,用户找不到自己真正感兴趣的内容。所以重排不是越散越好,得有个度。
二、各层的高可用挑战
架构搭好了,接下来就是怎么让它稳定运行。我总结了每层最常见的几个问题。
1. 数据层的高可用挑战
| 挑战 | 说明 | 我的建议 |
|---|---|---|
| 数据延迟 | 用户行为数据不能实时更新 | 用消息队列做异步处理,保证最终一致性 |
| 数据不一致 | 不同数据源对同一用户画像描述不同 | 建立统一的数据治理规范,定期做数据对账 |
| 存储故障 | Redis、MySQL等存储节点宕机 | 主从切换 + 多副本,做好容灾 |
我记得有一次,用户画像的Redis集群挂了。结果所有推荐结果都变成了默认的热门内容。用户反馈炸了。从那以后,我强制要求数据层必须做降级方案——即使数据拿不到,也不能让推荐接口挂掉。
2. 召回层的高可用挑战
召回层最怕什么?怕召回结果为空。
- 冷启动问题:新用户、新物品没有行为数据,召回不到
- 向量召回索引更新慢:新物品上线后,要等几个小时才能被召回
- 多路召回合并超时:某一路召回太慢,拖累整体响应时间
我的做法是:给每一路召回设置超时时间。超时了就直接跳过,用其他路的结果顶上。宁可少召回一些,也不能让用户等太久。
核心原则:召回层必须保证“有结果返回”,哪怕结果质量差一点。
3. 排序层的高可用挑战
排序层是计算量最大的地方。高并发下,模型推理很容易成为瓶颈。
- 模型推理超时:单个请求推理时间超过100ms
- 模型版本不一致:线上模型和离线训练模型不同步
- 特征缺失:某个特征拿不到,模型直接报错
我建议在排序层做两件事:
- 特征默认值:每个特征都设置一个合理的默认值,防止缺失导致崩溃
- 模型灰度发布:新模型先切1%流量,观察一段时间再全量
你想想看,如果排序层挂了,整个推荐接口就废了。所以排序层一定要做熔断和降级。
4. 重排层的高可用挑战
重排层看似简单,其实坑也不少。
- 业务规则冲突:运营要求A类物品必须排前3,但排序模型认为A类物品质量很差
- 打散算法性能问题:当候选集很大时,打散算法可能很慢
- AB实验干扰:不同实验组的重排规则不同,导致结果混乱
我曾经遇到一个线上事故。运营在重排层加了一条规则:“所有带‘促销’标签的物品必须排第一”。结果当天所有推荐结果都是促销品,用户点击率暴跌。后来我们加了一个规则权重系统,运营规则不能完全覆盖排序结果,只能做微调。
避坑指南:重排层的规则一定要有上限。比如“最多调整前3个位置”,不能全盘推翻排序结果。
三、总结一下
推荐系统的分层架构,每一层都有自己的使命:
- 数据层:提供准确、实时的特征
- 召回层:快速、全面地捞取候选集
- 排序层:精准、稳定地打分排序
- 重排层:灵活、可控地调整展示
高可用不是一蹴而就的。它需要你在每一层都做好容错、降级、监控。说白了,就是“别让一个点炸了,拖垮整条线”。
下一章,我会详细讲讲数据层的高可用设计。包括怎么保证用户画像的实时性,怎么处理数据延迟,以及我踩过的那些坑。咱们下期见。
个人小贴士:刚开始做推荐系统时,别想着一步到位。先把分层架构搭起来,保证每一层都能独立运行。然后再慢慢优化每一层的性能和稳定性。稳扎稳打,比什么都重要。