第一天:什么是Flink、WordCount入门、Flink安装、并行度

1. 初识 Flink

在当前数据量激增的时代,各种业务场景都有大量的业务数据产生,对于这些不断产的数据应该如何进行有效的处理,成为当下大多数公司所面临的问题。目前比较流行的大数据处理引擎 Apache Spark,基本上已经取代了 MapReduce 成为当前大数据处理的标准。但 对实时数据处理来说,Apache Spark 的 Spark-Streaming 还有性能改进的空间。对于 Spark-Streaming 的流计算本质上还是批(微批)计算,Apache Flink 就是近年来在开源社区不断发展的技术中的能够同时支持高吞吐低延迟高性能的纯实时的分布式处理框架(主要贡献者是阿里(官网支持汉化阅读),QPS可达30W+)。

Flink 是什么

1. Flink 的发展历史

在 2010 年至 2014 年间,由柏林工业大学、柏林洪堡大学和哈索普拉特纳研究所联合发 起名为Stratosphere:Information Management on the Cloud研究项目,该项目在当时的社区逐渐具有了一定的社区知名度。2014 年 4 月,Stratosphere 代码被贡献给 Apache 软件基金会,成为 Apache 基金会孵化器项目。初期参与该项目的核心成员均是 Stratosphere 曾经的核心成员,之后团队的大部分创始成员离开学校,共同创办了一家名叫 Data Artisans 的公司,其主要业务便是将 Stratosphere,也就是之后的 Flink 实现商业化。在项目孵化 期间,项目 Stratosphere 改名为 Flink。Flink 在德语中是快速灵敏的意思,用来体现流 式数据处理器速度快和灵活性强等特点,同时使用棕红色松鼠图案作为 Flink 项目的 Logo, 也是为了突出松鼠灵活快速的特点,由此,Flink 正式进入社区开发者的视线。 2014 年 12 月,该项目成为 Apache 软件基金会顶级项目,从 2015 年 9 月发布第一个稳 定版本 0.9,到目前为止已经发布到 1.9 的版本,更多的社区开发成员逐步加入,现在 Flink 在全球范围内拥有 350 多位开发人员,不断有新的特性发布。同时在全球范围内,越来越多 的公司开始使用 Flink,在国内比较出名的互联网公司如阿里巴巴、美团、滴滴等,都在大 规模使用 Flink 作为企业的分布式大数据处理引擎。

2. Flink 的定义

Apache Flink 是一个框架和分布式处理引擎,用于在无边界有边界数据流上进行有状态的计算。Flink 能在所有常见集群环境中运行,并能以内存速度和任意规模进行计算。

Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams. Flink has been designed to run in all common cluster environments, perform computations at in-memory speed and at any scale

3. 有界流和无界流

任何类型的数据都可以形成一种事件流。信用卡交易、传感器测量、机器日志、网站或 移动应用程序上的用户交互记录,所有这些数据都形成一种流。

无界流: 有定义流的开始,但没有定义流的结束。它们会无休止地产生数据。无界流 的数据必须持续处理,即数据被摄取后需要立刻处理。我们不能等到所有数据都到达再处理, 因为输入是无限的,在任何时候输入都不会完成。处理无界数据通常要求以特定顺序摄取事 件,例如事件发生的顺序,以便能够推断结果的完整性。

有界流: 有定义流的开始,也有定义流的结束。有界流可以在摄取所有数据后再进行 计算。有界流所有数据可以被排序,所以并不需要有序摄取。有界流处理通常被称为批处理。跟Spark-Stream类似。
在这里插入图片描述
Apache Flink 擅长处理无界和有界数据集精确的时间控制和状态化使得 Flink 的运 行时(runtime)能够运行任何处理无界流的应用。有界流则由一些专为固定大小数据集特殊设计的算法和数据结构进行内部处理,产生了出色的性能。

4. 有状态的计算架构

数据产生的本质,其实是一条条真实存在的事件按照时间顺序源源不断的产生,我们很难在数据产生的过程中进行计算并直接产生统计结果,因为这不仅对系统有非常高的要求, 还必须要满足高性能、高吞吐、低延时等众多目标。而有状态流计算架构(如图所示)的提 出,从一定程度上满足了企业的这种需求,企业基于实时的流式数据,维护所有计算过程的 状态,所谓状态就是计算过程中产生的中间计算结果每次计算新的数据进入到流式系统中 都是基于中间状态结果的基础上进行运算,最终产生正确的统计结果。基于有状态计算的方式最大的优势是不需要将原始数据重新从外部存储中拿出来,从而进行全量计算,因为这种计算方式的代价可能是非常高的。从另一个角度讲,用户无须通过调度和协调各种批量计算 工具,从数据仓库中获取数据统计结果,然后再落地存储,这些操作全部都可以基于流式计 算完成,可以极大地减轻系统对其他框架的依赖,减少数据计算过程中的时间损耗以及硬件存储
在这里插入图片描述

2. 为什么要使用 Flink

可以看出有状态流计算将会逐步成为企业作为构建数据平台的架构模式,而目前从社区 来看,能够满足的只有 Apache Flink。Flink 通过实现 Google Dataflow 流式计算模型实现 了高吞吐、低延迟、高性能兼具实时流式计算框架。同时 Flink 支持高度容错的状态管理, 防止状态在计算过程中因为系统异常而出现丢失,Flink 周期性地通过分布式快照技术 Checkpoints实现状态的持久化维护,使得即使在系统停机或者异常的情况下都能计算出正 确的结果。

Flink用户 众多,自2019年1月起,阿里巴巴逐步将内部维护的Blink回馈给Flink开源社区,目前贡献代码已超过100万行,国内包括腾讯、百度、字节跳动等公司,国外包括Uber、Lyft、Netflix等公司都是Flink的使用者。
在这里插入图片描述

3. Flink 的应用场景

在实际生产的过程中,大量数据在不断地产生,例如金融交易数据、互联网订单数据、 GPS 定位数据、传感器信号、移动终端产生的数据、通信信号数据等,以及我们熟悉的网络 流量监控、服务器产生的日志数据,这些数据最大的共同点就是实时从不同的数据源中产生, 然后再传输到下游的分析系统。针对这些数据类型主要包括实时智能推荐复杂事件处理实时欺诈检测实时数仓ETL 类型流数据分析类型实时报表类型等实时业务场景,而 Flink 对于这些类型的场景都有着非常好的支持

