Flink DataStream API

Flink DataStream算子汇总 依据1.12官网进行归纳汇总,方便学习 Transformation数据流转换 Description Map 1->1 FlatMap 1->n Filter 为每个元素评估一个布尔函数,并保留该函数返回true的布尔函数。过滤出零值的过滤器 KeyBy 从逻辑上将流划分为不相交的分区。具... 阅读详情

Flink 根据抽象程度分层,提供了三种不同的 API。每一种 API 在简洁性和表达力上有着不同的侧重,并且针对不同的应用场景。

image.png
DataStream API 是 Flink 中用于编写流处理作业的 API,为许多通用的流处理操作提供了处理原语。它支持 Java 和 Scala 语言,预先定义了例如 map()、reduce()、aggregate() 等函数。
​
在 DataStream API 中,Flink 应用程序同样包含以下步骤:

  1. 获取 execution environment
  2. 定义数据源
  3. 执行转换操作
  4. 输出到指定地点
  5. 触发执行

本文将主要介绍其中的三大部分,分别是定义数据源的 Source、执行转换操作的 Transformation、输出计算结果的 Sink。

Source

Source 层负责数据流的读取。Flink 官方已提供多种数据源 Connector,如 File、Socket、Kafka、RabbitMQ 等。同时,Flink 也支持用户自定义 Source。

File-based

File-based Source 支持从文件中读取数据:

DataStreamSource<String> source = env.readTextFile("data/xxx.log");

Socket-based

Socket-based Source 支持从 Socket 连接中读取数据:

DataStreamSource<String> source = env.socketTextStream("xxx.xxx.xxx.xxx", 9999);

Collection-based

Collection-based Source 支持从集合中读取数据:

DataStreamSource<String> source = env.fromCollection(collection);

Kafka

对于 Kafka 数据源,官方提供了两种实现,分别为 Kafka Source 和 Kafka Consumer。

Kafka Source 示例:

KafkaSource<String> kafkaSource = KafkaSource.<String>builder()
    .setBootstrapServers(KAFKA_BROKER_SERVERS)
    .setTopics("test")
    .setGroupId("panda")
    .setStartingOffsets(OffsetsInitializer.earliest())
    .setValueOnlyDeserializer(new SimpleStringSchema())
    .build();

DataStreamSource<String> source =
    env.fromSource(kafkaSource, WatermarkStrategy.noWatermarks(), "Kafka Source");

Kafka Consumer 示例:

Properties consumerProperties = new Properties();
consumerProperties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_BROKER_SERVERS);
consumerProperties.put(ConsumerConfig.GROUP_ID_CONFIG, "panda");
DataStreamSource<String> source =
    env.addSource(new FlinkKafkaConsumer<>("test", new SimpleStringSchema(), consumerProperties));

Transformation

Transformation,又称算子,它可以将一个或多个的 DataStream 转换为新的 DataStream。通常,一个 Flink 应用作业会包含多个算子。

本节,我们将根据官方文档,介绍一些基础的算子。

Map

DataStream -> DataStream
​
Map 可以通过 1 个元素产生 1 个新元素。
​
本例中,Map 会将输入流的元素加倍:

DataStream<Integer> dataStream = //...
dataStream.map(new MapFunction<Integer, Integer>() {
    @Override
    public Integer map(Integer value) throws Exception {
        return 2 * value;
    }
});

FlatMap

DataStream -> DataStream

FlatMap 可以通过 1 个元素产生 **0、1 或更多 **的新元素。

本例中,FlatMap 会将输入的句子进行拆分,获得一个单词集合:

dataStream.flatMap(new FlatMapFunction<String, String>() {
    @Override
    public void flatMap(String value, Collector<String> out) throws Exception {
        for(String word: value.split(" ")){
            out.collect(word);
        }
    }
});

Filter

DataStream -> DataStream

Filter 可以根据用户设置的条件筛选出符合条件的元素。

本例中,Filter 会保留输入流中值不为 0 的元素:

dataStream.filter(new FilterFunction<Integer>() {
    @Override
    public boolean filter(Integer value) throws Exception {
        return value != 0;
    }
});

KeyBy

DataStream -> KeyedStream

KeyBy 会将 key 值相同的记录分配到相同的分区中,其作用类似 SQL 中的 group by。

在内部,KeyBy 是通过哈希分区实现的。

dataStream.keyBy(value -> value.getSomeKey());
dataStream.keyBy(value -> value.f0);

🔔 满足以下条件的类型 不能成为 key:

  1. POJO 类型,但不覆写 hashCode() 方法且依赖于 Object.hashCode() 实现
  2. 任何类型的数组

Reduce

KeyedStream -> DataStream

Reduce 会将数据流中的元素与上一个 Reduce 后的元素进行合并且产生一个新值。这个合并发生在每次数据流入时,即每流入一个元素,都会有一次合并操作。

keyedStream.reduce(new ReduceFunction<Integer>() {
    @Override
    public Integer reduce(Integer value1, Integer value2) throws Exception {
        return value1 + value2;
    }
});

🔔 Reduce 不能用于无界流,因为对于无界流来说,合并是没有意义的。通常情况下,Reduce 作用于分组或窗口处理后的有界数据流。

Union

DataStream* -> DataStream

Union 可以将 两个或以上 的数据流合并成一个。

dataStream.union(otherStream1, otherStream2, ...);

Connect

DataStream, DataStream -> ConnectedStream

Connect 可以连接 两个 数据流,并允许在两个流之间共享状态。

DataStream<Integer> someStream = //...
DataStream<String> otherStream = //...

ConnectedStreams<Integer, String> connectedStreams = someStream.connect(otherStream);

🔔 Union 和 Connect 都有连接、合并的作用,但实际上两者是有区别的:

  • Union 是多流合并,Connect 是双流合并
  • Union 要求各个流的数据类型要一致,Connect 允许两个流的数据类型不同
  • Connect 对被合并的流可以有不同的处理逻辑(参考 CoMap/CoFlatMap),更加灵活

CoMap

ConnectedStream -> DataStream

CoMap 的作用同 Map,但它是作用在 ConnectedStream 上的。

connectedStreams.map(new CoMapFunction<Integer, String, Boolean>() {
    @Override
    public Boolean map1(Integer value) {
        return true;
    }

    @Override
    public Boolean map2(String value) {
        return false;
    }
});

CoFlatMap

ConnectedStream -> DataStream

CoFlatMap 的作用同 FlatMap,但它是作用在 ConnectedStream 上的。

connectedStreams.flatMap(new CoFlatMapFunction<Integer, String, String>() {
   @Override
   public void flatMap1(Integer value, Collector<String> out) {
       out.collect(value.toString());
   }

   @Override
   public void flatMap2(String value, Collector<String> out) {
       for (String word: value.split(" ")) {
         out.collect(word);
       }
   }
});

Partitioner

Flink 对数据流提供了分区控制。其本质上,是将上游 Subtask 处理后的数据通过指定的分区策略输出到下游的 Subtask。

Custom

DataStream -> DataStream

Flink 支持用户编写自定义的 Partitioner 进行元素的分区选择。Custom Partitoner 只需实现 Partitioner 接口。

dataStream.partitionCustom(partitioner, "someKey");
dataStream.partitionCustom(partitioner, 0);

Random

DataStream -> DataStream

Random Partitioner 会根据均匀分布将数据流中的元素随机发往下游任意分区。

dataStream.shuffle();

Rebalance

DataStream -> DataStream

Rebalance Partioner 为 默认分区器,会通过轮询的方式将元素发往下游分区。

dataStream.rebalance();

Rescale

DataStream -> DataStream

Rescale Partioner 也是通过轮询的方式将元素发往下游分区,但其在分区分配上与 Rebalance 有着非常大的差异。

🔔 Rebalance 不管上下游算子各自的并行度为多少,每个上游算子都会被分配到所有的下游算子。而在 Rescale 策略中,每个上游算子只会分配到下游算子中的某个子集。该分配机制是由 StreamingJobGraphGenerator 在将 StreamGraph 转换为 JobGraph 时实现的。

