Flink 基础

举报
剑指南天 发表于 2026/10/27 12:15:21 2026/10/27
【摘要】 Apache Flink 是一个分布式处理引擎和框架,用于对无界和有界数据流进行有状态的计算。

1.概述

Apache Flink 是一个分布式处理引擎和框架,用于对无界和有界数据流进行有状态的计算。

Flink 主要特点:

  • 高吞吐和低延时。每秒处理数百万个事件,毫秒级延迟。
  • 结果的准确性。Flink提供了事件时间(event-time)和处理时间(processing-time)语义。对于乱序事件流,事件时间语义仍然能提供一致且准确的结果。
  • 精确一次(exactly-once)的状态一致性保证。
  • 可以连接到最常用的外部系统,如 Kafka、Hive、JDBC、HDFS、Redis等。
  • 高可用。本身高可用的设置,加上与 K8s 、YARN 和 Mesos 的紧密集成,再加上从故障中快速恢复和动态拓展任务的能力,Flink能做到以极少的停机时间7X24全天候运行。

Flink API:

2. 快速上手代码

import org.apache.flink.api.common.eventtime.WatermarkStrategy;
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.connector.file.src.FileSource;
import org.apache.flink.connector.file.src.reader.TextLineInputFormat;
import org.apache.flink.core.fs.Path;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.util.Collector;

public class Flink05UnboundStream {
    public static void main(String[] args) throws Exception {

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        FileSource<String> fileSource = FileSource.forRecordStreamFormat(new TextLineInputFormat(), new Path("input/")).build();
        DataStreamSource<String> dataStreamSource = env.fromSource(fileSource, WatermarkStrategy.noWatermarks(), "file");
        SingleOutputStreamOperator<Tuple2<String, Integer>> word_one = dataStreamSource.flatMap(new FlatMapFunction<String, Tuple2<String, Integer>>() {
            @Override
            public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {
                String[] words = s.split(" +");
                for (String word : words) {
                    collector.collect(new Tuple2<>(word, 1));
                }
            }
        });
        word_one.keyBy((KeySelector<Tuple2<String, Integer>, String>) stringIntegerTuple2 -> stringIntegerTuple2.f0).sum(1).print();

        env.execute();
    }
}

3. 作业部署模式(基于 YARN)

3.1 会话模式

会话模式需要启动一个集群,保持一个会话。客户端通过这个会话提交作业。因为集群启动时所有资源已经确定,所以提交的所有作业会竞争集群中的资源。

bin/yarn-session.sh -nm test

可用参数解读:

  • -d:分离模式,如果你不想让Flink YARN客户端一直前台运行,可以使用这个参数,即使关掉当前对话窗口,YARN session也可以后台运行。
  • -jm(--jobManagerMemory):配置JobManager所需内存,默认单位MB。
  • -nm(--name):配置在YARN UI界面上显示的任务名。
  • -qu(--queue):指定YARN队列名。
  • -tm(--taskManager):配置每个TaskManager所使用内存。

注意:Flink1.11.0版本不再使用 -n 参数和 -s 参数分别指定 TaskManager 数量和 slot 数量,YARN 会按照需求动态分配 TaskManager 和 slot 。所以从这个意义上讲,YARN的会话模式也不会把集群资源固定,同样是动态分配的。

bin/flink run -c com.atguigu.wc.SocketStreamWordCount FlinkTutorial-1.0-SNAPSHOT.jar

3.2 单作业模式

单作业模式为每个提交的作业启动一个集群。Flink 本身无法直接这样运行,需要借助资源管理框架(YARN、Kubernetes)来启动集群。

bin/flink run -d -t yarn-per-job -c com.atguigu.wc.SocketStreamWordCount FlinkTutorial-1.0-SNAPSHOT.jar

bin/flink list -t yarn-per-job -Dyarn.application.id=application_XXXX_YY

bin/flink cancel -t yarn-per-job -Dyarn.application.id=application_XXXX_YY <jobId>

3.3 应用模式

会话模式和单作业模式的应用代码都是在客户端上执行,然后由客户端提交给 JobManager 的。这种方式客户端需要占用大量网络带宽,去下载依赖和把二进制数据发送给 JobManager;加上很多情况下提交作业用的是同一个客户端,就会加重客户端所在节点的资源消耗。所以解决办法就是,直接把应用提交到 JobManger 上运行。所以需要为每一个提交的应用单独启动一个JobManager,也就是创建一个集群。这个JobManager只为执行这一个应用而存在,执行结束之后JobManager也就关闭了,这就是所谓的应用模式。

bin/flink run-application -t yarn-application -Dyarn.provided.lib.dirs="hdfs://hadoop102:8020/flink-dist" -c com.atguigu.wc.SocketStreamWordCount  hdfs://hadoop102:8020/flink-jars/FlinkTutorial-1.0-SNAPSHOT.jar

bin/flink list -t yarn-application -Dyarn.application.id=application_XXXX_YY

bin/flink cancel -t yarn-application -Dyarn.application.id=application_XXXX_YY <jobId>

3.4 三种模式对比

维度

Session

Per-Job(老)

Application(推荐)

main() 在哪执行

客户端

客户端

JM(集群内)​

JobGraph 在哪生成

客户端

客户端

JM​

客户端带宽消耗

高

高

低(只传 jar 引用)

JM 生命周期

长驻,多作业

