1、日志场景的痛点分析:传统离线批处理与实时流处理的割裂,为什么需要流批一体?
做日志处理这么多年,我见过太多团队在「实时」和「离线」之间反复横跳。说实话,这俩东西本来就不该分开。
你想想看,一个典型的日志场景——比如服务器访问日志、用户行为埋点——它天生就是流式产生的。但我们的技术栈呢?往往是两套:一套 Storm / Flink 做实时,一套 Hive / Spark 跑离线。两套代码,两套运维,两套数据口径。
嗯,这里有个很现实的问题:同一个日志,实时算出来的结果和离线算出来的结果,经常对不上。业务方来问「到底该信哪个」,你只能硬着头皮说「以离线为准」——其实心里清楚,离线也只是重跑了一遍而已。
1.1 传统离线批处理的局限
离线批处理,说白了就是「攒够了再算」。每天凌晨跑一次 Hive 任务,把昨天的日志全量扫描一遍,出报表、出指标。这套模式在数据量不大的时候没问题,但放到今天的日志场景下,问题就暴露了。
- 时效性差:日志产生后至少要等几个小时甚至一天才能看到结果。对于监控告警、实时大屏这类场景,完全不可接受。
- 资源浪费:每天全量扫描,大量重复计算。我见过一个团队,每天凌晨跑 3 小时的 Hive 任务,其实 90% 的数据跟前一天没变化。
- 数据倾斜难处理:日志中的热点 key(比如某个爆款商品的访问日志)会导致单个 reducer 撑爆,任务失败重跑,恶性循环。
- 修正成本高:一旦发现数据有问题,需要重跑整个分区。重跑期间,下游报表全部不可用。
1.2 实时流处理的困境
实时流处理解决了时效性问题,但它自己也有硬伤。
- 状态管理复杂:日志场景中很多指标需要去重、计数、求 PV/UV。Flink 的状态后端如果配置不当,很容易 OOM。我曾经踩过一个坑——状态 TTL 设得太长,Checkpoint 越来越大,最后直接撑爆了 RocksDB。
- 精确一次语义的代价:为了做到 exactly-once,需要引入分布式快照、两阶段提交。吞吐量下降不说,运维复杂度直线上升。
- 历史数据回溯困难:实时管道默认只处理「当前」数据。如果你想看过去 7 天的趋势,或者修正某个历史窗口的指标,实时流基本无能为力——除非你把数据全部重放一遍。
- 数据口径不一致:实时任务和离线任务用的是两套代码,两套窗口逻辑。同样的「日活用户」,实时算出来 100 万,离线算出来 95 万,差了 5 万。业务方问起来,你只能解释「实时有延迟,离线有回溯」——其实自己心里也没底。
1.3 割裂架构带来的具体问题
两套系统并行,不只是技术上的重复建设,更是数据治理的灾难。我整理了一个对比表,你可以直观感受一下:
| 维度 | 离线批处理 | 实时流处理 | 割裂的后果 |
|---|---|---|---|
| 时效性 | T+1 或小时级 | 秒级/分钟级 | 口径无法对齐,业务决策混乱 |
| 计算引擎 | Hive / Spark | Flink / Storm | 两套代码,两套运维 |
| 存储 | HDFS / Hive 表 | Kafka / 状态后端 | 数据冗余,存储成本翻倍 |
| 容错 | 重跑分区 | Checkpoint / Savepoint | 故障恢复策略不同,难以统一管理 |
| 数据修正 | 全量重跑 | 数据回撤 + 重放 | 修正流程复杂,容易引入二次错误 |
| 开发效率 | SQL 为主 | Java/Scala API | 人员技能要求高,沟通成本大 |
你看,每一行都是实实在在的痛点。更可怕的是,这些痛点会相互叠加——实时出问题,离线补;离线出问题,实时又对不上。最后整个数据团队都在救火。
1.4 为什么需要流批一体?
流批一体的核心思想,说白了就是用一套引擎、一套 API、一套存储,同时处理实时数据和离线数据。它不是什么新概念,但直到 Flink 把批看作「有界流」之后,这个理念才真正有了落地的可能。
我个人习惯把流批一体理解为「一个管道,两种模式」:
- 实时模式:数据源源不断流入,秒级产出结果,用于监控、告警、大屏。
- 批处理模式:对同一份数据进行全量回溯,用于报表、分析、模型训练。
两种模式共享同一套计算逻辑,同一份数据源。实时算出来的结果,和离线算出来的结果,天然一致。不再需要「对账」,不再需要「修复」。
- 一套代码,两种语义。开发效率翻倍,维护成本减半。
- 数据口径天然统一。实时和离线不再打架。
- 存储层统一。Kafka 和 HDFS 之间不再需要反复搬运数据。
- 容错和修正更简单。实时管道出问题,可以用批处理模式重跑历史数据;批处理出问题,可以用实时模式快速补数。
你可能会问:那是不是所有场景都适合流批一体?当然不是。但日志场景——数据量大、时效性要求高、口径一致性要求严格——恰恰是流批一体最能发挥价值的地方。
下面这张图,是我自己总结的日志场景流批一体架构的核心逻辑:
从这张图你可以看到,流批一体并不是把实时和离线「拼在一起」,而是从数据接入、计算引擎、存储到服务层,全部统一。实时和离线只是同一套架构的两种运行模式。