经过WordCount来入门Flink,读懂Flink基础架构,Flink学习入门(一)

你们好,我是后来,我会分享我在学习和工做中遇到的点滴,但愿有机会个人某篇文章可以对你有所帮助,全部的文章都会在公众号首发,欢迎你们关注个人公众号" 后来X大数据 ",感谢你的支持与承认。

前几天写的计算机网络的网络层在csdn阅读量快破5000了,也给我带来了很多的粉丝,仍是很是开心的,给了我写文很大的动力。在这里看一下:[
警察叔叔顺着网线是怎么找到你的?计算机网络(四)之网络层未完待续](https://editor.csdn.net/md/?a...java

最近公司愈来愈多的业务要用到Flink,我也正好把知识点再复习下,作到学以至用,哈哈,并且前几天看到Flink1.11版本都开始支持hive流处理了,仍是比较兴奋的。由于本身关于Flink的经验也不是不少,因此我就再以小白的身份写个Flink学习专栏。各位大佬不喜勿喷。linux

写完基本知识,也会夹杂着工做实例,算是给本身作个笔记。但愿某篇文章能对你有所帮助。
强烈建议:阅读官网!
我学习一个新技术的步骤大概是这样的:web

  1. 先了解这个技术要解决什么问题
  2. 简单上手体验一下,找找自信心
  3. 学习架构,知晓原理
  4. 学习API,体验高级玩法
  5. 搞个小项目上手,学以至用。

一、Flink大体介绍

关于实时处理与离线处理,一个很大的不一样就在于,数据是否是有界的。apache

  1. 有界流:数据有终点,好比要对一个txt文本作wordCount。
  2. 无界流:数据有起点,没有终点,好比说是从socket 端口拿数据计算wordCount,能够无休止的产生数据。

而在实时处理方面,又有Flink和Spark Streaming,那么他俩最大的区别就是Flink是真正的流处理,而spark Streaming是微批次处理。编程

  1. Flink能够以事件为单位,来一条数据就处理一条(能够,不是只能,flink也能够 以时间窗口为单位进行计算,你们不要误解)
  2. Spark Streaming是以一个窗口为单位,一次处理一批

固然flink也能够擅长作批处理,只不过如今flink表明的更多的是实时处理。api

1.1 Flink的组件栈有哪些?

在这里插入图片描述
这些组件能够先大概知道有这么回事,而后后续的学习中一点点理解就记住了。
图中也能知道:缓存

  1. 运行模式大体分为3种,本地、集群、云
  2. DataStream API流处理
  3. DataSet API批处理
  4. 上层还支持CEP、SQL、机器学习ML、图计算。

二、Flink初体验

仍是先在IDE中来一个WordCount吧。这个先直接复制了,跑起来咱们再来分析其中的东西。
这个代码是scala代码写的,关于建项目和导入scala框架这个你们百度吧。bash

import org.apache.Flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
import org.apache.Flink.streaming.api.scala._

/**
  * @description: WordCount小入门
  * @author: Liu Jun Jun
  * @create: 2020-06-04 10:10
  **/
object WordCount {
  def main(args: Array[String]): Unit = {
  //获取环境
    val env = StreamExecutionEnvironment.getExecutionEnvironment
//从客户端获取流式数据
    val wordDS: DataStream[String] = env.socketTextStream("bigdata101",3456)
//对数据进行转换,按照单词分组,最后求和
    val resultDS = wordDS.map((_,1)).keyBy(_._1).sum(1)
//对结果进行打印
    resultDS.print("ceshi:")
//真正的执行命令,前面这些都是懒加载的,只有在遇到execute才会触发执行
    env.execute("wordCount")
  }

}

测试——在linux系统中用netcat命令进行发送测试。没有nc 的能够安装一下
(yum -y install nc)
nc -lk 3456
而后本身写点单词,控制台看输出结果:
结果展现:
在这里插入图片描述
在这个测试案例中,咱们已经体验到了Flink的流式处理。
结果展现中,前面的数字表明的当前这个任务跑在个人哪一个cpu上,我这个电脑是4个cpu,默认使用所有资源,因此它本身选择执行。固然你会发现later这个单词总在cpu4上。微信

好了,那就继续往下走,咱们刚只是在IDE中体验了一把,可是咱们实际生产中仍是要打包放在集群上跑的。网络

那么接下里咱们在集群上部署一下Flink

三、Flink安装

说到Flink的集群安装,就有几种模式。本地模式通常也就是自学用,因此这里就暂时不安装了。来看看集群部署。

  1. Standalone模式:这种模式下的Flink使用本身的资源管理及任务调度,不依赖于hadoop,目前使用的不是不少。
  2. yarn模式:这种模式的话,Flink更像是一个客户端,作了一个计算引擎,把任务提交到yarn,由yarn来进行资源的分配以及任务的调度。但计算使用的是Flink引擎。使用的比较多。

以上两种方式,根据公司需求不一样选择不一样。我在这里主要讲一下yarn模式
根据官网介绍:
若是你计划将 Apache Flink 与 Apache Hadoop 一块儿使用(在 YARN 上运行 Flink ,链接到 HDFS ,链接到 HBase 等),则须要下载好Flink后,把hadoop组件放在Flink的lib目录下,这个在官网有说明,若是官网没提供你的hadoop版本,那就须要本身编译了。
在这里插入图片描述
**我这里直接提供一个Flink1.7.2版本集成好hadoop依赖的包,直接解压部署就能够了。
解压值须要配置web页面地址,固然不配置跑任务也没有问题。 连接在个人微信公众号【后来X大数据】,回复”flink“就能够直接下载。**

yarn模式也有2种类型:

  1. Session-Cluster

在这里插入图片描述
这种模式就是在启动hadoop集群后,先申请一块空间,也就是启动yarn-session,之后全部提交的任务都在这块空间内执行。至关因而承包商。不以下面的方式灵活。

  1. Per-Job-Cluster

在这里插入图片描述
这个则是每次提交一个Flink任务,都会单独的只申请本身所须要的空间,组成flink集群,任务执行完就注销掉。任务之间互相独立,互不影响,方便管理。

很明显,第二种方式对资源的利用更加灵活。

那么接下来咱们提交个任务看看。咱们就用官方的WordCount测试包吧。本身写个文件,里面随便写点单词。

bin/flink run -m yarn-cluster -yn 7 -ys 2 -p 14  -ytm 2048m -yjm 2048m  -yqu Flink ./examples/batch/WordCount.jar --input /opt/wc.txt --output /opt/output4/

bin/Flink 后面其实能够指定不少参数,你们能够bin/Flink --help查看一下
-m 指定任务运行模式
-yqu 指定提交任务的队列
-n(--container):TaskManager的数量。
-s(--slots): 每一个TaskManager的slot数量,默认一个slot一个core,默认每一个taskmanager的slot的个数为1,有时能够多一些taskmanager,作冗余。
-jm:JobManager的内存(单位MB)。
-tm:每一个taskmanager的内存(单位MB)。
-nm:yarn 的appName(如今yarn的ui上的名字)。
-d:后台执行。

那一看命令这么多参数,那咱们平时怎么提交任务就会方便一些呢?通常状况下咱们写成脚本执行。

提交任务后能够在yarn上看到这个任务,经过Application,能够进入webUI页面,咱们能够看到这个任务的流程图。(这个图我完了补上,写文的电脑上没装集群)

四、Flink架构

经过上述的介绍,其实对Flink已经有了初步的认识。那咱们来初步理解一下Flink的架构,前期只须要大体理解就能够了,更多的理解仍是要基于使用,毕竟实践出真知!

4.1 Flink在运行时会包含这几种主要的角色:

  1. Job Managers:提交的这个任务的老大,管理Flink集群中从节点TaskManager
  2. Task Managers:单个任务的管理者,负责管理其所在节点上的资源信息,如内存、磁盘、网络,在启动的时候将资源的状态向JobManager汇报
  3. Resource Manager:集群资源的管理者
  4. Clients:提交做业的机器

上面提到的是任务在运行中有哪些具体的角色,那么广义上来讲,Flink在这里充当的角色更多的是一个客户端,用来提交job。

4.2Flink on yarn时,提交任务的流程就以下图所示:

在这里插入图片描述

  1. Flink提交后,Client向HDFS上传Flink的Jar包和配置
  2. Client给RM提交任务
  3. RM分配资源并通知选中的对应的NodeManager,启动ApplicationMaster来做为这个任务全部资源的老大,进行管理。
  4. ApplicationMaster启动后加载Flink的Jar包和配置构建环境,而后启动JobManager
  5. AM向RM申请资源启动TaskManager,AM分配资源之后,AM就通知资源所在的节点的NodeManager启动TaskManager
  6. NodeManager加载Flink的Jar包和配置构建环境并启动TaskManager,TaskManager启动后向JobManager发送心跳包,并等待JobManager向其分配任务。

4.3那么Flink任务是怎么资源调度的?

咱们来跟着官网的思路走一下:

  1. 咱们的每个TaskManager都是一个JVM进程,这么理解吧,TaskManager启动在NodeManager所在的节点,就等于说是一个节点一个TaskManager。
  2. 这个JVM进程能够在不一样的线程中执行一个或多个 subtasks(子任务),那确定啊,一个节点同时执行不少个子任务。可是同时执行的子任务过多,是否是会抢占资源比较严重,那么几个会比较合理呢?
  3. 在Flink中有个插槽的概念,slot: TaskManager 的一份固定资源子集。目前仅仅用来隔离task的内存,例如,具备三个 slots 的 TaskManager 会将其管理的内存资源分红三等份给每一个 slot。这样作的好处就是划分到不一样slot的子任务集不会再抢占别的slot资源。
  4. 可是问题是:这样也不公平,好比2个须要资源相差很大的子任务划分到了不一样的slot中,会出现须要资源小的任务早就跑完了,而另外一个须要资源多的任务却迟迟跑不完。因此,Flink 容许 subtasks 共享 slots,即便它们是不一样 tasks 的 subtasks,只要它们来自同一个 job。这样的好处是:

(1)须要资源少的子任务能够划分到一个slot,而须要资源多的能够单独划分到一个slot,能够充分利用slot资源,同时确保繁重的 subtask 在 TaskManagers 之间公平地获取资源。
(2)Flink 的并行度只要控制好合理的slot数就能够了,由于每一个slot都是一个线程。这样不须要计算做业总共包含多少个 tasks。
在这里插入图片描述
根据经验,合理的 slots 数量应该和 CPU 核数相同。这个在实际的工做中,应在是看给本身分到的队列的资源一共是多少,而本身预估这个任务大概须要多少资源,而后合理的设置slots数,也就是合理的设置并行度。

4.4 Flink的Slot和parallelism有什么区别?

注意:

  1. Task Slot是静态的概念,是指TaskManager 具备的并发执行能力 ,能够经过参数taskmanager.numberOfTaskSlots进行配置;
  2. 而并行度parallelism是动态概念,即TaskManager运行程序时实际使用的并发能力,能够经过参数parallelism.default进行配置。

这么举例子吧,咱们提交一个job,就有了一个JobManger,那么经过资源的分配,假如如今在3个节点上执行任务,那就等于说有3个TaskManager,假如每个TaskManager都包含了必定数量的插槽(slots)。插槽的数量限制了TaskManager可以执行的任务数量。这里假设每一个TaskManager能够接收3个task,一共9个TaskSlot,若是咱们设置parallelism.default=1,即运行程序默认的并行度为1,9个TaskSlot只用了1个,有8个空闲,所以,设置合适的并行度才能提升效率。

4.5 Flink的并行度是什么?怎么设置才算是合理呢?

算子的并行度: 一个特定算子的子任务(subtask)的个数被称之为其并行度(parallelism)。一个程序中,不一样的算子可能具备不一样的并行度。
那么具体的每一个算子的并行度是多少这个咱们后面具体说算子的时候再来说,这里先大体介绍一下:

  1. One-to-one,相似于spark的窄依赖,好比map、filter等
  2. 一对多,相似于spark的宽依赖。

相同并行度的one to one操做,Flink这样相连的算子连接在一块儿造成一个task,原来的算子成为里面的一部分。将算子连接成task是很是有效的优化:它能减小线程之间的切换和基于缓存区的数据交换,在减小时延的同时提高吞吐量。

任务链必须知足两个条件:one-to-one的数据传输而且并行度相同
job的并行度:任务被分为多个并行任务来执行,其中每一个并行的实例处理一部分数据。这些并行实例的数量被称为并行度。

咱们在实际生产环境中能够从四个不一样层面设置并行度:(具体代码体如今后续写)
操做算子层面(Operator Level)
执行环境层面(Execution Environment Level)
客户端层面(Client Level)
系统层面(System Level)
须要注意的优先级:算子层面>环境层面>客户端层面>系统层面。

4.6 Flink的基础编程模型

咱们在上述wordCount的代码中,就发现数据流由3部分组成,数据源source,数据转换,数据最后的流出sink 3部分组成。那么这其实也是咱们代码的主要构成,经过合适的转换算子将数据源的数据进行处理,最后把结果经过sink的方式输出到别的地方。
每个dataflow以一个或多个sources开始以一个或多个sinks结束。
在这里插入图片描述
Flink 将算子的子任务连接成 task。每一个 task 由一个线程执行。把算子连接成 tasks 可以减小线程间切换和缓冲的开销,在下降延迟的同时提升了总体吞吐量。

4.7 Flink的流程图有哪些?

那么上述的数据流直接映射成的数据流图是StreamGraph,也被称为逻辑流图,由于它们表示的是计算逻辑的高级视图。为了执行一个流处理程序,Flink须要将逻辑流图转换为物理数据流图(也叫执行图),详细说明程序的执行方式。
Flink 中的执行图能够分红四层:StreamGraph -> JobGraph -> ExecutionGraph -> 物理执行图。

  1. StreamGraph:是根据用户经过 Stream API 编写的代码生成的最初的图。用来表示程序的拓扑结构。
  2. JobGraph:StreamGraph通过优化后生成了 JobGraph,提交给 JobManager 的数据结构。主要的优化为,将多个符合条件的节点 chain 在一块儿做为一个节点,这样能够减小数据在节点之间流动所须要的序列化/反序列化/传输消耗。
  3. ExecutionGraph:JobManager 根据 JobGraph 生成ExecutionGraph。ExecutionGraph是JobGraph的并行化版本,是调度层最核心的数据结构。
  4. 物理执行图:JobManager 根据 ExecutionGraph 对 Job 进行调度后,在各个TaskManager 上部署 Task 后造成的“图”,并非一个具体的数据结构。

这几个类在源码中也能找到。

关于Flink比较基础的框架概念已经了解的差很少了,部份内容也来源于官网中文翻译。
可能有些概念还没理解透彻,不过不要紧,在接下来的应用中,使用的多了就会有不同的收获,指望经过一篇文章或者只看官网的介绍理解透彻是不存在的,毕竟这框架是众多大牛汇集在一块儿搞了不少年才搞出来的,咱们只不过是个框架的使用者,约等于搬砖工。

因此我写的内容也欢迎你们前来讨论。

那么下一篇Flink的文章我来继续学习关于Flink的API。期待能和你一块儿学习!

扫码关注”后来X大数据“,回复【电子书】,领取【超多本pdf java及大数据 电子书】

在这里插入图片描述

相关文章
相关标签/搜索