每作业一个

每应用一个​

作业隔离

无

有

有​

客户端断网

作业可能失败

作业可能失败

不受影响​

适合场景

调试、小作业

逐步淘汰

生产主流​

4. Flink 运行时架构

4.1 会话模式系统架构流程

1)作业管理器(JobManager)

JobManager 是一个Flink集群中任务管理和调度的核心,是控制应用执行的主进程。也就是说,每个应用都应该被唯一的 JobManager 所控制执行。

JobManger 又包含3个不同的组件。

(1)JobMaster

JobMaster 是 JobManager 中最核心的组件,负责处理单独的作业(Job)。所以 JobMaster 和具体的 Job 是一一对应的,多个 Job 可以同时运行在一个Flink集群中, 每个 Job 都有一个自己的 JobMaster。

在作业提交时,JobMaster 会先接收到要执行的应用。JobMaster 会把 JobGraph 转换成一个物理层面的数据流图,这个图被叫作“执行图”(ExecutionGraph),它包含了所有可以并发执行的任务。JobMaster会向资源管理器(ResourceManager)发出请求,申请执行任务必要的资源。一旦它获取到了足够的资源,就会将执行图分发到真正运行它们的 TaskManager 上。

(2)资源管理器(ResourceManager)

ResourceManager 主要负责资源的分配和管理,在 Flink 集群中只有一个。所谓“资源”,主要是指 TaskManager 的任务槽(task slots)。任务槽就是Flink集群中的资源调配单元,包含了机器用来执行计算的一组 CPU 和内存资源。每一个任务(Task)都需要分配到一个slot上执行。

(3)分发器(Dispatcher)

Dispatcher 主要负责提供一个 REST 接口,用来提交应用,并且负责为每一个新提交的作业启动一个新的 JobMaster 组件。Dispatcher 也会启动一个 Web UI,用来方便地展示和监控作业执行的信息。

2)任务管理器(TaskManager)

TaskManager 是 Flink 中的工作进程,数据流的具体计算就是它来做的。Flink集群中必须至少有一个 TaskManager;每一个 TaskManager 都包含了一定数量的任务槽(task slots)。Slot 是资源调度的最小单位,slot 的数量限制了TaskManager能够并行处理的任务数量。

启动之后,TaskManager 会向资源管理器注册它的 slots;收到资源管理器的指令后,TaskManager 就会将一个或者多个槽位提供给 JobMaster 调用,JobMaster 就可以分配任务来执行了。在执行过程中,TaskManager 可以缓冲数据,还可以跟其他运行同一应用的 TaskManager 交换数据。

4.2 核心概念

并行度:一个特定算子的子任务(subtask)的个数被称之算子的并行度(parallelism)。

  • 代码中设置:算子后跟着调用setParallelism();执行环境的setParallelism()。注意:keyBy不是算子,所以无法对keyBy设置并行度
  • 提交应用时设置:-p 参数来指定当前应用程序执行的并行度
  • 配置文件中设置:配置文件flink-conf.yaml -> parallelism.default: 2

算子链:并行度相同的一对一(one to one)算子操作,可以直接链接在一起形成一个“大”的任务(task),每个task会被一个线程执行。Flink默认会按照算子链的原则进行链接合并。

任务槽:Flink 中每一个 TaskManager 都是一个JVM进程,TaskManager的计算资源是有限的,并行的任务越多,每个线程的资源就会越少。TaskManager上对每个任务运行所占用的资源做出明确的划分,这就是所谓的任务槽(task slots)。每个任务槽(task slot)其实表示了 TaskManager 拥有计算资源的一个固定大小的子集。flink-conf.yaml配置文件中 taskmanager.numberOfTaskSlots。需要注意的是,slot目前仅仅用来隔离内存,不会涉及CPU的隔离。

flink run-application -t yarn-application -d -Dyarn.application.name=my-job -Dyarn.application.queue=realtime -Djobmanager.memory.process.size=2048m -Dtaskmanager.memory.process.size=4096m -Dtaskmanager.numberOfTaskSlots=4 -Dparallelism.default=12 -c com.xxx.MyJob /path/to/job.jar

Flink默认是允许slot共享的,如果希望某个算子对应的任务完全独占一个slot,或者只有某一部分算子共享slot,可以通过算子的 slotSharingGroup("组名") slot 共享组手动指定。

目的

用法

只断链、不隔离资源

.disableChaining()

只隔离 slot、可链

.slotSharingGroup("g")(同组可链)

又单飞又隔离

.disableChaining().slotSharingGroup("g")

重新起链

.startNewChain()

任务槽和并行度的关系:任务槽是静态的概念,TaskManager 具有的并发执行能力,可以通过参数 taskmanager.numberOfTaskSlots 进行配置;而并行度是动态概念,也就是 TaskManager 运行程序时实际使用的并发能力,可以通过参数parallelism.default进行配置。举例说明:standalone的会话模式,假设一共有3个TaskManager,每一个TaskManager中的slot数量设置为3个,那么一共有9个task slot,表示集群最多能并行执行9个同一算子的子任务。

4.3 YARN模式系统架构流程

注意:AM 是 YARN 视角的名字,JobManager 是 Flink 视角的名字

5. 代码生成任务的过程


【版权声明】本文为华为云社区用户原创内容,未经允许不得转载,如需转载请自行联系原作者进行授权。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。