推荐系统整体架构:经典分层架构与高可用挑战

大家好,我是你们的老朋友。今天我们来聊聊推荐系统的骨架——整体架构。

很多同学刚接触推荐系统时,总觉得它是个黑盒。用户点一下,系统就推一堆东西出来。其实拆开来看,它就是一个流水线。我习惯把它分成四层:数据层、召回层、排序层、重排层。每一层都有自己的职责,也都有自己的坑。

一、经典分层架构长什么样?

说白了,推荐系统就是个漏斗。从海量候选集,一步步筛选出用户最可能喜欢的那几个。

我画过一张图,大致是这样的流程:

用户请求 → 数据层(特征/画像) → 召回层(粗筛) → 排序层(精排) → 重排层(业务规则) → 返回结果

每一层都在做减法。召回层把千万级候选集砍到几百,排序层再精排到几十,重排层最后做业务兜底。

1. 数据层

这是地基。没有数据,后面全是空中楼阁。

数据层主要管三件事:

  • 用户画像:性别、年龄、兴趣标签、历史行为
  • 物品画像:类目、属性、标签、内容特征
  • 上下文特征:时间、地点、设备、网络环境

我在项目中遇到过最头疼的事——用户画像更新延迟。用户刚点了个“数码产品”,结果画像里还是三天前的“母婴用品”。你想想看,这推荐能准吗?

2. 召回层

召回层的目标很简单:从全量物品里,快速捞出用户可能感兴趣的候选集。

常用的召回策略有:

  • 协同过滤:用户喜欢A,也喜欢B,那就推B
  • 向量召回:把用户和物品都映射成向量,算相似度
  • 热度召回:最近最火的物品,先捞出来
  • 多路召回:不同策略并行,最后合并去重

嗯,这里要注意。召回层追求的是“快”和“全”。宁可多召回一些不相关的,也不能漏掉用户可能喜欢的。

3. 排序层

排序层是推荐系统的核心。它负责对召回结果做精细化打分。

常见的排序模型有:

  • LR(逻辑回归):简单、可解释性强
  • FM/FFM:能处理特征交叉
  • DNN(深度神经网络):表达能力更强
  • 多目标排序:同时优化点击率、转化率、停留时长

我个人习惯在排序层加一个“粗排”环节。为什么?因为精排模型太慢了。先粗排筛掉明显不行的,再精排打分,性能能提升好几倍。

4. 重排层

重排层是最后一道关卡。它不改变排序分数,但会调整最终展示顺序。

重排层主要做这些事:

  • 去重:同一个物品不能出现两次
  • 打散:同类型物品不能连续出现
  • 多样性:保证推荐结果覆盖多个类目
  • 业务规则:比如广告插播、运营强插

我曾经踩过一个坑。重排层把排序结果打散后,用户点击率反而下降了。后来发现,打散得太均匀,用户找不到自己真正感兴趣的内容。所以重排不是越散越好,得有个度。

二、各层的高可用挑战

架构搭好了,接下来就是怎么让它稳定运行。我总结了每层最常见的几个问题。

1. 数据层的高可用挑战

挑战 说明 我的建议
数据延迟 用户行为数据不能实时更新 用消息队列做异步处理,保证最终一致性
数据不一致 不同数据源对同一用户画像描述不同 建立统一的数据治理规范,定期做数据对账
存储故障 Redis、MySQL等存储节点宕机 主从切换 + 多副本,做好容灾

我记得有一次,用户画像的Redis集群挂了。结果所有推荐结果都变成了默认的热门内容。用户反馈炸了。从那以后,我强制要求数据层必须做降级方案——即使数据拿不到,也不能让推荐接口挂掉。

2. 召回层的高可用挑战

召回层最怕什么?怕召回结果为空。

  • 冷启动问题:新用户、新物品没有行为数据,召回不到
  • 向量召回索引更新慢:新物品上线后,要等几个小时才能被召回
  • 多路召回合并超时:某一路召回太慢,拖累整体响应时间

我的做法是:给每一路召回设置超时时间。超时了就直接跳过,用其他路的结果顶上。宁可少召回一些,也不能让用户等太久。

核心原则:召回层必须保证“有结果返回”,哪怕结果质量差一点。

3. 排序层的高可用挑战

排序层是计算量最大的地方。高并发下,模型推理很容易成为瓶颈。

  • 模型推理超时:单个请求推理时间超过100ms
  • 模型版本不一致:线上模型和离线训练模型不同步
  • 特征缺失:某个特征拿不到,模型直接报错

我建议在排序层做两件事:

  1. 特征默认值:每个特征都设置一个合理的默认值,防止缺失导致崩溃
  2. 模型灰度发布:新模型先切1%流量,观察一段时间再全量

你想想看,如果排序层挂了,整个推荐接口就废了。所以排序层一定要做熔断和降级。

4. 重排层的高可用挑战

重排层看似简单,其实坑也不少。

  • 业务规则冲突:运营要求A类物品必须排前3,但排序模型认为A类物品质量很差
  • 打散算法性能问题:当候选集很大时,打散算法可能很慢
  • AB实验干扰:不同实验组的重排规则不同,导致结果混乱

我曾经遇到一个线上事故。运营在重排层加了一条规则:“所有带‘促销’标签的物品必须排第一”。结果当天所有推荐结果都是促销品,用户点击率暴跌。后来我们加了一个规则权重系统,运营规则不能完全覆盖排序结果,只能做微调。

避坑指南:重排层的规则一定要有上限。比如“最多调整前3个位置”,不能全盘推翻排序结果。

三、总结一下

推荐系统的分层架构,每一层都有自己的使命:

  • 数据层:提供准确、实时的特征
  • 召回层:快速、全面地捞取候选集
  • 排序层:精准、稳定地打分排序
  • 重排层:灵活、可控地调整展示

高可用不是一蹴而就的。它需要你在每一层都做好容错、降级、监控。说白了,就是“别让一个点炸了,拖垮整条线”。

下一章,我会详细讲讲数据层的高可用设计。包括怎么保证用户画像的实时性,怎么处理数据延迟,以及我踩过的那些坑。咱们下期见。

个人小贴士:刚开始做推荐系统时,别想着一步到位。先把分层架构搭起来,保证每一层都能独立运行。然后再慢慢优化每一层的性能和稳定性。稳扎稳打,比什么都重要。