1. Confluent Kafka批流管道全景
在传统数据平台里,批处理和流处理长期是两套人马、两套代码、两套运维。离线侧用 Hive/Spark 跑 T+1 报表,实时侧用 Flink/Storm 做秒级告警,同一份业务逻辑往往要写两遍,口径还经常对不上。Confluent Kafka 的核心价值,就是把这两条链路收敛到同一套以 Kafka 为中枢的架构上:批是"有边界的流",流是"无边界的批",二者共享同一份事件日志、同一套 Schema、同一套连接器与同一套计算引擎。
一、统一架构:Kafka 作为"单一事实来源"
理解批流统一,关键是理解 Kafka 的日志抽象。Topic 是一个只追加、可重放、按分区有序的事件日志。批处理之所以能"批",是因为它人为设定了起止边界——比如读取 orders 主题中 offset 0 到 1000000 的数据;流处理之所以能"流",是因为它不设终点,持续消费新到达的事件。两者读的是同一个日志,只是消费的边界策略不同。
由此形成三层结构:接入层由 Kafka Connect 负责,把数据库 CDC、日志、MQ、文件系统等源端数据以 Source Connector 写入 Kafka,再以 Sink Connector 写出到数据仓库、对象存储或下游系统;存储与传输层是 Kafka Broker 集群,配合 Schema Registry 管理 Avro/Protobuf/JSON Schema 的兼容性演进,配合 ksqlDB 或 Kafka Streams 提供流式计算能力;计算与消费层则同时容纳流式作业(Kafka Streams、Flink、ksqlDB 持续查询)和批式作业(Spark、Flink Batch、Kafka 消费者按 offset 区间批量拉取)。
二、核心组件各自扮演什么角色
Broker 与 Topic/Partition 是地基。分区数决定并行度上限,副本因子决定容错能力。生产环境通常把副本因子设为 3,min.insync.replicas=2,在可用性与一致性之间取平衡。
Kafka Connect 解决"数据怎么进来、怎么出去"。它把连接器配置、offset 管理、错误处理和格式转换标准化,避免为每个源端手写消费者。一个典型的 Debezium MySQL Source 配置片段如下:
{
"name": "mysql-orders-cdc",
"config": {
"connector.class": "io.debezium.connector.mysql.MySqlConnector",
"database.hostname": "mysql-prod",
"database.port": "3306",
"database.user": "cdc_user",
"database.password": "******",
"database.server.name": "mysql-prod",
"table.include.list": "shop.orders,shop.payments",
"topic.prefix": "cdc",
"key.converter": "io.confluent.connect.avro.AvroConverter",
"value.converter": "io.confluent.connect.avro.AvroConverter",
"value.converter.schema.registry.url": "http://schema-registry:8081"
}
}
启动后,shop.orders 表的每一行变更会以 Avro 编码写入 cdc.shop.orders 主题,key 为订单主键,value 包含 before、after、op 等字段。下游无论是流式作业还是批式作业,读到的都是同一份带 Schema 的事件。
Schema Registry 是批流口径一致的保险栓。它强制所有生产者注册 Schema,并在演进时校验兼容性。例如订单表新增 coupon_code 字段并设置默认值 null,属于 BACKWARD 兼容,老消费者仍能解析;若直接删除字段且无默认值,注册会被拒绝,从而避免下游批作业在凌晨跑数时突然解析失败。
Kafka Streams / ksqlDB 承担流式计算。Kafka Streams 是嵌入应用的库,适合需要复杂状态、窗口、join 的场景;ksqlDB 用 SQL 表达持续查询,适合快速搭建实时聚合。例如统计每分钟支付金额:
CREATE STREAM payments_stream
WITH (KAFKA_TOPIC='cdc.shop.payments', VALUE_FORMAT='AVRO');
CREATE TABLE payments_per_min AS
SELECT
WINDOWSTART AS window_start,
SUM(after.amount) AS total_amount,
COUNT(*) AS txn_count
FROM payments_stream
WINDOW TUMBLING (SIZE 1 MINUTE)
GROUP BY 1
EMIT CHANGES;
这条查询持续输出到 PAYMENTS_PER_MIN 主题,实时看板直接消费即可。而同一份 cdc.shop.payments 数据,批作业可以在每天凌晨用 Spark 读取 offset 区间,重算 T+1 对账表,两者结果可交叉验证。
三、典型应用场景
第一类是实时数仓与湖仓一体:CDC 入 Kafka,流式写入 Iceberg/Hudi 的近实时层,批式作业做历史回刷与 compaction。第二类是实时风控与告警:支付事件流经 Kafka Streams 做规则匹配,命中后写入告警主题。第三类是批流同源对账:实时链路产出分钟级指标,批链路产出日级汇总,二者基于同一事件日志,差异只来自窗口边界而非数据源。第四类是事件驱动微服务:订单、库存、物流服务通过 Kafka 解耦,Connect 负责与遗留数据库同步。
四、课程实战项目目标
本课程将围绕一个"电商订单实时与离线统一管道"项目展开,贯穿 30 个章节。项目目标可拆解为:
- 数据接入:用 Debezium MySQL Source 采集
shop.orders、shop.payments、shop.inventory三张表,写入 Kafka,Schema 用 Avro 管理。 - 流式处理:用 Kafka Streams 实现订单支付状态 join,用 ksqlDB 实现每分钟 GMV 聚合与库存预警。
- 批式处理:用 Spark 按 offset 区间回放同一主题,生成 T+1 订单明细宽表与对账报表。
- 数据写出:Sink Connector 把实时聚合写入 Elasticsearch 供看板查询,把批结果写入 S3 供数仓使用。
- 任务编排:用 Airflow 编排批作业依赖,用 Confluent Cloud 的任务能力管理连接器生命周期,实现失败重试与告警。
- 可观测与排障:监控 consumer lag、Connect 任务状态、Schema 兼容性事件,能定位"批流结果不一致"的根因。