1. 实时智能推荐

智能推荐会根据用户历史的购买行为,通过推荐算法训练模型,预测用户未来可能会购 买的物品。对个人来说,推荐系统起着信息过滤的作用,对 Web/App 服务端来说,推荐系统 起着满足用户个性化需求,提升用户满意度的作用。推荐系统本身也在飞速发展,除了算法 越来越完善,对时延的要求也越来越苛刻和实时化。利用 Flink 流计算帮助用户构建更加实 时的智能推荐系统,对用户行为指标进行实时计算,对模型进行实时更新,对用户指标进行 实时预测,并将预测的信息推送给 Wep/App 端,帮助用户获取想要的商品信息,另一方面也 帮助企业提升销售额,创造更大的商业价值。

2. 复杂事件处理

对于复杂事件处理,比较常见的案例主要集中于工业领域,例如对车载传感器、机械设备等实时故障检测,这些业务类型通常数据量都非常大,且对数据处理的时效性要求非常高。 通过利用 Flink 提供的 CEP(复杂事件处理)进行事件模式的抽取,同时应用 Flink 的 Sql 进行事件数据的转换,在流式系统中构建实时规则引擎,一旦事件触发报警规则,便立即将 告警结果传输至下游通知系统,从而实现对设备故障快速预警监测,车辆状态监控等目的。

3. 实时欺诈检测

在金融领域的业务中,常常出现各种类型的欺诈行为,例如信用卡欺诈、信贷申请欺诈等,而如何保证用户和公司的资金安全,是近年来许多金融公司及银行共同面对的挑战。 随着不法分子欺诈手段的不断升级,传统的反欺诈手段已经不足以解决目前所面临的问题。 以往可能需要几个小时才能通过交易数据计算出用户的行为指标,然后通过规则判别出具有 欺诈行为嫌疑的用户,再进行案件调查处理,在这种情况下资金可能早已被不法分子转移, 从而给企业和用户造成大量的经济损失。而运用 Flink 流式计算技术能够在毫秒内就完成对 欺诈判断行为指标的计算,然后实时对交易流水进行规则判断或者模型预测,这样一旦检测 出交易中存在欺诈嫌疑,则直接对交易进行实时拦截,避免因为处理不及时而导致的经济损 失。

4. 实时数仓与 ETL 结合离线数仓

通过利用流计算诸多优势和 SQL 灵活的加工能力,对流式数据进行实时清洗归并结构化处理,为离线数仓进行补充和优化。另一方面结合实时数据 ETL 处理能 力,利用有状态流式计算技术,可以尽可能降低企业由于在离线数据计算过程中调度逻辑的复杂度,高效快速地处理企业需要的统计结果,帮助企业更好地应用实时数据所分析出来的 结果。

5. 流数据分析

实时计算各类数据指标,并利用实时结果及时调整在线系统相关策略,在各类内容投放、 无线智能推送领域有大量的应用。流式计算技术将数据分析场景实时化,帮助企业做到实时化分析 Web 应用或者 App 应用的各项指标,包括 App 版本分布情况、Crash 检测和分布等, 同时提供多维度用户行为分析,支持日志自主分析,助力开发者实现基于大数据技术的精细 化运营、提升产品质量和体验、增强用户黏性。

6. 实时报表分析

实时报表分析是近年来很多公司采用的报表统计方案之一,其中最主要的应用便是实时大屏展示。利用流式计算实时得出的结果直接被推送到前端应用,实时显示出重要指标的变 换情况。最典型的案例便是淘宝的双十一活动,每年双十一购物节,除疯狂购物外,最引人 注目的就是天猫双十一大屏不停跳跃的成交总额。在整个计算链路中包括从天猫交易下单购买到数据采集数据计算数据校验,最终落到双十一大屏上展现的全链路时间压缩在 5 秒以内,顶峰计算性能高达数三十万笔订单/秒,通过多条链路流计算备份确保万无一失。 而在其他行业,企业也在构建自己的实时报表系统,让企业能够依托于自身的业务数据,快 速提取出更多的数据价值,从而更好地服务于企业运行过程中。
在这里插入图片描述

4. Flink 的特点和优势

Flink 的具体优势和特点有以下几点

1. 同时支持高吞吐、低延迟、高性能

Flink 是目前开源社区中唯 一 一套集高吞吐低延迟高性能三者于一身的分布式流式数据处理框架。像 Apache Spark 也只能兼顾高吞吐和高性能特性,主要因为在 Spark Streaming 流式计算中无法做到低延迟保障;而流式计算框架 Apache Storm 只 能支持低延迟和高性能特性,但是无法满足高吞吐的要求。而满足高吞吐、低延迟、高 性能这三个目标对分布式流式计算框架来说是非常重要的。

2. 支持事件时间(Event Time)概念

在流式计算领域中,窗口计算的地位举足轻重,但目前大多数框架窗口计算采用的都是系统时间(Process Time),也是事件传输到计算框架处理时,系统主机的当前时间。Flink 能够支持基于事件时间(Event Time)语义进行窗口计算,也就是使用事件产生的时间,这种基于事件驱动的机制使得事件即使乱序到达,流系统也能够计算出 确的结果,保持了事件原本产生时的时序性,尽可能避免网络传输或硬件系统的影响。

Event Time/Processing Time/Ingestion Time,也就是事件时间、处理时间、提取时间,那么这三个时间有什么区别和联系

下图是一个信号站,分别列出了事件时间、处理时间、提取时间的先后顺序。当然上面图示需要你对Flink有一个基本的了解。我们先白话解释,然后在官方解释。
在这里插入图片描述

  • Event Time:也就是事件发生的时间,事件的发生时间。我们有些同学可能会模糊,这里举个例子,我们产生日志的时间,这个应该清楚的,日志的时间戳就是发生时间
  • Processing Time:也就是处理时间,我们看到了这个已经进入Flink程序,也就是我们读取数据源时间,也就是日志到达Flink的时间,但是这个时间是本地机器的时间
  • Ingestion Time:也就是提取时间,我们看到它比处理时间还晚一些,这个时候数据已经发送给窗口,也就是发送给窗口的时间,也就是程序处理计算的时间。
