基于 Flink 与 Kafka 的流式销售数据分析 Demo
基于 Flink 与 Kafka 的流式销售数据分析 Demo
https://github.com/fanqingsong/flink-kafka-demo

导读:在流式计算的学习与落地过程中,如何快速搭建一个端到端的实时数据处理链路是许多开发者面临的挑战。本文基于开源项目 flink-kafka-demo,深入解析如何利用 Apache Flink 和 Apache Kafka 构建一个完整的流式销售数据分析系统。文章涵盖了从架构设计、核心组件解析到数据流转的完整链路,并提供了详细的部署与运行指南,旨在为大数据初学者和流计算开发者提供一个清晰、可复现的实战参考。
项目简介
flink-kafka-demo 是一个专注于流式数据分析的演示项目,由开发者 fanqingsong 基于 garystafford 的开源项目 fork 并持续优化。该项目利用 Streaming Synthetic Sales Data Generator(流式合成销售数据生成器)模拟真实的电商销售场景,完整展示了从数据产生、消息传输、实时计算到前端展示的闭环流程。
项目采用 Apache License 2.0 许可证,技术栈主要由 Java (79.7%)、HTML (16.1%)、Dockerfile (2.7%) 和 Shell (1.5%) 构成,非常适合希望深入理解 Flink 与 Kafka 协同工作的技术人员进行源码阅读与二次开发。
技术选型与架构
核心技术栈
为了保证演示环境的现代化与高性能,项目对底层组件进行了版本升级与重构: - Kafka 3.7:采用 KRaft 模式,摆脱了对 ZooKeeper 的依赖,简化了部署架构。 - Flink 1.19.1:提供强大的流式计算引擎,支持复杂的窗口计算与状态管理。 - Spring Boot:作为 Web 应用框架,替代了原有的 FastAPI,更好地与 Java 生态融合。
整体架构设计
项目的架构遵循经典的流处理范式:Kafka 负责消息存储与解耦,Flink 负责实时计算,Web 应用作为唯一的长运行客户端负责数据注入与结果展示。这种设计使得各个组件职责单一,便于独立扩展与调试。
核心功能解析
1. Web 应用 (端口 8088)
Web 应用是整个 Demo 的交互枢纽,基于 Spring Boot 构建。它承担了以下核心职责: - Topic 管理:在启动时自动创建四个所需的 Kafka Topic。 - 数据注入:当 demo.products 为空时,自动写入产品目录;接收用户请求,向 demo.purchases 写入购买记录。 - 结果展示:实时从三个 Topic 拉取数据,并在页面上直观展示 RunningTotals 和 JoinStreams 两个 Flink Job 的处理结果。
2. RunningTotals Job
这是一个典型的流式聚合任务。它读取 demo.purchases Topic,在内存中维护每个产品的累计统计(交易次数、数量、销售额),并将结果写入 demo.running.totals Topic。该 Job 采用“submit and exit”模式,即客户端提交任务后即退出,但 Job 会在 TaskManager 上持续运行。
3. JoinStreams Job
这是一个流-流/流-表 Join 的实战案例。它同时读取 demo.products(静态产品目录)和 demo.purchases(动态购买记录),根据 product_id 将两者关联,附加产品名称、分类、成本等详细信息,最终将富化后的数据写入 demo.purchases.enriched Topic。
数据流转详解
整个系统的数据流转过程高度自动化,具体步骤如下:
1. 用户通过浏览器访问 Web 应用 (localhost:8088)。
2. Web 应用初始化 Kafka Topic,并将产品目录写入 demo.products。
3. 用户在页面触发一笔购买,Web 应用将交易数据写入 demo.purchases。
4. 两个 Flink Job 并行消费 demo.purchases:
◦ RunningTotals:累加该笔交易,更新产品统计并写入 demo.running.totals。
◦ JoinStreams:查询产品详情,合并数据后写入 demo.purchases.enriched。
5. Web 应用实时拉取上述三个 Topic 的最新数据,刷新前端页面。
Kafka Topics 设计
|
Topic 名称 |
数据特征 |
说明 |
|
demo.products |
静态数据 |
产品目录,Web 应用初始化时写入一次 |
|
demo.purchases |
流式数据 |
每笔购买记录,由用户触发写入 |
|
demo.running.totals |
聚合结果 |
RunningTotals Job 输出的产品销售统计 |
|
demo.purchases.enriched |
富化数据 |
JoinStreams Job 输出的附带产品详情的购买记录 |
消息结构示例
购买记录 (demo.purchases):
{
"transaction_time": "2022-09-13 12:58:36.915834",
"transaction_id": "2883033696701592101",
"product_id": "SC04",
"price": 5.99,
"quantity": 1,
"total_purchase": 5.99
}
富化后的购买记录 (demo.purchases.enriched):
{
"transaction_time": "2022-09-13 12:50:55.644564",
"product_id": "CS06",
"product_name": "Blimey Limey",
"product_category": "Classic Smoothies",
"product_cogs": 1.50,
"purchase_price": 4.99,
"total_purchase": 4.99
}
运行与部署
项目提供了完善的 Docker Compose 配置,支持一键启动:
docker compose up --build -d
启动后,可通过以下地址访问各组件: - Web 应用: http://localhost:8088 - Flink UI: http://localhost:8081 - Kafka Broker: localhost:9092
调试与验证
若需直接在命令行查看 Topic 中的实时数据,可使用以下命令:
docker compose exec kafka /opt/bitnami/kafka/bin/kafka-console-consumer.sh \
--topic demo.running.totals --from-beginning --bootstrap-server localhost:9092
如需重新构建 Flink Job 的 JAR 包,可执行:
mvn -B -pl flink-jobs -am package -DskipTests
项目亮点总结
1. 架构现代化:Kafka 采用 KRaft 模式,Web 端迁移至 Spring Boot,构建工具统一为 Maven,紧跟社区最新实践。
2. 链路完整性:从数据生成、传输、计算到展示,提供了一个无需外部依赖的完整闭环。
3. 代码可读性:去除了冗余的 one-shot producer,逻辑更加聚焦于核心的流计算场景。
4. 部署极简:Docker Compose 一键拉起,极大降低了本地环境搭建的门槛。
学习建议与延伸方向
对于希望深入掌握流计算技术的开发者,建议以该项目为起点,进行以下延伸探索:
1. 引入状态后端与 Checkpoint:当前 RunningTotals 依赖内存状态,可尝试配置 RocksDB 状态后端并开启 Checkpoint,观察 Flink 的容错机制与 Exactly-Once 语义。
2. 处理迟到数据与乱序:在 Web 应用中注入带有时间戳延迟的测试数据,研究 Flink 的 Watermark 机制与 Side Output(侧输出流)的应用。
3. 扩展计算维度:尝试增加基于时间窗口(如 1 分钟滚动窗口)的销售额统计,对比无界流聚合与有界窗口聚合的区别。
对接真实数据源:将 Web 应用替换为真实的业务系统或对接 MySQL CDC,体验从批流一体到真实生产环境的过渡

浙公网安备 33010602011771号