1. 平台架构总览:实时推荐系统整体架构、数据流转链路、核心组件介绍

大家好,我是这次课程的主讲。做实时推荐系统运维有些年头了,踩过的坑不少,积累的经验也还算扎实。今天咱们先聊聊整个平台的骨架——架构、数据怎么流、以及那几个核心组件到底在干什么。

你可能会问:为什么第一节课就要讲架构?我个人的习惯是,不管接手什么系统,第一件事就是把架构图画出来。没有全局视角,后面排查问题就像盲人摸象。说白了,你得知道数据从哪来、经过谁、最后去哪,才能知道故障出在哪一环。

一句话总结:实时推荐平台 = 实时采集 + 实时计算 + 实时存储 + 实时服务。四个环节缺一不可,任何一个环节出问题,推荐效果都会打折扣。

1.1 整体架构分层

我习惯把实时推荐平台分成四层来看。这样分层,故障定位会清晰很多。

  • 数据接入层:负责收集用户行为日志、业务事件。主力是 Kafka。
  • 实时计算层:负责特征计算、模型推理、规则引擎。主力是 Flink。
  • 存储层:负责特征存储、模型参数、实时结果。主力是 Redis 和 HBase。
  • 服务层:负责对外提供推荐 API,组装结果返回给客户端。

嗯,这里要注意:分层不是的。比如 Redis 既做缓存也做实时特征存储,HBase 既存画像也存中间结果。但脑子里有这个分层模型,遇到问题就能快速缩小范围。

下面这张图是我自己画的架构总览,你可以对照着看。

实时推荐平台架构总览 数据接入层 用户行为日志 · 业务事件 · 外部数据源 Kafka Cluster 日志采集 Agent API Gateway 实时计算层 特征计算 · 模型推理 · 规则引擎 · 实时统计 Flink Job (CEP) Flink SQL Pipeline 模型推理服务 存储层 特征存储 · 模型参数 · 用户画像 · 实时结果 Redis Cluster HBase MySQL / TiDB HDFS 服务层 推荐 API · 结果组装 · 降级兜底 · A/B 测试 推荐服务 (Java/Go) AB 实验平台 数据流:用户行为 → Kafka → Flink 计算 → 写入 Redis/HBase → 推荐服务读取 → 返回推荐结果

1.2 数据流转链路详解

数据是怎么一步步走的?我拿一个典型的「用户点击商品」事件来举例。

  1. 用户点击商品,前端 SDK 生成一条日志,包含 userId、itemId、timestamp、行为类型。
  2. 日志发送到 Kafka,写入名为 user_behavior 的 Topic。这里一般会做分区,按 userId 哈希,保证同一个用户的行为落到同一个分区。
  3. Flink 消费 Kafka,做几件事:
    • 解析 JSON,做数据清洗(过滤爬虫、异常数据)。
    • 计算实时特征,比如「用户最近 5 分钟点击次数」「商品实时热度」。
    • 调用模型服务,获取推荐候选集。
    • 将特征和结果写入 Redis 和 HBase。
  4. 推荐服务收到请求,从 Redis 读取用户实时特征,从 HBase 读取用户长期画像,组装成最终推荐列表返回。

整个过程,从用户点击到推荐结果返回,延迟要求通常在 200ms 以内。嗯,这个 SLA 其实挺苛刻的。我在项目中遇到过因为 Kafka 消费积压导致推荐延迟飙升到 5 秒的情况,最后排查发现是 Flink 的 Checkpoint 超时了。

我的经验:数据链路中,最容易出问题的三个点是:Kafka 消费偏移量提交失败、Flink Checkpoint 超时、Redis 热 key 导致阻塞。后面我们会专门讲这些场景的排查方法。

1.3 核心组件介绍

四个组件,每个都有它的脾气。我挑重点说。

1.3.1 Kafka —— 数据高速公路

Kafka 是整个系统的数据总线。所有行为数据、业务事件都经过它。说白了,没有 Kafka,实时计算就是无源之水。