我们举个例子。假设,上游并行度是 2,下游是 6,那么在 Rescale 策略下,上游的一个算子以循环的方式将元素输出到下游的 3 个算子上,另一个算子以循环的方式将元素输出到下游剩下的 3 个算子上,如下图所示:
在这里插入图片描述
若上游并行度是 6,下游并行度是 2,则上游 3 个算子会将元素输出到下游的一个算子上,上游的另外 3 个算子会将元素输出到下游的另一个算子上。

dataStream.rescale();

💡 在上下游算子并行度成比例的情况下,Rescale 会表现得比 Rebalance 更好,因为它可以减少上下游算子间数据传输所耗费的网络开销。

Broadcast

DataStream -> DataStream

Broadcast Partitioning 的作用正如广播一样,会将数据流中的元素分发到下游每个分区中(类比 Flume 中的 Replicating Selector,如果下游分区数为 8,则流中的元素复制 8 份)。

dataStream.broadcast();

Sink

Sink 层负责计算结果的输出。相较于 Source,官方对 Sink 组件的支持更加丰富,包括但不限于以下:Kafka、ElasticSearch、RabbitMQ、HDFS、JDBC、Redis。同样地,Flink 也支持用户自定义 sink。

Print

Print Sink 由 PrintSinkFunction 实现,支持将数据输出到控制台,通常用于调试阶段。它本质上是调用了 PrintStream 对象的 println() 方法,即我们常用的 System.out.println()。

其使用方式如下:

dataStream.print();

在 Print Sink 中,对计算结果的输出格式做了一定的处理:

  • 若并行度为 1,不做任何处理
  • 若并行度大于 1 且未指定 sink 标识,则添加前缀 1>
  • 若并行度大于 1 且指定 sink 标识为 panda,则添加前缀 panda:1>

🔔 上述前缀中的数字,由当前 subtask 的下标加上数字 1 获得,即 subtaskIndex + 1。

PrintToErr

PrintToErr 也是由 PrintSinkFunction 实现,它与 Print 的区别在于输出的字体颜色不同。

Kafka

官方提供了 Kafka Producer,用于将计算结果写入到 Kafka 中:

// 定义 kafka sink
Properties produceProperties = new Properties();
produceProperties.setProperty(ConsumerConfig.BOOTSTRAP_SERVERS_CONFIG, KAFKA_BROKER_SERVERS);
FlinkKafkaProducer<String> kafkaProducer = new FlinkKafkaProducer<>(
    "test",
    new SimpleStringSchema(),
    produceProperties);

dataStream.addSink(kafkaProducer);

Redis

官方并未提供 Redis Sink,但 Apache Bahir 提供了实现:

public static class RedisExampleMapper implements RedisMapper<Tuple2<String, String>>{

    @Override
    public RedisCommandDescription getCommandDescription() {
        return new RedisCommandDescription(RedisCommand.HSET, "HASH_NAME");
    }

    @Override
    public String getKeyFromData(Tuple2<String, String> data) {
        return data.f0;
    }

    @Override
    public String getValueFromData(Tuple2<String, String> data) {
        return data.f1;
    }
}
FlinkJedisPoolConfig conf = new FlinkJedisPoolConfig.Builder().setHost("127.0.0.1").build();

