Flink实时计算引擎-02 并行度配置、DataStream编程模型、转换算子及实战案例

本文详细介绍了Apache Flink的并行度概念,包括TaskManager、slot和Task的关系,并展示了如何在算子、执行环境、客户端和系统级别设置并行度。此外,还涵盖了DataStream编程模型,数据源(如文件、Socket、集合和自定义输入)、数据转换算子(如map、filter、flatMap、keyBy、sum、reduce、union、connect、重分区)以及Sink数据目标,如写入Redis。最后,通过实际代码演示了并行度的配置和操作。

Flink学习笔记

Flink实操篇

Flink 并行度 & Slot & Task

Flink 中的 TaskManager 是执行任务的节点,Flink 的每个 TaskManager 为集群提供 slot(插槽),这些 slot 可以同时执行多个任务。
slot 个数代表的是每一个 TaskManager 的并发执行能力,每个 task slot 代表了 TaskManager 的一个固定大小的资源子集。
slot的数量通常与每个 TaskManager 节点的可用 CPU 内核数成比例。一般情况下你的 slot 数是你每个节点的 cpu 的核数。
在这里插入图片描述

1. 并行度
  • 一个 Flink 程序由多个任务组成(source、transformation和 sink)。 一个任务由多个并行的实例(线程)来执行, 一个任务的并行实例 (线程) 数目就被称为该任务的并行度
2. 并行度的设置
  • 一个任务的并行度设置可以从多个级别指定
    • Operator Level(算子级别)
    • Execution Environment Level(执行环境级别)
    • Client Level(客户端级别)
    • System Level(系统级别)
  • 这些并行度的优先级为
    • Operator Level > Execution Environment Level > Client Level > System Level
算子级别
DataStream<Tuple2<String, Integer>> resultStream = streamSource
                .flatMap((FlatMapFunction<String, Tuple2<String, Integer>>) (line, collector) -> {
   
   
                    Arrays.stream(line.split(" ")).filter(Objects::nonNull)
                            .forEach(word -> collector.collect(new Tuple2<>(word, 1)));
                }).returns(Types.TUPLE(Types.STRING, Types.INT))
                .keyBy((KeySelector<Tuple2<String, Integer>, String>) tuple2 -> tuple2.f0)
                .sum(1)
    			// 设置并行度
    			.setParallelism(4);
执行环境级别
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment()
    			// 设置并行度
                .setParallelism(2);
客户端级别
  • 并行度可以在客户端将 job 提交到 Flink 时设定,对于 CLI 客户端,可以通过 -p参数指定并行度
bin/flink run -p 10 examples/batch/WordCount.jar
系统级别
  • 在系统级可以通过设置 flink-conf.yaml 文件中的 parallelism.default 属性来指定所有执行环境的默认并行度
parallelism.default: 1
3. 并行度操作
  • 为了方便在本地测试观察任务并行度信息,可以在本地工程添加以下依赖
<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-runtime-web_2.11</artifactId>
    <version>${flink.version}</version>
</dependency>
  • 代码演示
import org.apache.flink.streaming.api.scala.{
   
   DataStream, StreamExecutionEnvironment}
import org.apache.flink.api.scala._

/**
  * 本地调试并行度
  */
object ParallelismTest {
   
   
  def main(args: Array[String]): Unit = {
   
   
    // 1. 使用 createLocalEnvironmentWithWebUI 方法,构建本地流处理环境
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.createLocalEnvironmentWithWebUI()
//    // 设置环境级别 并行度
//    env.setParallelism(4)

    // 2. 接收socket数据
    val sourceStream: DataStream[String] = env
      .socketTextStream("node01", 9999) // source task

    // 3. 数据处理
    sourceStream.flatMap(x => x.split(" ")) // flatMap task
      .map(x => (x, 1)) // map task
      .keyBy(0)
      .sum(1)  // sum task
      .print()  // print task

    // 4. 启动
    env.execute()
  }
}
  • 本地启动程序,并访问地址:http://localhost:8081,查看并行度和Task数量

在这里插入图片描述

为什么 Task 数量是 25?不设置并行度时,默认 tasks 数量是 CPU 核心线程数

在这里插入图片描述

再比如:

在这里插入图片描述
在这里插入图片描述

DataStream 编程模型

DataStream 编程模型

  • DataStream 的编程模型包括四个部分:Environment、DataSource、Transformation、Sink

在这里插入图片描述

Flink 的 DataSource 数据源

1. 基于文件
  • 使用 readTextFile(path) 读取文本文件,文件遵循 TextInputFormat 读取规则,逐行读取并返回。

在这里插入图片描述

2. 基于 Socket
  • 使用 socketTextStream 从socker中读取数据,元素可以通过一个分隔符切开。

在这里插入图片描述

3. 基于集合
  • 使用 fromCollection(Collection) 集合创建一个数据流,集合中的所有元素必须是相同类型的。
import org.apache.flink.streaming.api.scala.{
   
   DataStream, StreamExecutionEnvironment}
import org.apache.flink.api.scala._

/**
  * 基于数组或者集合构建DataStream
  */
object StreamSourceFromCollection {
   
   
  def main(args: Array[String]): Unit = {
   
   
    // 1. 获取流处理环境
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment

    // 2. 准备数据源--数组
    val array = Array("hello world","world spark","flink test","spark hive","test")
    val fromArray: DataStream[String] = env.fromCollection(array)

    // 3. 数据处理
    val resultDataStream: DataStream[(String, Int)] = fromArray
                .flatMap(x => x.split(" "))
                .map(x =>(x,1))
                .keyBy(0)
                .sum(1)
    // 4. 打印
    resultDataStream.print()

    // 5. 启动
    env.execute()
  }
}
4. 自定义输入
  • 使用 addSource 可以实现读取第三方数据源的数据
案例一:自定义单并行度数据源
  • source task 只有一个,通过继承 SourceFunction 来自定义单并行度 Source,代码实现如下:
import org.apache.flink.streaming.api.functions.source.SourceFunction
import org.apache.flink.streaming.api.scala.{
   
   DataStream, StreamExecutionEnvironment}
import org.apache.flink.api.scala._

object CustomSourceTest {
   
   
  def main(args: Array[String]): Unit = {
   
   
    val env: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment

    val getSource: DataStream[Long] = env.addSource
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值