第一阶段:项目背景与起因
1.1 核心危机:当算法陷入“局部最优解”
如果你做过推荐系统相关的数据工程,你一定听过**“劣币驱逐良币”**。当时的我们正处于这个危机的风暴眼。从数据监控来看,我们的日活虽然在涨,但一个关键指标——优质内容消费时长占比——却在断崖式下跌。
发生了什么? 早期的推荐算法是“唯点击率(CTR)论”的:
- 搬运号/营销号:利用美女封面、惊悚标题(标题党)、擦边球内容,骗取了极高的点击率 。
- 算法的反应:算法觉得“用户喜欢看”,于是疯狂分发这些低质内容。
- 优质创作者:辛辛苦苦拍的原创视频,因为封面不够“炸”,点击率一般,拿不到流量。
- 结果:内容池被“噪声”淹没。用户觉得平台变 Low 了,开始流失;优质作者赚不到钱,开始停更。
这就是我们要解决的工程命题: 我们需要构建一个**“上帝视角”的过滤器**。算法做不到的“价值判断”,需要数仓通过全生命周期的行为分析来完成。我们要把内容池的信噪比重新拉回来。
1.2 工程使命:创作者分层体系
业务方希望我们不仅仅是“洗数据”,而是要给全平台 1000万+ 创作者打上“阶级标签” 。这不是简单的 IF...ELSE,这是一个基于价值的流量分配系统。
我们需要将创作者划分为以下四层,每一层对应不同的工程策略:
- 🏆 S/A级(头部)
- 定义:金字塔尖的 1%。高原创、高粘性、高商业价值 。
- 数据特征:粉丝留存率极高,完播率稳定。
- 策略:现金补贴 + 流量加权。数据必须 100% 准确,任何误判都会导致投诉。
- 🌱 B级(腰部)
- 定义:潜力股。内容很好,但粉丝少,没人看。
- 数据特征:完播率高(内容好),但曝光量低。
- 策略:冷启动扶持。这是系统的核心增长点,我们要把这部分人捞出来。
- 📉 C/D级(尾部)
- 定义:素人、搬运号、营销号。
- 数据特征:高查重率、发布频率异常(机器搬运)、低互动 。
- 策略:打压与清洗。减少推荐权重,甚至封禁。
💡 笔记: 为什么不能只用“粉丝数”定级? 这是一个典型的虚荣指标。很多 10万粉丝的账号全是僵尸粉,互动率极低;而很多只有 1000 粉丝的新作者,完播率却高达 60%。 作为数据工程师,我们的任务是挖掘“隐性价值”。 我们要计算的是 LTV(生命周期价值),而不是粉丝数。
1.3 建设规模与数据链路
这个项目不是做一个离线报表那么简单,它是一个闭环系统。
我们要处理的数据规模:
- 数据体量:每日增量数据 2.1 TB 。
- 事件量:日均处理用户行为事件 10 亿+ 。
- 覆盖对象:覆盖全生命周期 1000 万+ 创作者 。
数据链路概览: 我们要构建的不仅仅是数仓,而是从采集到服务的全链路 :
- 输入源:
- 客户端日志:用户的每一次触屏(展现、点击、滑动、长按、评论)。
- 服务端日志:视频的审核状态、账号的封禁状态。
- 核心计算:
- 清洗脏数据(DWD) 。
- 计算复杂的互动指标(DWS)。
- 运行分层算法模型(Spark ML/规则引擎)。
- 输出服务:
- 在线服务:将标签(如
level: S)推送到 Redis/HBase,供推荐引擎实时读取,调整分发权重 。 - 分析监控:推送到 ClickHouse/Tableau,供运营监控“大盘健康度”。
- 在线服务:将标签(如
第一阶段总结
这一部分的核心价值: 我们不仅定义了“要做什么”,更澄清了“业务痛点”(信噪比危机)和“工程挑战”(不能用单一指标,要处理海量行为数据)。 这为后续 第二阶段 的架构选型埋下了伏笔:正是因为要处理 10亿+ 的复杂行为数据,且需要回溯历史来判断价值,我们才不能只用简单的数据库,而必须上 Spark + Hive 的混合架构。
第二阶段:架构设计与技术选型
很多初级工程师的通病是“手里有把锤子,看什么都是钉子”(比如只会 Flink 就强行用 Flink 做所有事)。我们需要根据业务场景(创作者分层)来做取舍。
2.1 总体架构:混合架构的博弈

我们面临一个经典的快与准的矛盾:
- 业务想要快:作者发了视频,最好几分钟内就有反馈(流量激励),否则作者会觉得平台没反应。
- 模型需要准:要判断一个作者是不是“优质”,不能只看这一个视频,必须回溯他过去 180天 的完播率稳定性、涨粉趋势、违规记录。
纯实时架构(Real-time) 存不下半年的状态;纯离线架构(Batch) 反应太慢。
所以,我们设计了 “Kappa架构变体 + T+1 离线校准” 的混合链路 1。
数据流转逻辑:
- 快链路(准实时层):
- 目的:解决当天的冷启动激励。
- 流向:
Kafka->Spark Streaming->Redis。 - 逻辑:只看当前视频的瞬时表现。如果完播率极高,立刻给一个“临时潜力标签”。这叫“快”。
- 慢链路(离线核心层):
- 目的:决定作者的最终评级(S/A/B/C)和全量特征校准。
- 流向:
ODS (日志)->DWD (清洗)->DWS (画像聚合)->ADS (分层计算)。 - 逻辑:每天凌晨,基于全量的历史数据 + 昨天的增量数据,重新跑一遍复杂的算法,修正作者的等级。
💡 笔记:
我们称之为 "T+1 校准"。
考虑到创作者激励机制需要实时反馈(如流量扶持),但精准的分层模型依赖离线特征校准,故在 Kappa 架构基础上添加 T+1 校准批处理层 2。
实时流给出的标签是“预估值”,离线批处理给出的标签是“最终真值”。第二天早上,离线结果会覆盖实时结果。
2.2 技术栈选型与决策理由
面试时,别只背诵组件名字。要能说出**“为什么”**。以下是我们在该项目中的决策清单:
| 组件层级 | 我们的选择 | 为什么选它?(核心决策理由) |
| 计算引擎 | Apache Spark | 核心原因:迭代计算能力强。 创作者分层涉及大量复杂的 Join(关联)和迭代逻辑。相比 MapReduce,Spark 的内存计算快 10-100 倍。相比 Flink,Spark 在处理海量离线宽表的 Join 时更稳定,不容易 OOM(内存溢出)。我们使用 Spark SQL 处理数仓逻辑,Spark Core 处理复杂倾斜场景 |
| 存储底座 | HDFS + Hive | 核心原因:成本与吞吐。 我们要存 PB 级的数据,HDFS 是最经济的方案。Hive 提供了 SQL 接口,方便构建分层模型和元数据管理 |
| 数据治理 | 自研/DolphinScheduler | 核心原因:依赖管理。 分层任务有严格的先后顺序。我们需要严格的血缘追踪,我们的系统覆盖了 95% 的核心表字段血缘追踪 |
| 数据加速 | Z-Order Index | 核心原因:多维查询慢。 仅仅用 Hive 分区是不够的。我们需要 Z-Order 聚类策略来加速广告主对“多维度组合”的查询速度,将响应时间从 12s 降至 1.3s |
2.3 数仓分层模型规划
我们将数据仓库划分为标准的四层,每一层都有严格的职责边界,绝对不允许跨层调用(比如 ADS 层直接去读 ODS 层)^7。
- ODS 层 (原始数据层)
- 保持原貌,不做修改,直接映射日志文件。
- DWD 层 (明细数据层) —— 数据质量的防线
- 职责:进行行列级数据治理。
- 关键动作:我们在这一层修复了 27种 脏数据场景(如异常值、格式错误),确保下游拿到的数据是干净的 8。
- 粒度:保持原子粒度,不进行聚合。
- DWS 层 (服务汇总层) —— 🌟最关键的一层
- 职责:按作者粒度进行轻度汇总,构建画像。
- 关键技术:采用 SCD Type 4 (渐变维) 策略。
- 理由:我们需要追踪创作者等级变更轨迹(例如:某作者上个月是 B 级,这个月变成了 A 级),Type 4 策略能完美支持这种历史状态追溯 9。
- ADS 层 (应用数据层)
- 职责:直接为业务报表和在线服务提供数据。
- 优化:应用 Z-Order 优化,支撑万级 QPS 的实时查询 10101010。
第二阶段总结
我们做了什么?
我们确定了“离线为主,实时为辅”的战略,并选定了 Spark + Hive 作为重型武器,利用 SCD Type 4 解决历史回溯问题,利用 Z-Order 解决查询性能问题。