角色 说明 运维关注点
Producer 写入数据,如日志 Agent、业务服务 写入吞吐、ACK 策略、重试机制
Broker 存储数据,集群节点 磁盘空间、ISR 同步、Leader 选举
Consumer 消费数据,如 Flink、推荐服务 消费延迟、Rebalance 频率、偏移量提交
Topic 数据分类,如 user_behavior、item_update 分区数、副本数、数据保留策略

我个人习惯把 Kafka 的监控放在第一位。消费延迟超过 1 分钟就要报警,超过 5 分钟就要介入。我曾经因为没及时处理消费积压,导致 Flink 任务 OOM,整个推荐链路挂了半小时。

1.3.2 Flink —— 实时计算引擎

Flink 是实时推荐的大脑。它负责消费 Kafka 数据,做各种计算。你想想看,如果没有 Flink,这些计算就得靠批处理,延迟至少几分钟,实时推荐就变成「准实时」了。

Flink 在实时推荐中的典型用法:

  • CEP(复杂事件处理):识别用户行为序列,比如「用户连续点击 3 次同品类商品」,触发推荐策略调整。
  • 实时特征计算:用 Flink SQL 做窗口聚合,比如 SELECT userId, COUNT(*) FROM clicks GROUP BY TUMBLE(ts, INTERVAL '5' MINUTE)。
  • 模型推理:加载训练好的模型,对每条事件做实时打分。

注意:Flink 的 Checkpoint 是保证 Exactly-Once 语义的关键。但 Checkpoint 超时或失败,会导致数据重复或丢失。我建议 Checkpoint 间隔不要超过 5 分钟,超时时间设为 10 分钟。如果频繁超时,优先检查反压和 GC。

1.3.3 Redis —— 实时特征缓存

Redis 在实时推荐里主要干两件事:

  • 缓存实时特征:比如用户最近 5 分钟的点击列表、商品实时热度。这些数据更新快,用 Redis 的 Hash 或 Sorted Set 存。
  • 缓存模型参数:一些轻量级的模型参数,比如 LR 的权重,直接放 Redis,推理时毫秒级读取。

Redis 的坑主要在热 key 和大 key。我记得有一次,某个爆款商品的实时热度 key 被疯狂读取,导致 Redis 实例 CPU 打满,所有请求都卡住了。后来我们做了本地缓存 + 热 key 拆分才解决。

1.3.4 HBase —— 用户画像存储

HBase 存的是用户长期画像和物品属性。比如用户过去 30 天的购买记录、商品类目偏好。这些数据量大,但不需要毫秒级更新,HBase 的 LSM-Tree 结构很适合。

HBase 的 RowKey 设计很关键。我一般用 userId 反转 + 时间戳 作为 RowKey,这样能避免热点,同时支持按时间范围扫描。

组件选型总结:

  • 需要高吞吐、持久化、顺序读写 → Kafka
  • 需要状态计算、事件时间、Exactly-Once → Flink
  • 需要毫秒级读写、高并发、数据结构丰富 → Redis
  • 需要海量存储、稀疏列、范围扫描 → HBase

1.4 架构设计的几个原则

最后,分享几个我做架构设计时坚持的原则。这些原则帮我避免了不少线上事故。

  • 解耦:每一层之间通过 Kafka 或 API 解耦。这样某一层挂了,不会直接拖垮其他层。
  • 降级兜底:推荐服务必须有降级策略。比如 Redis 挂了,就从 HBase 读离线特征;HBase 也挂了,就返回热门推荐。
  • 可观测性:每一层都要有完善的监控和日志。没有监控的架构,出了故障就是盲人摸象。
  • 容量规划:Kafka 的分区数、Flink 的并行度、Redis 的内存、HBase 的 Region 数,都要提前规划好。我见过太多因为分区数不够导致消费倾斜的案例。

好了,这一章的内容就到这里。架构是骨架,数据是血液,组件是器官。理解了它们的关系,后面的故障排查才能有的放矢。