3. 支持有状态计算

Flink 在 1.4 版本中实现了状态管理,所谓状态就是在流式计算过程中将算子的中间结果数据保存在内存或者文件系统中,等下一个事件进入算子后可以从之前的状态中 获取中间结果中计算当前的结果,从而无须每次都基于全部的原始数据来统计结果,这 种方式极大地提升了系统的性能,并降低了数据计算过程的资源消耗。对于数据量大且运算逻辑非常复杂的流式计算场景,有状态计算发挥了非常重要的作用。

4.支持高度灵活的窗口(Window)操作

在流处理应用中,数据是连续不断的,需要通过窗口的方式对流数据进行一定范围 的聚合计算,例如统计在过去的 1 分钟内有多少用户点击某一网页,在这种情况下,我 们必须定义一个窗口,用来收集最近一分钟内的数据,并对这个窗口内的数据进行再计 算。Flink 将窗口划分为基于 Time、Count、Session,以及 Data-driven 等类型的窗口 操作,窗口可以用灵活的触发条件定制化来达到对复杂的流传输模式的支持,用户可以 定义不同的窗口触发机制来满足不同的需求。

5.基于轻量级分布式快照(CheckPoint)实现的容错

Flink 能够分布式运行在上千个节点上,将一个大型计算任务的流程拆解成小的计 算过程,然后将 tesk 分布到并行节点上进行处理。在任务执行过程中,能够自动发现事件处理过程中的错误而导致数据不一致的问题,比如:节点宕机、网路传输问题,或 是由于用户因为升级或修复问题而导致计算服务重启等。在这些情况下,通过基于分布 式快照技术的Checkpoints,将执行过程中的状态信息进行持久化存储,一旦任务出现异常停止,Flink 就能够从 Checkpoints 中进行任务的自动恢复,以确保数据在处理过 程中的精准一致性(Exactly-Once)。快照是默认自动开启实现的。

6.基于 JVM 实现独立的内存管理

内存管理是所有计算框架需要重点考虑的部分,尤其对于计算量比较大的计算场 景,数据在内存中该如何进行管理显得至关重要。针对内存管理,Flink 实现了自身管理内存的机制,尽可能减少 JVM GC 对系统的影响。另外,Flink 通过序列化/反序列化 方法将所有的数据对象转换成二进制在内存中存储,降低数据存储的大小的同时,能够更加有效地对内存空间进行利用,降低 GC 带来的性能下降或任务异常的风险,因此 Flink 较其他分布式处理的框架会显得更加稳定,不会因为 JVM GC 等问题而影响整个 应用的运行。

7. Save Points(保存点)

对于 7*24 小时运行的流式应用,数据源源不断地接入,在一段时间内应用的终止有可能导致数据的丢失或者计算结果的不准确,例如进行集群版本的升级、停机运维操 作等操作。值得一提的是,Flink 通过 SavePoints技术将任务执行的快照保存在存储介质上,当任务重启的时候可以直接从事先保存的 Save Points 恢复原有的计算状态, 使得任务继续按照停机之前的状态运行,Save Points 技术可以让用户更好地管理和运 维实时流式应用。不过需要手动启动跟恢复数据。

5. 常见实时计算框架对比

产品 模型 API 保证次数 容错机制 状态管理 延时 吞吐量
Storm Native(数据实时进入处理) 组合式(基础API) At-least-once(至少一次) Record ACK(ACK机制)
Trident Micro-Batching(划分为小批次处理) 组合式 Exactly-once(精准一致性) Record ACK 基于操作(每个操作都有一个状态) 中等 中等
Spark-Streaming Micro-Batching 声明式(提供封装后的高阶函数,比如Count) Exactly-once RDD CheckPoint(基于RDD做CheckPoint) 基于DStream 中等
Flink Native 声明式 Exactly-once CheckPoint(Flink的一种快照) 基于操作
  1. 模型
    Storm 和 Flink 是真正的一条一条处理数据;而 Trident(Storm 的封装框架) 和 Spark Streaming 其实都是小批处理,一次处理一批数据(小批量)。
  2. API
    Storm 和 Trident 都使用基础 API 进行开发,比如实现一个简单的 sum 求和操作; 而 Spark Streaming 和 Flink 中都提供封装后的高阶函数,可以直接拿来使用,这样就 比较方便了。
  3. 保证次数
    在数据处理方面,Storm 可以实现至少处理一次,但不能保证仅处理一次, 这样就会导致数据重复处理问题,所以针对计数类的需求,可能会产生一些误差; Trident 通过事务可以保证对数据实现仅一次的处理,Spark Streaming 和 Flink 也是 如此。
  4. 容错机制
    Storm和Trident可以通过ACK机制实现数据的容错机制,而Spark Streaming 和 Flink 可以通过 CheckPoint 机制实现容错机制。
  5. 状态管理
    Storm 中没有实现状态管理,Spark Streaming 实现了基于 DStream 的状态 管理,而 Trident 和 Flink 实现了基于操作的状态管理。
  6. 延时
    表示数据处理的延时情况,因此 Storm 和 Flink 接收到一条数据就处理一条数据, 其数据处理的延时性是很低的;而 Trident 和 Spark Streaming 都是小型批处理,它们 数据处理的延时性相对会偏高。
  7. 吞吐量
    Storm 的吞吐量其实也不低,只是相对于其他几个框架而言较低;Trident 属于中等;而 Spark Streaming 和 Flink 的吞吐量是比较高的。
    在这里插入图片描述

2.Flink编程入门

1. Flink 的开发环境

Flink 课程选择的是 Apache Flink 1.9.1 版本,是目前较的稳定版本,并且 兼容性比较好。
下载地址: https://flink.apache.org/zh/downloads.html

1. 开发工具

先说明一下开发工具的问题。官方建议使用IntelliJ IDEA,因为它默认集成了 ScalaMaven环境,使用更加方便,当然使用 Eclipse 也是可以的。本文使用 IDEA。开发Flink 程序时,可以使用JavaPython或者Scala语言,本教程使用 Scala,因为 使用 Scala 实现函数式编程会比较简洁。