DataStream<String> stream = ...;
stream.addSink(new RedisSink<Tuple2<String, String>>(conf, new RedisExampleMapper());

不过这种实现方式存在些许不足:

  • 必须按照其接口规范进行编码,缺少灵活性
  • RedisMapper 并未继承 RichSinkFunction,无法获取运行环境上下文等信息

所幸,我们可以自己实现 Redis Sink:

public class MyRedisSink extends RichSinkFunction<Tuple2<String, String>> {

    private static final Logger LOGGER = LoggerFactory.getLogger(MyRedisSink.class);

    private static final String HASH_KEY = "flink-test";

    private Jedis jedis;

    private String key;

    public MyRedisSink() {

    }

    public MyRedisSink(String key) {
        this.key = key;
    }

    @Override
    public void open(Configuration parameters) {
        this.jedis = new Jedis("192.168.117.128", 6379);
    }

    @Override
    public void close() {
        if (this.jedis != null) {
            this.jedis.close();
        }
    }

    @Override
    public void invoke(Tuple2<String, String> value, Context context) {

        LOGGER.info("redis sink invoked, key: {}, value: {}", value.f0, value.f1);

        if (StringUtils.isEmpty(key)) {
            key = HASH_KEY;
        }

        this.jedis.hset(key, value.f0, value.f1);

    }
}
Flink DataStream API使用及原理 flink DataStream API使用及原理 传统的大数据处理方式一般是批处理式的,也就是说,今天所收集的数据,我们明天再把今天收集到的数据算出来,以供大家使用,但是在很多情况下,数据的时效性对于业务的成败是非常关键的。 Spark 和 Flink 都是通用的开源大规模处理引擎,目标是在一个系统中支持所有的数据处理以带来效能的提升。两者都有相对比较成熟的生态系统。是下一代大数据... 阅读详情

相关推荐

总结:Flink之DataStream各API介绍

本文主要是详细介绍类中的各个方法,并给出它们的使用场景。

w2009211777的专栏 1244

Flink DataStream API(基础版)

概述   DataStream(数据流)本身是 Flink 中一个用来表示数据集合的类(Class),我们编写的 Flink 代码其实就是基于这种数据类型的处理,所以这套核心API 就以DataStream 命名。对于批处理和流处理,我们都可以用这同一套 API 来实现。   DataStream 在用法上有些类似于常规的 Java 集合,但又有所不同。我们在代码中往往并不关心集合中具体的数据,而只是用 API 定义出一连串的操作来处理它们;这就叫作数据流的“转换”(transformations)。  

mengxianglong123的博客 4616

Flink Hudi DataStream API代码示例

总结Flink通过DataStream API读写Hudi Demo示例,主要是自己备忘用。最开始学习Flink时都是使用Flink SQL,所以对于Flink SQL读写Hudi比较熟悉。但是对于写代码实现并不熟悉,而有些需求是基于Flink代码实现的,所以需要学习总结一下。仅为了实现用代码读写Hudi的需求,其实有两种方式,一种是在代码里通过Flink SQL API,也就是代码中执行Flink SQL,这种方式其实和通过SQL实现差不多,另一种方式是通过DataStream API实现。

主要分享大数据相关的知识,如Spark、Hudi 1866

Flink核心API之DataStream

Flink核心API学习笔记

qq_40905284的博客 894

PL端:HDMI 输出实验

开发板没有HDMI编码芯片,是将FPGA的3.3差分IO直接连接到HDMI连接器,FPGA 完成 24 位 RGB 编码输出TMDS 差分信号。1、学会使用第三点IP核,首先是添加,后面的使用和自带IP核操作一致。2、主要还是在梳理vivado使用流程。

qq_43441284的博客 4287

LaTeX参考文献格式apsrev4-1,增加文献标题

APS的LaTeX参考文献格式apsrev4-1是隐藏标题的,如果想要出现标题,需要更改apsrev4-1.bst文件内容 在apsrev4-1.bst文件靠后部分,定义不同类型文献格式的地方,将article类型的内容替换为, FUNCTION {article} { output.bibitem format.authors booktitle empty$ { "author" output.check }{ output } if$ author format.

loading1234567的博客 5031

Flink之DataStream API 概述

系列文章目录前言一、DataStream API 应用实例1、StreamExecutionEnvironment初始化:该部分主要创建和初始化StreamExecutionEnvironment,提供通过DataStream API构建Flink作业需要的执行环境,包括设定ExecutionConfig、CheckpointConfig等配置信息以及StateBackend和TimeCharacteristic等变量。

m0_43437171的博客 1402

【AutoSar CP】SoAd模块

比如对于特定的PDU,其PduId在程序编译时就确定了,但是在代码运行中,该PduId可能需要发送到不同的远端ip,这时就需要用SoAd来设置连接远端地址信息。SoAdSocketConnectionGroup(连接参数)SoAdSocketRoute(接收数据)SoAdRoutingGroup(开关)SoAdPduRoute(发送数据)

至道无难,唯嫌拣择。 1686

Flink04: Flink核心API之DataStream

Flink中提供了4种不同层次的API,每种API在简洁和易表达之间有自己的权衡,适用于不同的场景。目前上面3个会用得比较多。• 低级API(Stateful Stream Processing):提供了对时间和状态的细粒度控制,简洁性和易用性较差,主要应用在一些复杂事件处理逻辑上。

anglemanyi的博客 833

NXP S32K3 Safety软件生态全解析:RTD、SPD、SAF、SCST到底怎么选?

本文深入解析NXP S32K3系列MCU的安全软件生态,详细对比RTD、SPD、SAF和SCST四大组件的功能定位与选型策略。针对不同ASIL等级需求,提供从架构设计到工程实践的完整解决方案,帮助开发者高效实现功能安全认证,优化汽车电子系统的安全性与可靠性。

weixin_42524226的博客 323

Open3D——RANSAC 三维点云空间直线拟合【2025最新版】

使用RANSAC算法在点云数据中拟合三维空间直线的python代码实现。博客长期更新,本文最新更新时间为:2025年3月23日。

点云侠的博客 7354

【Flink系列】5. DataStream API

5. DataStream API DataStream API是Flink的核心层API。一个Flink程序,其实就是对DataStream的各种转换。具体来说,代码基本上都由以下几部分构成: 5.1 执行环境(Execution Environment) Flink程序可以在各种上下文环境中运行:我们可以在本地JVM中执行程序,也可以提交到远程集群上运行。 不同的环境,代码的提交运行的过程会有所不同。这就要求我们在提交作业执行计算时,首先必须获取当前Flink的运行环境,从而建立起与Flink框架之间

ayt007的博客 1272

加权均值向量算法(INFO)详解:从数学原理到智能算法

本文系统介绍了加权均值向量算法(INFO)的理论基础、数学模型与实现应用。该算法基于加权均值数学概念,通过MeanRule规则平衡探索与开发能力,具有结构新颖、参数合理的特点。核心内容包括:1) 算法理论基础,阐述加权均值数学定义与小波函数权重计算;2) 算法原理,详细解析更新规则、向量组合和局部搜索三阶段数学模型;3) 实现方法,提供MATLAB代码关键参数解析;4) 改进方向,介绍INFO-KELM混合模型等变体;5) 应用案例,涵盖函数优化、工程设计与机器学习领域。

