# 流处理:像乐高积木一样的架构
现代数据处理系统需要灵活性和可扩展性。本文将详细解析如何使用模块化架构原则,将 Kafka、Flink、S3 等组件组合成一个统一的流处理平台。我们将深入探讨从数据生成到实时分析的集成阶段。
系统基础:流处理平台
构建流处理系统,我们采用一栈经过实战检验的技术。核心组件是 Apache Kafka——一个分布式流平台,确保可靠的消息传递。我们还使用:
- Kafka Connect 用于与外部系统集成
- Schema Registry 用于数据模式管理
- Kafka UI 作为可视化管理界面
关键理念是将组件视为乐高积木。每个组件负责特定功能,并通过明确定义的接口与其他组件连接。要启动最小化配置,只需 Docker Compose 和 Git LFS 即可。系统通过多阶段构建组装,确保环境可重现。
docker-compose.yml 中的基本配置示例:
services:
kafka:
image: confluentinc/cp-kafka:8.1.0
environment:
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:9092
schema-registry:
image: confluentinc/cp-schema-registry:8.1.0
environment:
SCHEMA_REGISTRY_KAFKASTORE_BOOTSTRAP_SERVERS: kafka:9092
重要的是要理解传统数据库与流处理系统之间的区别。在关系型数据库中,焦点在于状态(表、记录),而在流处理中,焦点在于事件。Kafka 中的每条消息代表一个不可变事件,追加到日志末尾。这种方法实现了保证交付和状态恢复的系统。
数据集成阶段
我们将系统构建过程分为四个逻辑阶段:
- Ingest —— 从外部源接收数据
- Storage —— 持久化存储
- Transform —— 转换和丰富数据
- Serve —— 交付结果
Ingest:数据生成与摄取
在 Ingest 阶段,我们通过 Kafka Connect 配置数据源。作为演示,我们实现一个温度传感器读数的生成器。该 Java 连接器生成带有地理坐标和温度的合成数据,考虑了时间和相对于赤道的位置因素。
连接器配置:
{
"connector.class": "dev.miron.connect.temp.TempSourceConnector",
"tasks.max": "1",
"topic": "earth-temp",
"sensors": "5",
"messages.per.sensor.per.second": "1"
}
注意使用 Avro 进行序列化。消息以二进制格式存储,减少流量并加速处理。Schema Registry 处理模式版本管理和兼容性检查(BACKWARD 模式)。当数据结构发生变化时,系统会自动拒绝无效更新。
Storage:长期存储
对于持久化存储,我们结合 S3 和 Apache Iceberg 使用。S3 作为对象存储,而 Iceberg 添加元数据层,支持 ACID 事务和时间旅行。这种方法高效处理大规模数据集,避免传统文件系统的常见问题。
Sink 连接器配置:
{
"connector.class": "io.confluent.connect.s3.S3SinkConnector",
"topics": "earth-temp",
"s3.bucket.name": "data-lake",
"storage.class": "io.confluent.connect.s3.storage.S3Storage",
"format.class": "io.confluent.connect.s3.format.avro.AvroFormat"
}
对于数据查询,我们使用 Trino——一个分布式 SQL 引擎,能够联合多个数据源。这允许在不移动数据的情况下执行复杂分析查询。
数据转换
我们使用 Apache Flink 实现 Transform 阶段——一个支持窗口和有状态操作的流处理引擎。示例任务:将温度从华氏转换为摄氏,并过滤异常值。
DataStream<TempEvent> processed = source
.map(event -> {
event.setCelsius((event.getFahrenheit() - 32) * 5/9);
return event;
})
.filter(event -> event.getCelsius() > -50 && event.getCelsius() < 60);
Flink 通过原生连接器与 Kafka 集成。正确配置检查点对于 exactly-once 处理保证至关重要。关键参数:
execution.checkpointing.interval: 60000state.backend: rocksdbstate.checkpoints.dir: file:///checkpoints
对于监控,我们使用 Flink 内置的 Web 界面跟踪处理延迟(lag)和操作符状态。
服务层
在最终阶段,数据可供消费者使用。我们实现两种选项:
- PostgreSQL 通过 JDBC 连接器用于操作查询
- Redis 用于缓存热点数据
PostgreSQL Sink 配置:
{
"connector.class": "io.confluent.connect.jdbc.JdbcSinkConnector",
"connection.url": "jdbc:postgresql://postgres:5432/analytics",
"topics": "processed-temp",
"auto.create": "true",
"insert.mode": "upsert",
"pk.fields": "sensorId,timestamp"
}
对于 Redis,我们使用自定义连接器,将每个传感器的最新读数存储在哈希表中。这为当前数据查询提供毫秒级延迟。
关键要点
- 数据模式 必须通过 Schema Registry 管理,并确保 BACKWARD 兼容性
- 有状态处理 在 Flink 中需要配置检查点和选择状态后端
- 系统分解 为 Ingest/Storage/Transform/Serve 阶段简化调试
- 二进制序列化(Avro/Protobuf)对流系统性能至关重要
- 通过 Docker Compose 测试配置 实现快速迭代
— Editorial Team
暂无评论。