实时推荐架构总览:离线批处理 vs 实时流处理、Lambda架构与Kappa架构、实时推荐的技术选型
大家好,我是你们的老朋友。今天咱们聊聊实时推荐的整体架构。
很多刚入行的朋友,一上来就问我:“老师,实时推荐到底该用Lambda还是Kappa?” 说实话,这个问题没有标准答案。我做了这么多年架构,见过不少团队在选型上栽跟头。今天我就把这块掰开了讲清楚。
离线批处理 vs 实时流处理
先搞清楚这两个概念。说白了,就是“算得快”和“算得全”的博弈。
| 维度 | 离线批处理 | 实时流处理 |
|---|---|---|
| 计算延迟 | 分钟级到小时级 | 毫秒级到秒级 |
| 数据量 | 全量历史数据 | 近期窗口数据 |
| 计算精度 | 高(全量计算) | 较低(近似计算) |
| 典型框架 | Hive、Spark SQL、MapReduce | Flink、Spark Streaming、Kafka Streams |
| 适用场景 | 用户画像、离线模型训练 | 实时召回、在线特征计算 |
我个人习惯把离线批处理比作“慢工出细活”。它能把所有历史数据翻个底朝天,算出来的结果非常准。但问题是,等你算完,用户可能已经刷了十几条新内容了。
实时流处理呢?它就像“快刀斩乱麻”。数据一来,立刻处理,几毫秒就能给出推荐结果。但精度上会打折扣,毕竟它只能看最近几分钟的数据。
Lambda架构与Kappa架构
好,现在咱们聊聊架构选型。这两个架构,是实时推荐领域的“少林”和“武当”。
Lambda架构
Lambda架构,说白了就是“两条腿走路”。一条腿是离线批处理层,负责全量计算;另一条腿是实时流处理层,负责增量计算。最后在服务层把两边的结果合并。
它的核心思想是:用离线层保证准确性,用实时层保证低延迟。
我刚开始做推荐系统时,用的就是Lambda架构。当时团队人少,离线层用Spark SQL跑用户画像,实时层用Storm做点击流处理。两套代码,两套运维,确实累。但好处是,离线层算错了,实时层还能兜底。
Kappa架构
Kappa架构就激进多了。它只保留实时流处理层,所有数据都走实时管道。离线计算?不存在的。它通过重放Kafka中的历史数据,来实现全量计算。
你想想看,Kappa架构的好处是什么?一套代码,一套运维。不用再维护两套逻辑,开发效率直接翻倍。
但问题也很明显:实时流处理框架的容错能力,决定了整个系统的上限。如果Flink或Kafka Streams挂了,你的全量计算也得重来。
| 对比维度 | Lambda架构 | Kappa架构 |
|---|---|---|
| 代码维护 | 两套代码(离线+实时) | 一套代码(纯实时) |
| 数据一致性 | 离线层兜底,一致性高 | 依赖流框架的Exactly-Once语义 |
| 运维复杂度 | 高(两套集群) | 低(一套集群) |
| 适用场景 | 对准确性要求极高的场景 | 对延迟敏感、数据量可控的场景 |
实时推荐的技术选型
技术选型这块,我踩过的坑比走过的路还多。咱们直接上干货。
消息队列选型
消息队列是实时推荐的“血管”。数据流不通,后面全白搭。
- Kafka:业界标准。高吞吐、持久化、支持重放。我个人习惯用它做核心消息总线。
- Pulsar:新兴力量。支持分层存储、多租户。如果你需要跨地域复制,可以考虑它。
- RocketMQ:阿里出品。低延迟、事务消息。适合电商场景。
嗯,这里要注意:别用Redis做消息队列。我在项目中遇到过,有人拿Redis List当消息队列用,结果数据积压时直接OOM。Redis适合做缓存,不适合做消息管道。
流处理框架选型
流处理框架是实时推荐的“大脑”。选对了,事半功倍;选错了,天天加班。
| 框架 | 优势 | 劣势 | 推荐场景 |
|---|---|---|---|
| Flink | Exactly-Once语义、事件时间处理、状态管理强大 | 学习曲线陡峭 | 复杂实时计算、CEP、窗口聚合 |
| Spark Streaming | 生态丰富、与Spark SQL无缝集成 | 微批次延迟较高(秒级) | 与离线任务共用集群的场景 |
| Kafka Streams | 轻量级、与Kafka深度集成 | 状态管理较弱 | 简单的ETL、实时特征计算 |
我个人习惯:核心推荐链路用Flink,因为它的事件时间处理和状态管理,能保证推荐结果的准确性。简单的数据清洗和特征计算,用Kafka Streams就够了,轻量又高效。
存储选型
实时推荐的存储,讲究“快”和“准”。
- 在线特征存储:Redis、Aerospike。要求毫秒级读写,支持高并发。
- 用户画像存储:HBase、Cassandra。支持宽表、稀疏列,适合存储用户的多维标签。
- 实时索引:Elasticsearch。用于召回阶段的向量检索和倒排索引。
架构总览图
说了这么多,咱们用一张图把整体架构串起来。这张图是我在多个项目中沉淀下来的,你可以直接拿去用。
这张图里,我特意把离线层和实时层并列。你可能会问:“为什么存储层要单独画出来?” 因为存储是实时推荐的瓶颈。我在项目中遇到过,Redis扛不住高并发,导致推荐接口超时。后来加了本地缓存和限流,才稳住。
选型决策树
最后,我给大家一个简单的选型决策树。照着这个走,至少不会出大错。
- 数据量 < 10TB,团队 < 5人 → Kappa架构 + Kafka + Flink + Redis + ES
- 数据量 10TB~100TB,团队 5~10人 → Lambda架构 + Kafka + Flink + Spark SQL + HBase + Redis
- 数据量 > 100TB,团队 > 10人 → Lambda架构 + Pulsar + Flink + Spark + HBase + ES + 自研存储