2. 配置依赖

开发 Flink 应用程序需要最低限度的 API 依赖。最低的依赖库包括:flink-scalaflink-streaming-scala。大多数应用需要依赖特定的连接器或其他类库,例如 Kafka 的连 接器、TableAPI、CEP 库等。这些不是 Flink 核心依赖的一部分,因此必须作为依赖项手 动添加到应用程序中。

与其他运行用户自定义应用的大多数系统一样,Flink 中有两大类依赖类库

  • Flink 核心依赖:
    Flink 本身包含运行所需的一组类和依赖,比如协调、网络通讯、checkpoint、容错处理、API、算子(如窗口操作)、 资源管理等,这些类和依赖形成了 Flink 运行时的核心。当 Flink 应用启动时,这些依赖必须可用。
    这些核心类和依赖被打包在 flink-dist jar 里。它们是 Flink lib 文件夹下的一部分,也是 Flink 基本容器镜像的一部分。 这些依赖类似 Java String 和 List 的核心类库(rt.jar, charsets.jar等)。
    Flink 核心依赖不包含连接器和类库(如 CEP、SQL、ML 等),这样做的目的是默认情况下避免在类路径中具有过多的依赖项和类。 实际上,我们希望尽可能保持核心依赖足够精简,以保证一个较小的默认类路径,并且避免依赖冲突。

  • 用户应用依赖:
    是指特定的应用程序需要的类库,如连接器,formats等。用户应用代码和所需的连接器以及其他类库依赖通常被打包到 application jar 中。用户应用程序依赖项不需包括 Flink DataSet / DataStream API 以及运行时依赖项,因为它们已经是 Flink 核心依赖项的一部分。

Flink官方依赖文档说明:官方依赖入手

2.WordCount演示

添加pom依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sowhat</groupId>
    <artifactId>Flink-Test</artifactId>
    <version>1.0-SNAPSHOT</version>

<dependencies>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-scala_2.11</artifactId>
        <version>1.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-streaming-scala_2.11</artifactId>
        <version>1.9.1</version>
    </dependency>

    <!--    上述两个是核心依赖-->

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.7.2</version>
    </dependency>

    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-connector-kafka_2.11</artifactId>
        <version>1.9.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.kafka</groupId>
        <artifactId>kafka-clients</artifactId>
        <version>0.11.0.3</version>
    </dependency>

    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-connector-filesystem_2.11</artifactId>
        <version>1.9.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.bahir</groupId>
        <artifactId>flink-connector-redis_2.11</artifactId>
        <version>1.0</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.44</version>
    </dependency>
    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-table-planner_2.11</artifactId>
        <version>1.9.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-table-api-scala-bridge_2.11</artifactId>
        <version>1.9.1</version>
    </dependency>

    <dependency>
        <groupId>org.apache.flink</groupId>
        <artifactId>flink-cep-scala_2.11</artifactId>
        <version>1.9.1</version>
    </dependency>

</dependencies>

    <build>
        <plugins>
            <!-- 该插件用于将Scala代码编译成class文件 -->
            <plugin>
                <groupId>net.alchim31.maven</groupId>
                <artifactId>scala-maven-plugin</artifactId>
                <version>3.4.6</version>
                <executions>
                    <execution>
                        <!-- 声明绑定到maven的compile阶段 -->
                        <goals>
                            <goal>testCompile</goal>
                            <goal>compile</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>

            <!-- Java Compiler   https://blog.csdn.net/liupeifeng3514/article/details/80236077  -->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.1</version>
                <configuration>
                    <source>1.8</source> <!-- 开始代码时指定的JDK版本-->
                    <target>1.8</target> <!-- 编译成.class 文件所需版本-->
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>make-assembly</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal> 
                            <!-- 表示会出现一个无任何依赖的jar,还有一个包含所有依赖的jar -- >
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
    
</project>

注意事项: 所有这些 依赖项 的作用域都应该设置为 provided 。 这意味着需要这些依赖进行编译,但不应将它们打包到项目生成的应用程序jar文件中,因为这些依赖项是 Flink 的核心依赖,服务器运行环境在应用启动前已经是可用的状态了。

我们强烈建议保持这些依赖的作用域provided。 如果它们的作用域未设置为 provided ,则典型的情况是因为包含了 Flink 的核心依赖而导致生成的jar包变得过大。 最糟糕的情况是添加到应用程序的 Flink 核心依赖项与你自己的一些依赖项版本冲突(通常通过反向类加载来避免)。

IntelliJ 上的一些注意事项: 为了可以让 Flink 应用在 IntelliJ IDEA 中运行,这些 Flink 核心依赖的作用域需要设置为 compile 而不是provided否则 IntelliJ 不会添加这些依赖到 classpath,会导致应用运行时抛出 NoClassDefFountError 异常。为了避免声明这些依赖的作用域为 compile (因为我们不推荐这样做), 上文给出的 Java 和 Scala 项目模板使用了一个小技巧:添加了一个 profile,仅当应用程序在 IntelliJ 中运行时该 profile 才会被激活, 然后将依赖作用域设置为 compile ,从而不影响应用 jar 包。

1. 流式接受数据

案例需求:采用 Netcat 数据源发送数据,使用 Flink 统计每个单词的数量。

package com.sowhat.flink

import org.apache.flink.streaming.api.scala.StreamExecutionEnvironment

/**
  * flink的流计算的WordCount
  */
object FlinkStreamWordCount {

  def main(args: Array[String]): Unit = {
    //1、初始化Flink流计算的环境
    val streamEnv: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    //修改并行度
    streamEnv.setParallelism(1) //默认所有算子的并行度为1
    //2、导入隐式转换
    import org.apache.flink.streaming.api.scala._
    //3、读取数据,读取sock流中的数据
    val stream: DataStream[String] = streamEnv.socketTextStream("IP", 8899) //DataStream ==> spark 中Dstream

    //4、转换和处理数据
    val result: DataStream[(String, Int)] = stream.flatMap(_.split(" "))
      .map((_, 1)).setParallelism(2)
      .keyBy(0) //分组算子  : 0 或者 1 代表下标。前面的DataStream[二元组] , 0代表单词 ,1代表单词出现的次数
      .sum(1).setParallelism(2) //聚会累加算子

    //5、打印结果
    result.print("结果").setParallelism(1)
    //6、启动流计算程序
    streamEnv.execute("wordcount")
  }
}

