Flink随笔 20241129 流数据处理:以生产线烤鸡为例理解 Flink

流数据(streaming data)就像是一条永不停歇的生产线,源源不断地向前推进,带来新的数据。而 Apache Flink 就是这条生产线的核心,它负责对数据进行处理、分类、聚合和存储。为了更好地理解 Flink 的流处理,我们可以通过一个简单的类比来解释:流数据就像是流水线上的烤鸡,而 Flink 就是这条流水线上的工作部,负责对这些烤鸡进行加工、分拣、统计和存储。

下面,我们将通过这个类比一步步讲解 Flink 的核心概念,并展示如何在 Flink 中实现这些操作。

类比:生产线的烤鸡

想象一下,你在一个生产线的末端,看到源源不断的烤鸡从流水线上流过。你需要对这些鸡进行以下操作:

  1. 去掉烤糊的鸡肉(过滤):生产线上有些鸡被烤得过焦,不能食用,需要将其剔除。
  2. 分拣出火鸡还是普通鸡肉(映射):在生产线的下一步,你需要把鸡肉分成不同的类别,比如火鸡和普通鸡肉。
  3. 统计有多少只火鸡,多少只普通鸡肉(聚合):你需要统计每种鸡肉的数量,以便后续处理。
  4. 将鸡肉存储(存储):最后,所有的合格鸡肉需要被存储,或者被送到市场。

这些操作正是 Flink 中流数据处理的核心功能。下面我们将逐一介绍如何在 Flink 中实现这些步骤。

1. 去掉烤糊的鸡肉(过滤)

在生产线的第一步,你需要对烤鸡进行筛选,去掉那些已经烤糊或者质量不合格的鸡肉。在 Flink 中,这就是 过滤操作 (Filter)。Flink 提供了 filter() 函数,可以根据条件筛选出符合要求的数据。

例如,假设我们有一个数据流,其中包含不同类型的鸡肉,而我们只关心健康的鸡肉。你可以通过过滤操作去除那些不符合条件的数据。

java 复制代码
DataStream<String> chickenStream = env.fromElements("Turkey", "Burnt Chicken", "Chicken", "Turkey");

DataStream<String> validChickenStream = chickenStream.filter(chicken -> !chicken.equals("Burnt Chicken"));
validChickenStream.print();
2. 分拣出火鸡还是普通鸡肉(映射)

在生产线的第二步,你需要把鸡肉分成火鸡和普通鸡肉两类,这就是 映射操作 (Map)。在 Flink 中,map() 函数可以将输入数据转换成不同的输出数据。在本例中,我们可以将鸡肉类型映射成不同的标签,例如"火鸡"和"普通鸡肉"。

java 复制代码
DataStream<String> sortedChickenStream = chickenStream
    .map(new MapFunction<String, String>() {
        @Override
        public String map(String value) throws Exception {
            return value.equals("Turkey") ? "Turkey" : "Chicken";
        }
    });

sortedChickenStream.print();
3. 统计有多少只火鸡,多少只普通鸡肉(聚合)

接下来,你需要统计每种类型的鸡肉有多少只,这就是 聚合操作 (Aggregation)。在 Flink 中,keyBy()reduce() 函数常常一起使用,按指定的键(比如鸡肉类型)对数据进行分组,并对每个组进行聚合计算。

例如,你可以按鸡肉类型分组,并统计每种鸡肉的数量:

java 复制代码
DataStream<Tuple2<String, Integer>> mappedStream = chickenStream
    .map(chicken -> new Tuple2<>(chicken, 1));  // 每个鸡肉事件映射为类型和数量的元组

DataStream<Tuple2<String, Integer>> aggregatedStream = mappedStream
    .keyBy(0)  // 按鸡肉类型分组
    .reduce(new ReduceFunction<Tuple2<String, Integer>>() {
        @Override
        public Tuple2<String, Integer> reduce(Tuple2<String, Integer> value1, Tuple2<String, Integer> value2) throws Exception {
            return new Tuple2<>(value1.f0, value1.f1 + value2.f1);  // 累加数量
        }
    });

aggregatedStream.print();
4. 将鸡肉存储(存储)

在生产线的最后一步,合格的鸡肉需要被存储或发送到市场。Flink 提供了多种 Sink 操作,可以将处理结果输出到外部系统,如 Kafka、MySQL、Elasticsearch 或 HDFS。你可以根据需要将聚合结果写入数据库或消息队列,便于后续的处理和存储。