qq_42212808的博客 234

Flink核心之DataStream API

对于大部分操作而言,都需要传入一个用户自定义函数(UDF),实现相关操作的接口, 来完成处理逻辑的定义。Flink 暴露了所有 UDF 函数的接口,具体实现方式为接口或者抽象类, 例如 MapFunction、FilterFunction、ReduceFunction 等。所以最简单直接的方式,就是自定义一个函数类,实现对应的接口。下面例子实现了FilterFunction接口,用来筛选url中包含“home”的事件。@Override也可以通过匿名函数类实现@Override。

weixin_72525373的博客 865

置顶必读(1) |《YOLOv8实战:从入门到深度优化》专栏导读,带你一文了解本专栏!

🏆 本文收录于 《YOLOv8实战:从入门到深度优化》 专栏,该专栏专注于分享我在YOLOv8目标检测模型中的实战经验,涵盖从入门基础到深度优化的全方位解决方案。无论你是计算机视觉的新手,还是具有多年深度学习经验的专家,本专栏都将为你提供高效、可复现的技术方案,助你掌握YOLOv8的核心技术,提升目标检测性能,突破瓶颈,优化模型,并加速项目开发🚀!

**My Coding Family** 14万+

链接文件及功能安全:S32K3如何将FLASH驱动放到RAM里面、RAM如何实现软件复位数据不丢失操作。