找一个服务可以接受到的接口发送若干信息:

$ nc -lk 8899
hadoop spark hive flink
flink sowhat liu spark
flink sowhat
---
结果> (hive,1)
结果> (spark,1)
结果> (hadoop,1)
结果> (flink,1)
结果> (sowhat,1)
结果> (spark,2)
结果> (liu,1)
结果> (flink,2)
结果> (sowhat,2)
结果> (flink,3)

PS:如果将代码中所有关于并行度的全部屏蔽掉,系统会自动的将全部CPU利用起来,然后利用Hash算法来将数据归类给不同的CPU核心来处理,结果可能如下:

结果:1> (hive,1) // 表示第几个核给出的结果
结果:4> (flink,1)
结果:1> (spark,1)
结果:4> (sohat,1)
结果:1> (hive,2)
结果:2> (node,1)
结果:4> (zookeeper,1)
结果:3> (manager,1)
2. 直接统计指定文件WordCount

需求:读取本地数据文件,统计文件中每个单词出现的次数。 根据需求,很明显是有界流(批计算),所以采用另外一个上下文环境:ExecutionEnvironment
在IDEA的resources目录下创建个wc.txt 文件内容如下:

hello flink spark
hello spark
spark core flink stream
hello fink

批量统计代码如下:

package com.sowhat.flink

import java.net.{URL, URLDecoder}

import org.apache.flink.api.scala.{DataSet, ExecutionEnvironment, _}

/**
  * Flink的批计算案例
  */
object BatchWordCount {

  def main(args: Array[String]): Unit = {
    //初始化Flink批处理环境
    val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment

    val dataPath: URL = getClass.getResource("/wc.txt") //使用相对路径来得到完整的文件路径
    var packagePath: String = dataPath.getPath().replaceAll("%20", ""); //解决路径中含有空格的情况
    val str:String = URLDecoder.decode(packagePath, "utf-8"); //解决路径包含中文的情况
    println(str)

    //读数据
    val data: DataSet[String] = env.readTextFile(str) //DataSet ==> spark RDD

    //计算并且打印结果
    data.flatMap(_.split(" "))
      .map((_, 1))
      .groupBy(0) //分组算子  : 0 或者 1 代表下标。前面的DataStream[二元组] , 0代表单词 ,1代表单词出现的次数
      .sum(1)
      .print()
  }
}

3. Flink 的安装和部署

Flink 的安装和部署主要分为本地(单机)模式和集群模式,其中本地模式只需直接解压就可以使用,不用修改任何参数,一般在做一些简单测试的时候使用。本地模式不再赘述。集群模式包含:

  1. Standalone
  2. Flink on Yarn(重点)
  3. Mesos
  4. Docker
  5. Kubernetes
  6. AWS
  7. Goole Compute Engine

目前在企业中使用最多的是 Flink on Yarn 模式。本文主讲StandaloneFlink on Yarn这两种模式。

1. 集群基本架构

Flink 整个系统主要由两个组件组成,分别为 JobManagerTaskManager,Flink 架构也遵循Master-Slave 架构设计原则,JobManager 为 Master 节点,TaskManager 为 Worker (Slave)节点。所有组件之间的通信都是借助于 Akka Framework,包括任务的状态以及 Checkpoint 触发等信息。
在这里插入图片描述

1. Client 客户端

客户端负责将任务提交到集群,与 JobManager 构建 Akka连接,然后将任务提交到 JobManager,通过和 JobManager之间进行交互获取任务执行状态。客户端提交任务可以采 用 CLI 方式或者通过使用 Flink WebUI提交,也可以在应用程序中指定JobManagerRPC网络端口构建 ExecutionEnvironment 提交 Flink 应用。

2.JobManager

JobManager 负责整个 Flink 集群任务的调度以及资源的管理,从客户端中获取提交的 应用,然后根据集群中 TaskManager 上 TaskSlot 的使用情况,为提交的应用分配相应的 TaskSlots 资源并命令 TaskManger 启动从客户端中获取的应用。JobManager 相当于整个集 群的 Master 节点,且整个集群中有且仅有一个活跃的 JobManager,负责整个集群的任务管 理和资源管理。JobManager 和 TaskManager 之间通过 Actor System 进行通信,获取任务执 行的情况并通过 Actor System 将应用的任务执行情况发送给客户端。同时在任务执行过程 中,Flink JobManager会触发 Checkpoints 操作,每个TaskManager 节点收到 Checkpoint 触发指令后,完成 Checkpoint操作,所有的Checkpoint协调过程都是在 Flink JobManager中完成。当任务完成后,Flink 会将任务执行的信息反馈给客户端,并且释放掉 TaskManager 中的资源以供下一次提交任务使用。

3. TaskManager

TaskManager 相当于整个集群的 Slave 节点,负责具体的任务执行和对应任务在每个节 点上的资源申请与管理。客户端通过将编写好的 Flink 应用编译打包,提交到 JobManager, 然后 JobManager 会根据已经注册在 JobManager 中 TaskManager 的资源情况,将任务分配给 有资源的 TaskManager 节点,然后启动并运行任务。TaskManager 从 JobManager 接收需要 部署的任务,然后使用 Slot 资源启动 Task,建立数据接入的网络连接,接收数据并开始数 据处理。同时 TaskManager 之间的数据交互都是通过数据流的方式进行的。 可以看出,Flink 的任务运行其实是采用多线程的方式,这和 MapReduce 多 JVM 进程的 方式有很大的区别Fink 能够极大提高 CPU 使用效率,在多个任务和 Task 之间通过 TaskSlot方式共享系统资源,每个 TaskManager 中通过管理多个 TaskSlot 资源池进行对资源进行有 效管理

PS:可以认为JobManager类似Hadoop中ApplicationMaster,然后一个机器就是一个TaskManager,一个TaskManager可以分解成若干个Flink基本工作单元TaskSlot

