1、实时推荐系统概述

大家好,我是这门课的主讲。今天咱们聊聊实时推荐系统——说白了,就是用户刚点了个赞,下一秒推荐列表就得跟着变。我做了几年推荐系统,从离线批处理一路做到实时流处理,踩过的坑不少,今天把这些经验掰开揉碎了讲给你听。

什么是实时推荐

实时推荐,核心就一个字——快。

用户的行为数据从产生到影响推荐结果,延迟控制在秒级甚至毫秒级。你想想看,用户在双十一凌晨刷商品,每多等一秒,流失的订单可能就是几百万。我当年在电商平台做推荐,第一次上线实时模块时,看着用户点击后立刻刷出新内容,那种感觉,嗯,确实挺爽的。

实时推荐和传统离线推荐最大的区别在哪?我列个表你就明白了:

维度 离线推荐 实时推荐
数据处理延迟 小时级 / 天级 秒级 / 毫秒级
计算引擎 Hive / Spark Batch Flink / Spark Streaming
存储选型 HDFS / HBase Redis / ClickHouse
模型更新 定时全量重训 增量更新 + 近线融合
典型场景 每日热门榜单 「看了又看」实时推荐

核心要点:实时推荐不是要替代离线推荐,而是两者互补。离线做粗排和候选池生成,实时做精排和个性化兜底。我在项目里经常把离线产出的「用户长期兴趣」和实时计算的「短期行为」做加权融合,效果比单用任何一种都好。

业务场景分析

哪些业务场景必须上实时推荐?我挑三个最常见的说说:

1. 电商场景——「猜你喜欢」实时刷新

用户刚搜了「机械键盘」,又点进「青轴」商品详情页。这时候推荐系统应该立刻把「茶轴」「红轴」的对比款推上来,而不是等明天再更新。我曾经遇到过一个case:用户连续看了三款键盘都没下单,实时推荐立刻切到「键盘手托」和「鼠标垫」这类配件,转化率直接翻了一倍。

2. 内容资讯——「刷不完」的个性化 Feed

抖音、头条这类产品,用户每刷一下,推荐列表就得重新排。用户如果对某条视频点了「不感兴趣」,这条内容以及同类内容必须立刻从 feed 流消失。我记得有一次线上事故,实时屏蔽逻辑出了 bug,用户点了十几次「不感兴趣」还是能看到同类视频,那天的留存数据直接掉了两个点。

3. 社交推荐——「你可能认识的人」

用户刚关注了一个新好友,推荐列表里「共同好友」的权重就得立刻调整。这个场景对延迟要求极高,因为社交关系是实时变化的。我建议这类场景用 Flink 的 CEP(复杂事件处理)来做,比纯规则引擎灵活得多。

避坑指南:不是所有场景都需要实时。我曾经为了追求「实时」硬把用户画像的日更新改成秒更新,结果 Redis 集群被打爆,得不偿失。判断标准很简单——用户行为发生后,推荐结果在 10 秒内不更新会不会影响体验?如果不会,用近线(分钟级)就够了。

技术栈选型:Flink + Kafka + Redis + ClickHouse

这套组合拳,是我个人在多个项目中验证过的「黄金搭档」。为什么选它们?咱们一个一个说。

Flink——实时计算引擎

Flink 是目前流处理的事实标准。它支持 exactly-once 语义、事件时间处理、状态后端管理,这些特性在推荐场景里太重要了。我最早用 Spark Streaming 做实时推荐,遇到乱序数据时窗口计算经常不准,换成 Flink 后问题迎刃而解。

// Flink 实时推荐核心代码片段
DataStream<UserEvent> eventStream = env
    .addSource(new KafkaSource<>())
    .assignTimestampsAndWatermarks(
        WatermarkStrategy.<UserEvent>forBoundedOutOfOrderness(Duration.ofSeconds(5))
    );

// 实时计算用户短期兴趣向量
DataStream<UserVector> userVectorStream = eventStream
    .keyBy(UserEvent::getUserId)
    .process(new UserInterestProcessFunction());

Kafka——消息队列与数据管道

Kafka 负责承接所有用户行为日志,解耦数据生产端和消费端。我习惯把 Kafka 的 topic 按行为类型拆分:click_topic、purchase_topic、favorite_topic 等,方便 Flink 按需订阅。分区数建议设置为 Flink 并行度的 2-3 倍,这样能充分利用并行度。

Redis——实时特征存储

Redis 用来存用户最近 N 条行为、物品的实时热度、以及模型需要的特征缓存。我推荐用 Redis Cluster 模式,避免单点瓶颈。有个小技巧:把用户 ID 做哈希分片,让同一个用户的所有特征落在同一个 Redis 节点上,减少跨节点访问。

ClickHouse——实时 OLAP 分析

ClickHouse 用来做推荐结果的实时分析和监控。比如「过去 5 分钟推荐曝光了多少商品」「点击率是多少」,这些指标需要秒级响应。ClickHouse 的列式存储和向量化执行引擎,跑这类聚合查询比 MySQL 快两个数量级。

组件 核心职责 我推荐的版本 关键配置
Flink 实时流计算 + 状态管理 1.17+ Checkpoint 间隔 30s,状态后端用 RocksDB
Kafka 消息队列 + 数据缓冲 3.4+ 分区数 = Flink 并行度 × 2,副本数 2
Redis 实时特征缓存 7.0+ Cluster 模式,maxmemory-policy allkeys-lru
ClickHouse 实时指标分析 23.3+ MergeTree 引擎,分区按天

注意:技术栈选型不是一成不变的。如果你的业务量级不大(日均百万级事件),用 Flink + Kafka 可能太重了,换成 Redis + 简单的规则引擎也能跑。我见过不少团队一上来就上全套大数据组件,结果运维成本比开发成本还高。选型要匹配业务阶段。

系统架构总览

下面这张图是我画的一个简化版实时推荐架构。你看完就能明白数据是怎么从用户点击流到最终推荐结果的。

实时推荐系统架构总览 用户行为数据源 Kafka 消息队列 Flink 实时计算引擎 行为聚合 · 特征提取 · 实时召回 Redis 实时特征 ClickHouse 实时分析 推荐服务 (召回+排序) 用户端展示 数据流方向:从左到右,从下到上 实时推荐核心链路:用户 → Kafka → Flink → Redis → 推荐服务

整个流程其实不复杂:

  1. 数据采集层:用户的行为(点击、购买、收藏)通过埋点上报到 Kafka。
  2. 实时计算层:Flink 从 Kafka 消费数据,做窗口聚合、特征提取,生成用户短期兴趣向量。
  3. 特征存储层:实时特征写入 Redis,供推荐服务低延迟读取;同时写入 ClickHouse 做监控分析。
  4. 推荐服务层:从 Redis 取实时特征,结合离线产出的候选池,做召回和排序,最终返回推荐列表给用户。

架构要点:这套架构里最容易被忽视的是「数据闭环」。推荐服务产出的结果(曝光、点击)要回流到 Kafka,形成新的行为数据,这样才能让模型持续自学习。我见过不少团队只做了正向流程,忽略了回流,结果模型越跑越偏。