在通过RTD的SDK也好MCAL也好,始终存在一个问题,生成的代码除了看门狗模块,默认都是放在flash里面,按照正常逻辑来看没啥大的问题,思考一个问题:Flash放在0x100的位置,但是此时我们要操作0x100怎么办?那肯定不允许啊,但是将flash的驱动放在RAM里面就可以避免这个问题的产生。Flash的特性:PF0能操作PF1,当然PF1也能操作PF0的,以此类推,只要不操作自身,想怎么玩都可以。这也是一个物理特性吧。

梦想技术家 2310

Flink DataStream API 介绍

DataStream API 得名于特殊的 DataStream 类,该类用于表示 Flink 程序中的数据集合。你可以认为 它们是可以包含重复项的不可变数据集合。这些数据可以是有界(有限)的,也可以是无界(无限)的,但用于处理它们的API是相同的。

progammer10086的博客 769

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

5 Flink 算子大全-DataStream API

Flink和Spark类似,也是一种一站式处理的框架;既可以进行批处理(DataSet),也可以进行实时处理(DataStream)。所以下面将Flink的算子分为两大类:一类是DataSet,一类是DataStream。

qq_45972323的博客 1146

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

深入探索 Flink DataStream API

匿名函数:简洁代码实现:在代码中直接使用匿名函数来定义简单的数据处理逻辑,减少代码的复杂性和冗余。即时使用场景:适用于临时性、简单的数据转换或过滤操作,无需定义独立的函数类。函数作用域限制:匿名函数的作用域通常局限于定义它的代码块内,方便局部数据处理。具名函数:代码可读性提升:定义具名函数,使代码逻辑更清晰,便于理解和维护,尤其在复杂的数据处理流程中。函数复用性强:具名函数可以在多个地方被调用,提高了函数的复用性,减少重复代码编写。

你猜我是谁? 1092

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

【Flink从入门到精通 02】DataStream API

在之前的文章中,我们介绍了Flink的安装部署、基础概念,今天我们来一起学习Flink的核心之一DataStream API。 01 分布式流处理基础 上图中,我们将整个代码分为了三个部分,即分布式流处理的基本模型: Source Transformation Sink 从而,我们可以给出Flink编程框架: // 1. 获取运行环境 final StreamExecutionEnvironment env = StreamExecutionEnvironment.ge

十二 1345

48、Flink DataStream API 编程指南(1)- DataStream 入门示例

通常,只需要使用 getExecutionEnvironment() 即可,因为该方法会根据上下文做正确的处理:如果你在 IDE 中执行你的程序或将其作为一般的 Java 程序执行,那么它将创建一个本地环境,该环境将在你的本地机器上执行你的程序。如果你基于程序创建了一个 JAR 文件,并通过命令行运行它,Flink 集群管理器将执行程序的 main 方法,同时 getExecutionEnvironment() 方法会返回一个执行环境以在集群上执行你的程序。

alanchanchn的专栏 6万+

48、Flink DataStream API 编程指南- 完整版

addSource - 关联一个新的 source function。例如,你可以使用 addSource(new FlinkKafkaConsumer(…)) 来从 Apache Kafka 获取数据。其中的maven依赖参考本专栏的相关文章kafka该示例是基于flink1.13.5的版本/**/**// source // 准备kafka连接参数 Properties props = new Properties();

alanchanchn的专栏 6万+

五 Flink DataStream API

文章目录1.map2.filter3 flatmap函数4 keyby4.1 滚动聚合 1.map 实现Map操作,有三种方法.map操作是UDF(一进一出) 1.第一种是和spark的map类似,直接在map算子中传入匿名函数 2.其实map算子接收的是一个实现MapFunction接口的类,我们可以传入一个匿名类 3.可以创建一个实现MapFunction接口的类. package org.example.puapi import org.apache.flink.api.common.functio

andy的博客 494
上一篇: Java 多模块持续集成(Maven 示例)
下一篇: Flink Window
magicpenta
博客等级 码龄10年 42粉丝 30原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值