2. Standalone 集群安装和部署

Standalone 是 Flink 的独立部署模式,它不依赖其他平台。在使用这种模式搭建 Flink 集群之前,需要先规划集群机器信息。在这里为了搭建一个标准的 Flink 集群,需要准备 3 台 Linux。
在这里插入图片描述

  1. 下载并解压文件到指定目录
  2. 修改配置文件
    进入到 conf 目录下,编辑 flink-conf.yaml 配置文件
jobmanager.rpc.address: hadoop101

# The RPC port where the JobManager is reachable.

jobmanager.rpc.port: 6123


# The heap size for the JobManager JVM

jobmanager.heap.size: 1024m # JobManager 内存大小

# The total process memory size for the TaskManager.
#
# Note this accounts for all memory usage within the TaskManager process, including JVM metaspace and other overhead.

taskmanager.memory.process.size: 1024m # TaskManager初始化内存大小 

# To exclude JVM metaspace and overhead, please, use total Flink memory size instead of 'taskmanager.memory.process.size'.
# It is not recommended to set both 'taskmanager.memory.process.size' and Flink memory.
#
# taskmanager.memory.flink.size: 1280m

# The number of task slots that each TaskManager offers. Each slot runs one parallel pipeline.

taskmanager.numberOfTaskSlots: 3 # 每一个TaskManager 有几个TaskSlots

# The parallelism used for programs that did not specify and other parallelism.

parallelism.default: 1 # 默认并行度
  1. 编辑slaves文件
vi slaves
hadoop101
hadoop102
hadoop103
  1. 信息分发
[root@hadoop101 home]# scp -r flink-1.9.1 root@hadoop102:`pwd`
[root@hadoop101 home]# scp -r flink-1.9.1 root@hadoop103:`pwd`
  1. 主节点启动集群
    在这里插入图片描述
  2. WebUI 访问
    flink-conf.yaml的配置文件中rest.port是WebUI的对外端口,服务器输入hadoop101:8081即可访问(我这里随便找个别人搭建看的集群看下WebUI)。
    在这里插入图片描述
    左侧栏多点点看看即可,相对来说比较简单。
  3. 将IDEA代码中的两个Flink核心依赖设置为provided然后打包(打包的时候经常性出现问题需检查)通过WebUI上传。
    在这里插入图片描述
    测试结果如下:
[root@hadoop101 home]#  nc -lk 8899
12 21 21

在这里插入图片描述

在这里插入图片描述
PS敲重点 IDEA中用到的Flink-scala核心依赖要跟服务器集群的核心依赖版本一致,否则会 报错

java.lang.NoSuchMethodError: scala.Predef$.refArrayOps

  1. 命令行提交
    命令行提交 flink同样支持两种提交方式,默认不指定就是客户端方式。如果需要使用集群方式提交的话。可以在提交作业的命令行中指定-d或者–detached 进行进群模式提交。

-d,–detached If present, runs the job in detached mode(分离模式)

客户端提交方式:$FLINK_HOME/bin/flink run   -c com.daxin.batch.App flinkwordcount.jar 
客户端会多出来一个CliFrontend进程,就是驱动进程。
集群模式提交:$FLINK_HOME/bin/flink run -d  -c com.daxin.batch.App flinkwordcount.jar 
程序提交完毕退出客户端,不再打印作业进度等信息!
  1. 重要参数说明:下面针对 flink-conf.yaml 文件中的几个重要参数进行分析:
  • jobmanager.heap.size:JobManager 节点可用的内存大小。
  • taskmanager.heap.size:TaskManager 节点可用的内存大小。
  • taskmanager.numberOfTaskSlots:每台机器可用的 Slot 数量。
  • parallelism.default:默认情况下 Flink 任务的并行度。

上面参数中所说的 Slotparallelism的区别:

  • Slot 是静态的概念,是指 TaskManager 具有的并发执行能力。
  • parallelism 是动态的概念,是指程序运行时实际使用的并发能力。
  • 设置合适的 parallelism 能提高运算效率。
  • 比如我又4个跑道(Slot ),本次任务我占用2个(parallelism)。 一般情况下Slot >= parallelism

3. Flink 提交到 Yarn

Flink on Yarn 模式的原理是依靠 YARN 来调度 Flink 任务,目前在企业中使用较多。 这种模式的好处是可以充分利用集群资源,提高集群机器的利用率,并且只需要 1 套 Hadoop 集群,就可以执行 MapReduce 和 Spark 任务,还可以执行 Flink 任务等,操作非常方便,不 需要维护多套集群,运维方面也很轻松。Flink on Yarn 模式需要依赖 Hadoop 集群,并且 Hadoop 的版本需要是 2.2 及以上。本文选择的 Hadoop 版本是 2.7.2。

Flink On Yarn 的内部实现原理(Snagit Editor绘制):
在这里插入图片描述

  • 当启动一个新的 Flink YARN Client 会话时,客户端首先会检查所请求的资源(容器和内存)是否可用。之后,它会上传 Flink 配置和 JAR 文件到 HDFS。
  • 客 户 端 的 下 一 步 是 请 求 一 个 YARN 容 器 启 动 ApplicationMaster 。 JobManager 和 ApplicationMaster(AM)运行在同一个容器中,一旦它们成功地启动了,AM 就能够知道 JobManager 的地址,它会为 TaskManager 生成一个新的 Flink 配置文件(这样它才能连 上 JobManager),该文件也同样会被上传到 HDFS。另外,AM 容器还提供了 Flink 的 Web 界面服务。Flink 用来提供服务的端口是由用户和应用程序 ID 作为偏移配置的,这 使得用户能够并行执行多个 YARN 会话。
  • 之后,AM 开始为 Flink 的 TaskManager 分配容器(Container),从 HDFS 下载 JAR 文件 和修改过的配置文件。一旦这些步骤完成了,Flink 就安装完成并准备接受任务了

Flink on Yarn 模式在使用的时候又可以分为两种

第 1 种模式(Session-Cluster):