例如,将处理后的数据输出到 Kafka:

java 复制代码
aggregatedStream.addSink(new FlinkKafkaProducer<>(
    "kafka-broker",  // Kafka 服务器地址
    "chicken-topic",  // Kafka 主题
    new SimpleStringSchema()  // 数据序列化方式
));

通过上述步骤,我们可以编写一个完整的 Flink 程序,来实现流数据的处理,类似于生产线上的烤鸡加工过程。以下是一个简单的例子,展示如何使用 Flink 进行数据流的过滤、映射、聚合和存储:

java 复制代码
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.common.functions.ReduceFunction;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.api.java.tuple.Tuple2;

public class ChickenProcessing {
    public static void main(String[] args) throws Exception {
        // 1. 设置流处理环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 2. 输入数据流:每个事件包含一个鸡肉的类型
        DataStream<String> chickenStream = env.fromElements("Turkey", "Chicken", "Turkey", "Chicken", "Turkey");

        // 3. 映射:将每个事件映射为一个元组(鸡肉类型, 数量)
        DataStream<Tuple2<String, Integer>> mappedStream = chickenStream
            .map(new MapFunction<String, Tuple2<String, Integer>>() {
                @Override
                public Tuple2<String, Integer> map(String value) throws Exception {
                    return new Tuple2<>(value, 1);  // 每个事件都标记为1个鸡肉
                }
            });

        // 4. 聚合:按类型统计每种鸡肉的数量
        DataStream<Tuple2<String, Integer>> aggregatedStream = mappedStream
            .keyBy(0)  // 按鸡肉类型分组
            .reduce(new ReduceFunction<Tuple2<String, Integer>>() {
                @Override
                public Tuple2<String, Integer> reduce(Tuple2<String, Integer> value1, Tuple2<String, Integer> value2) throws Exception {
                    return new Tuple2<>(value1.f0, value1.f1 + value2.f1);  // 累加数量
                }
            });

        // 5. 输出结果到控制台
        aggregatedStream.print();

        // 6. 启动流处理作业
        env.execute("Chicken Processing");
    }
}

输出示例

bash 复制代码
(Turkey, 3)
(Chicken, 2)
结论

通过上面的例子,我们可以看到 Flink 在流数据处理中的应用。它不仅可以对数据进行过滤、分类和聚合,还能够将处理结果存储或发送到其他系统。流数据处理就像生产线上的烤鸡加工一样,Flink 作为流水线的核心,不仅对数据进行有效处理,还确保了高效、实时地传递和存储处理结果。

相关推荐
大数据CLUB12 小时前
基于spark的澳洲光伏发电站选址预测
大数据·hadoop·分布式·数据分析·spark·数据开发
ratbag67201312 小时前
当环保遇上大数据:生态环境大数据技术专业的课程侧重哪些领域?
大数据
计算机编程小央姐14 小时前
跟上大数据时代步伐:食物营养数据可视化分析系统技术前沿解析
大数据·hadoop·信息可视化·spark·django·课程设计·食物
智数研析社15 小时前
9120 部 TMDb 高分电影数据集 | 7 列全维度指标 (评分 / 热度 / 剧情)+API 权威源 | 电影趋势分析 / 推荐系统 / NLP 建模用
大数据·人工智能·python·深度学习·数据分析·数据集·数据清洗
潘达斯奈基~15 小时前
《大数据之路1》笔记2:数据模型
大数据·笔记
寻星探路15 小时前
数据库造神计划第六天---增删改查(CRUD)(2)
java·大数据·数据库
翰林小院17 小时前
【大数据专栏】流式处理框架-Apache Fink
大数据·flink
孟意昶18 小时前
Spark专题-第一部分:Spark 核心概述(2)-Spark 应用核心组件剖析
大数据·spark·big data
IT学长编程19 小时前
计算机毕业设计 基于Hadoop的健康饮食推荐系统的设计与实现 Java 大数据毕业设计 Hadoop毕业设计选题【附源码+文档报告+安装调试】
java·大数据·hadoop·毕业设计·课程设计·推荐算法·毕业论文
AAA修煤气灶刘哥19 小时前
Kafka 入门不踩坑!从概念到搭环境,后端 er 看完就能用
大数据·后端·kafka