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 区间批量拉取)。

Confluent Kafka 批流统一管道全景 接入层 · Kafka Connect MySQL CDC Debezium Source 应用日志 File/Syslog Source 对象存储 S3 Source 消息队列 MQ Source Sink 写出 JDBC / S3 / ES 中枢层 · Kafka 事件日志 + Schema Registry Topic: orders Partition 0 | 1 | 2 offset 0 → 1,000,000 → … 保留策略:7 天 / compact Topic: payments Partition 0 | 1 | 2 | 3 key = order_id 保证有序 副本因子 = 3 Schema Registry Avro / Protobuf / JSON 兼容性:BACKWARD 版本 v1 → v2 → v3 计算与消费层 · 流式 + 批式共享同一日志 流式作业 Kafka Streams ksqlDB 持续查询 Flink Streaming 批式作业 Spark Batch Flink Batch offset 区间回放 结果输出 实时看板 / 告警 T+1 数仓表 特征存储 编排与调度 Airflow / Confluent Cloud 任务编排 依赖触发 / 重跑 批 = 有界 offset 区间回放 | 流 = 无界持续消费 | 同一份日志、同一套 Schema

二、核心组件各自扮演什么角色

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 兼容性事件,能定位"批流结果不一致"的根因。
学习建议:每章动手前先确认三件事——当前 Topic 的 key 是什么、Schema 版本是否兼容、消费 offset 从 earliest 还是 latest 开始。这三项决定了批流两条链路能否对齐。