是在 YARN 中提前初始化一个 Flink 集群(称为 Flink yarn-session),开辟指定的资源,以后的 Flink 任务都提交到这里。这个 Flink 集群会常驻在 YARN 集群中,除非手工停止。这种方式创建的 Flink 集群会独占资源,不管有没有 Flink 任务在执行,YARN 上面的其他任务都无法使用这些资源。一般此种方式用的较少。
在这里插入图片描述

第 2 种模式(Per-Job-Cluster):

每次提交 Flink 任务都会创建一个新的 Flink 集群, 每个 Flink 任务之间相互独立、互不影响,管理方便。任务执行完成之后创建的 Flink 集群也会消失,不会额外占用资源,按需使用,这使资源利用率达到最大,在工作中推荐使用这种模式
在这里插入图片描述
注意:Flink on Yarn 还需要两个先决条件:

  1. 配置 Hadoop 的环境变量
  2. 下载 Flink 提交到 Hadoop 的连接器(jar 包 大约40M),并把 jar 拷贝到 Flink 的 lib 目录下在这里插入图片描述
[root@hadoop101 flink-1.9.1]# cp  /home/flink-shaded-hadoop-2-uber-2.7.5-7.0.jar   lib/

启动第一种 Session-Cluster 模式(yarn-session)

1 先启动 Hadoop 集群,然后通过命令启动一个 Flink 的 yarn-session 集群:

[root@hadoop101 flink-1.9.1]# bin/yarn-session.sh -n 3 -s 3 -nm sowhat -d 

其中 yarn-session.sh 后面支持多个参数。下面针对一些常见的参数进行讲解:

  1. -n、–container 表示分配容器的数量(也就是 TaskManager 的数量)。
  2. -D 动态属性。
  3. -d、–detached 在后台独立运行。
  4. -jm、–jobManagerMemory :设置 JobManager 的内存,单位是 MB。
  5. -nm、–name:在 YARN 上为一个自定义的应用设置一个名字。
  6. -q、–query:显示 YARN 中可用的资源(内存、cpu 核数)。
  7. -qu、–queue :指定 YARN 队列。
  8. -s、–slots :每个 TaskManager 使用的 Slot 数量。
  9. -tm、–taskManagerMemory :每个 TaskManager 的内存,单位是 MB。
  10. -z、–zookeeperNamespace :针对 HA 模式在 ZooKeeper 上创建 NameSpace。
  11. -id、–applicationId :指定 YARN 集群上的任务 ID,附着到一个后台独 立运行的 yarn session 中。
    在这里插入图片描述
    查看 WebUI: 由于还没有提交 Flink job,所以都是 0。
    在这里插入图片描述
    这个时候注意查看本地文件系统中有一个临时文件。有了这个文件可以提交 job 到 Yarn
    在这里插入图片描述
    提交 Job : 由于有了之前的配置,所以自动会提交到 Yarn 中。
bin/flink run -c com.bjsxt.flink.StreamWordCount /home/Flink-Demo-1.0-SNAPSHOT.jar

在这里插入图片描述
至此第一种模式全部完成。

启动第二种模式

这种模式下不需要先启动 yarn-session。所以我们可以把前面启动的 yarn-session 集 群先停止,停止的命令是:

yarn application -kill application_1576832892572_0002 //其中 application_1576832892572_0002 是ID

确保 Hadoop 集群是健康的情况下直接提交 Job 命令:

bin/flink run -m yarn-cluster -yn 3 -ys 3 -ynm sowhat02 \
-c com.sowhat.flink.StreamWordCount /home/Flink-Demo-1.0-SNAPSHOT.jar

可以看到一个全新的 yarn-session
在这里插入图片描述
任务提交参数讲解:相对于 Yarn-Session 参数而言,只是前面加了 y。

  1. -yn、–container 表示分配容器的数量,也就是 TaskManager 的数量。
  2. -d、–detached:设置在后台运行。
  3. -yjm、–jobManagerMemory:设置 JobManager 的内存,单位是 MB。
  4. -ytm、–taskManagerMemory:设置每个 TaskManager 的内存,单位是 MB。
  5. -ynm、–name:给当前 Flink application 在 Yarn 上指定名称。
  6. -yq、–query:显示 yarn 中可用的资源(内存、cpu 核数)
  7. -yqu、–queue :指定 yarn 资源队列
  8. -ys、–slots :每个 TaskManager 使用的 Slot 数量。
  9. -yz、–zookeeperNamespace:针对 HA 模式在 Zookeeper 上创建 NameSpace
  10. -yid、–applicationID : 指定 Yarn 集群上的任务 ID,附着到一个后台独 立运行的 Yarn Session 中。

4. Flink 的HA

默认情况下,每个 Flink 集群只有一个 JobManager,这将导致单点故障(SPOF),如 果这个 JobManager 挂了,则不能提交新的任务,并且运行中的程序也会失败。使用 JobManager HA,集群可以从 JobManager 故障中恢复,从而避免单点故障。用户可以在 StandaloneFlink on Yarn 集群模式下配置 Flink 集群 HA(高可用性)。

Standalone HA

Standalone 模式下,JobManager 的高可用性的基本思想是,任何时候都有一个 Alive JobManager 和多个 Standby JobManager。Standby JobManager 可以在 Alive JobManager 挂掉的情况下接管集群成为 Alive JobManager,这样避免了单点故障,一旦某一个 Standby JobManager 接管集群,程序就可以继续运行。Standby JobManagers 和 Alive JobManager 实例之间没有明确区别,每个 JobManager 都可以成为 Alive 或 Standby在这里插入图片描述
Flink Standalone 集群的 HA 安装和配置
实现 HA 还需要依赖 ZooKeeper 和 HDFS,因此要有一个 ZooKeeper 集群和 Hadoop 集群, 首先启动 Zookeeper 集群和 HDFS 集群。本文中分配 3 台 JobManager,如下表:

hadoop101 hadoop102 hadoop103
JobManager JobManager JobManager
TaskManager TaskManager TaskManager
  1. 修改配置文件 conf/masters
hadoop101:8081
hadoop102:8081
hadoop103:8081
  1. 修改配置文件 conf/flink-conf.yaml
#要启用高可用,设置修改为zookeeper
 high-availability: zookeeper 
