第二章:采集架构演进——从批处理到流处理

大家好,我是老张。今天咱们聊聊数据采集架构的演进史。

说实话,我刚入行那会儿,数据采集就是跑个定时脚本,每天凌晨把昨天的数据拉下来。那时候觉得挺香的,直到有一天老板说:「我要看实时用户行为。」嗯,噩梦开始了。

2.1 批处理架构:曾经的王者

批处理,说白了就是「攒一波,一起干」。每天凌晨2点,调度系统把前一天的数据全量拉取、清洗、入库。我最早做电商数据采集时,用的就是这种模式。

核心特征:

  • 数据按固定时间窗口(天/小时)批量处理
  • 延迟通常在分钟级到小时级
  • 适合离线报表、历史分析

举个例子,你想想看:

# 伪代码:批处理采集
def batch_collect():
    yesterday = get_yesterday_date()
    data = query_database(f"SELECT * FROM logs WHERE date = '{yesterday}'")
    save_to_warehouse(data)
    print("批处理完成")

这种架构简单、稳定,但有个致命问题——延迟。我在项目中遇到过,业务方要实时监控大促活动的流量,批处理根本扛不住。等数据出来,活动都结束了。

避坑指南:我曾经以为批处理能搞定一切,直到被实时需求打脸。记住:批处理适合「事后分析」,不适合「实时决策」。

2.2 流处理架构:实时才是王道

流处理,就是「来一条,处理一条」。数据像水流一样,源源不断地进入系统,实时处理、实时输出。

我个人习惯用 Apache Kafka 作为消息队列,配合 Flink 做流处理。为什么?因为 Kafka 能扛住百万级 TPS,Flink 的毫秒级延迟太香了。

// 伪代码:流处理采集
DataStream<Log> stream = env.addSource(kafkaConsumer);
stream
    .filter(log -> log.getLevel() != "DEBUG")
    .map(log -> transform(log))
    .addSink(elasticsearchSink);
env.execute("实时采集作业");

你可能会问:「流处理这么好,为啥不全面替代批处理?」

嗯,这里要注意。流处理也有短板:状态管理复杂、Exactly-Once 语义实现成本高、历史数据回溯困难。我见过不少团队,一上来就搞全流处理,结果状态后端炸了,数据对不齐,哭都来不及。

2.3 Lambda 架构:批流混合的妥协方案

Lambda 架构,说白了就是「两条腿走路」。一条批处理路径保证数据准确性,一条流处理路径保证实时性。最后在服务层合并结果。

Lambda 架构三要素:

  1. 批处理层(Batch Layer): 全量数据,保证最终一致性
  2. 流处理层(Speed Layer): 实时数据,提供低延迟
  3. 服务层(Serving Layer): 合并批流结果,对外提供服务

我记得在做一个金融风控项目时,就用了 Lambda 架构。实时流处理检测异常交易,批处理做历史回溯分析。效果不错,但维护成本高——两套代码、两套运维、两套逻辑。

避坑指南:我曾经在 Lambda 架构上踩过坑——批处理和流处理的逻辑不一致,导致同一笔数据在两个路径上算出的结果不同。排查了三天,最后发现是时间窗口的边界条件没对齐。所以,批流逻辑必须复用同一套代码

2.4 Kappa 架构:流处理一统天下

Kappa 架构,是 Lambda 架构的简化版。它认为:既然流处理能搞定一切,为什么还要保留批处理?

核心思想:所有数据都走流处理,批处理只是流处理的一个特例。需要回溯历史数据时,重新从 Kafka 消费即可。

# Kappa 架构核心:数据重放
def replay_data(topic, start_offset, end_offset):
    consumer = KafkaConsumer(topic, 
                            auto_offset_reset='earliest')
    consumer.seek(start_offset)
    for msg in consumer:
        if msg.offset > end_offset:
            break
        process(msg.value)

我个人比较推崇 Kappa 架构,尤其是数据量不大、业务逻辑不复杂的场景。但要注意:Kappa 架构对消息队列的存储能力要求很高。Kafka 默认只能保存 7 天的数据,你要回溯一个月的数据?得调大 retention 配置。

小技巧:如果你用 Kappa 架构,建议把 Kafka 的日志保留时间设为 30 天以上。磁盘不够?上对象存储(S3/HDFS)做冷热分层。

2.5 事件驱动架构:解耦的艺术

事件驱动架构,说白了就是「谁出事,谁通知」。每个服务只管自己的事,出了事件就发消息,其他服务按需订阅。

核心组件:

  • 事件生产者: 产生数据变更事件
  • 事件总线: 消息队列(Kafka/RabbitMQ)
  • 事件消费者: 订阅并处理事件

我做过一个微服务数据采集项目,每个服务产生自己的事件,通过 Kafka 广播。数据采集服务只订阅需要的事件,完全解耦。效果非常好,新增一个数据源只需要写个消费者,不用改其他服务。

事件驱动 vs 传统轮询:

对比项 事件驱动 传统轮询
延迟 毫秒级 秒级到分钟级
资源消耗 低(有事件才处理) 高(持续轮询)
耦合度
实现复杂度

2.6 架构演进全景图

下面这张图,是我自己总结的架构演进路线。从批处理到事件驱动,每一步都是被业务逼出来的。

数据采集架构演进路线 批处理 延迟高 简单稳定 Lambda 批+流混合 维护成本高 Kappa 纯流处理 依赖消息队列 事件驱动 完全解耦 实时响应 架构选型建议 • 数据量 < 100GB/天:批处理就够了 • 需要实时 + 历史回溯:Lambda 架构 • 纯实时场景,数据可重放:Kappa 架构 • 微服务 + 解耦需求:事件驱动架构 • 不要为了技术而技术,选最简单的方案

2.7 我的实战建议

讲了这么多,最后给点实在的:

  • 别一上来就搞流处理。 我见过太多团队,数据量一天才几万条,非要上 Flink。结果运维成本比开发成本还高。
  • Lambda 架构是过渡方案。 如果你已经在用 Lambda,逐步向 Kappa 迁移。批流两套逻辑,迟早出问题。
  • 事件驱动是未来。 尤其是微服务架构下,事件驱动能让你的数据采集系统像乐高一样灵活。

最后说一句:架构没有银弹。批处理、流处理、Lambda、Kappa、事件驱动,每种架构都有它的适用场景。选架构,先看业务需求,再看团队能力,最后才是技术选型。顺序别搞反了。


公众号:蓝海资料掘金营,微信deep3321