返回首页

流式数据处理:基于 Kafka 和 Flink 的架构

使用 Apache Kafka、Flink 和 S3 构建流式数据处理系统的文章。详细介绍了集成阶段、配置示例和生产环境的最佳实践。

像 LEGO 积木一样构建流式系统:实用指南
Advertisement 728x90

# 流处理:像乐高积木一样的架构

现代数据处理系统需要灵活性和可扩展性。本文将详细解析如何使用模块化架构原则,将 Kafka、Flink、S3 等组件组合成一个统一的流处理平台。我们将深入探讨从数据生成到实时分析的集成阶段。

系统基础:流处理平台

构建流处理系统,我们采用一栈经过实战检验的技术。核心组件是 Apache Kafka——一个分布式流平台,确保可靠的消息传递。我们还使用:

  • Kafka Connect 用于与外部系统集成
  • Schema Registry 用于数据模式管理
  • Kafka UI 作为可视化管理界面

关键理念是将组件视为乐高积木。每个组件负责特定功能,并通过明确定义的接口与其他组件连接。要启动最小化配置,只需 Docker Compose 和 Git LFS 即可。系统通过多阶段构建组装,确保环境可重现。

Google AdInline article slot

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 中的每条消息代表一个不可变事件,追加到日志末尾。这种方法实现了保证交付和状态恢复的系统。

数据集成阶段

我们将系统构建过程分为四个逻辑阶段:

Google AdInline article slot
  • 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 模式)。当数据结构发生变化时,系统会自动拒绝无效更新。

Google AdInline article slot

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: 60000
  • state.backend: rocksdb
  • state.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

Advertisement 728x90

继续阅读