#Zookeeper的主机名和端口信息,多个参数之间用逗号隔开
high-availability.zookeeper.quorum: hadoop103:2181,hadoop101:2181,hadoop102:2181 
# 建议指定HDFS的全路径。如果某个Flink节点没有配置HDFS的话,不指定HDFS的全路径 则无法识到,
# storageDir存储了恢复一个JobManager所需的所有元数据。
high-availability.storageDir: hdfs://hadoop101:9000/flink/h
  1. 把修改的配置文件拷贝其他服务器中
[root@hadoop101 conf]# scp masters flink-conf.yaml root@hadoop102:`pwd` 
[root@hadoop101 conf]# scp masters flink-conf.yaml root@hadoop103:`pwd`
  1. 启动集群
    在这里插入图片描述
    版本问题:目前使用 Flink1.7.1 版本测试没有问题,使用 Flink1.9 版本存在 HA 界面不能自动跳转到对应的 Alive jobManager。
Flink On Yarn HA

正常基于 Yarn 提交 Flink 程序,无论是使用 yarn-session 模式还是 yarn-cluster模 式 , 基 于 yarn 运 行 后 的 application 只 要 kill 掉 对 应 的 Flink 集 群 进 程YarnSessionClusterEntrypoint后,基于 Yarn 的 Flink 任务就失败了,不会自动进行重试,所以基于 Yarn 运行 Flink 任务,也有必要搭建 HA,这里同样还是需要借助 zookeeper 来完成,步骤如下:

  1. 修改所有 Hadoop 节点的 yarn-site.xml 将所有 Hadoop 节点的 yarn-site.xml 中的提交应用程序最大尝试次数调大
#在每台hadoop节点yarn-site.xml中设置提交应用程序的最大尝试次数,建议不低于4,
# 这里重试指的ApplicationMaster 
<property> 
    <name>yarn.resourcemanager.am.max-attempts</name>
     <value>4</value> 
</property>
  1. 启动 zookeeper,启动 Hadoop 集群
  2. 修改 Flink 对应 flink-conf.yaml 配置,配置内容如下:
#配置依赖zookeeper模式进行HA搭建 
high-availability: zookeeper 
#配置JobManager原数据存储路径 high-availability.storageDir: hdfs://hadoop101:9000/flink/yarnha/ 
#配置zookeeper集群节点 
high-availability.zookeeper.quorum: hadoop101:2181,hadoop102:2181,hadoop103:2181 
#yarn停止一个application重试的次数 
yarn.application-attempts: 10
  1. 启动 yarn-session.sh 测试 HA: yarn-session.sh -n 2 ,也可以直接提交 Job 启动之后,可以登录 yarn 中对应的 flink WebUI,如下图示:在这里插入图片描述
  2. 点击对应的 Tracking UI,进入 Flink 集群 UI
    在这里插入图片描述
    查看对应的 JobManager 在哪台节点上启动:在这里插入图片描述
    进入对应的节点,kill 掉对应的YarnSessionClusterEntrypoint进程。然后进入到 Yarn 中观察applicationxxxx_0001job 信息:在这里插入图片描述
    点击 job ID,发现会有对应的重试信息:在这里插入图片描述
    点击对应的Tracking U进入到 Flink 集群 UI,查看新的 JobManager 节点由原来的 hadoop103 变成了 hadoop101,说明 HA 起作用。在这里插入图片描述

4. Flink 并行度和 Slot

Flink中每一个worker(TaskManager)都是一个JVM进程,它可能会在独立的线程(Solt) 上执行一个或多个 subtask。Flink 的每个 TaskManager 为集群提供 Solt。Solt 的数量通常 与每个 TaskManager 节点的可用 CPU 内核数成比例一般情况下 Slot 的数量就是每个节点 的 CPU 的核数。 Slot 的 数 量 由 集 群 中 flink-conf.yaml 配 置 文 件 中 设 置 taskmanager.numberOfTaskSlots,这个值的大小建议和节点 CPU 的数量保持一致。比如我设置=3。
并行度=2的情况下:
在这里插入图片描述
注意一点:一个TaskSlot可能执行多个job。

一个任务的并行度设置可以从 4 个层面指定:

  1. Operator Level(算子层面)。
  2. Execution Environment Level(执行环境层面)。
  3. Client Level(客户端层面)。
  4. System Level(系统层面)。

这 些 并 行 度 的 优 先 级 为 :
Operator Level >Execution Environment Level > Client Level > System Level。

1. 并行度设置之 Operator Level

Operator、Source 和 Sink 目的地的并行度可以通过调用 setParallelism()方法来指定

    val result: DataStream[(String, Int)] = stream.flatMap(_.split(" "))
     .map((_, 1)).setParallelism(2)
     .keyBy(0) //分组算子  : 0 或者 1 代表下标。前面的DataStream[二元组] , 0代表单词 ,1代表单词出现的次数
     .sum(1).setParallelism(2) //聚会累加算子
      //5、打印结果
   result.print("结果").setParallelism(1)
2. 并行度设置之 Execution Environment Level

任务的默认并行度可以通过调用 setParallelism()方法指定。为了以并行度 3 来执行 所有的 Operator、Source 和 Sink,可以通过如下方式设置执行环境的并行度

    //1、初始化Flink流计算的环境
    val streamEnv: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
    //修改并行度
    streamEnv.setParallelism(3) //默认所有算子的并行度为3
3. 并行度设置之 Client Level

并行度还可以在客户端提交 Job 到 Flink 时设定。对于 CLI 客户端,可以通过-p 参数指定并行度。

bin/flink run -p 10  WordCount.jar
4. 并行度设置之 System Level

在系统级可以通过设置flink-conf.yaml文件中的parallelism.default属性来指定所 有执行环境的默认并行度。

# The parallelism used for programs that did not specify and other parallelism.
parallelism.default: 1
5. 并行度案例分析

Flink 集群中有 3 个 TaskManager 节点,每个 TaskManager 的 Slot 数量为 3
在这里插入图片描述
全部默认情况下:
在这里插入图片描述
全局并行度=2
在这里插入图片描述
End:牢记并行度设置的优先级,根据集群配置合理设置参数。

参考

Flink全套学习资料

猜你喜欢

转载自blog.csdn.net/qq_31821675/article/details/107296787