目录
1.初识Flink
1.1flink是什么
Flink是分布式、高性能的处理引擎,用于对无界和有界数据流进行有状态的计算。
1.2为什么要选择flink
流数据更加真实的反应了我们的生活方式,传统的数据架构都是基于有限数据集的。flink处理数据低延迟,高吞吐,来一条处理一条,并且支持精确一次性。
1.3flink特点
1.3.1事件驱动
数据来一个处理一个,保存状态。
1.3.2分层api
1
1.3.3 无界和有界数据流
flink认为一切数据都是流式数据,批处理是一种特殊的流
无界数据流:无界数据流有一个开始但是没有结束,它们不会在生成时终止并提供数据,必须连续处理无界流,也就是说必须在获取后立即处理event。对于无界数据流我们无法等待所有数据都到达,因为输入是无界的,并且在任何时间点都不会完成。处理无界数据通常要求以特定顺序(例如事件发生的顺序)获取event,以便能够推断结果完整性。
有界数据流:有界数据流有明确定义的开始和结束,可以在执行任何计算之前通过获取所有数据来处理有界流,处理有界流不需要有序获取,因为可以始终对有界数据集进行排序,有界流的处理也称为批处理。
1.3.4 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.lw</groupId>
<artifactId>flin2k</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-scala_2.11</artifactId>
<version>1.10.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.flink/flink-streaming-scala -->
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-streaming-scala_2.11</artifactId>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-connector-kafka-0.11_2.11</artifactId>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-common</artifactId>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-api-scala-bridge_2.11</artifactId>
<version>1.10.0</version>
</dependency>
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-table-planner_2.11</artifactId>
<version>1.10.0</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>
</goals>
</execution>
</executions>
</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>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
2.1 wordcount 批处理
package com.lw.wc
import org.apache.flink.api.scala._
object wc {
def main(args: Array[String]): Unit = {
//1.创建一个执行环境
val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
//2.读取数据
val lists = List("me thanks you hello ab test sou","test thanks you")
//3.创建dataset
val words: DataSet[String] = env.fromCollection(lists)
//4.统计
//4.1flatMap将数据按照空格切割,然后扁平化
//4.2 map映射为二元组(hello,1)
//4.3 groupBy(0) 按照第一个属性分组
//4.4sum(1) 分组之后按照第二个属性求和
words.flatMap(_.split(" ")).map((_,1)).groupBy(0).sum(1).print()
}
}
输出结果:
(thanks,2)
(me,1)
(sou,1)
(test,2)
(ab,1)
(you,2)
(,1)
(hello,1)
2.2流处理
package com.lw.wc
import org.apache.flink.api.common.functions.Partitioner
import org.apache.flink.api.java.utils.ParameterTool
import org.apache.flink.api.scala._
import org.apache.flink.streaming.api.scala.{DataStream, StreamExecutionEnvironment}
object WordCountStream {
def main(args: Array[String]): Unit = {
//1.创建一个执行环境
val streamEnv: StreamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment
//2.source。读取数据
val words: DataStream[String] = streamEnv.fromCollection( List("hello thanks you","520 520","abc abc"))
//3.transformation 转换操作
val wcDataStream: DataStream[(String, Int)] = words.flatMap(_.split(" ")).map((_, 1)).keyBy(0).sum(1)
//4.sink。输出。
wcDataStream.print()
//5.启动程序
streamEnv.execute()
}
}
输出结果
(thanks,2)
(me,1)
(sou,1)
(test,2)
(ab,1)
(you,2)
(,1)
(hello,1)
3.flink部署
3.1下载flink
3.2standalone 模式部署flink
3.2.1部署flink
1)解压flink tar zxvf flink-1.10.0-bin-scala_2.11.tgz
2)进入conf目录
a.修改 flink/conf/flink-conf.yaml 文件:
b.修改slave文件
c:分发给其他机器
hadoop103
hadoop104
d:启动集群
bin/start-cluster.sh
e:访问web界面
3.2.2提交任务
1) 打包wordcount
2)提交任务 bin/flink run -c com.lw.wc.WordCountStream -p 2 job/flin2k-1.0-SNAPSHOT-jar-with-dependencies.jar
3)运行结果
3.3 yarn模式
Flink提供了两种在yarn上运行的模式,分别为Session-Cluster和Per-Job-Cluster模式。
3.3.1 Session-cluster 模式:
Session-Cluster模式需要先启动集群,然后再提交作业,接着会向yarn申请一块空间后,资源永远保持不变。如果资源满了,下一个作业就无法提交,只能等到yarn中的其中一个作业执行完成后,释放了资源,下个作业才会正常提交。所有作业共享Dispatcher和ResourceManager;共享资源;适合规模小执行时间短的作业。
在yarn中初始化一个flink集群,开辟指定的资源,以后提交任务都向这里提交。这个flink集群会常驻在yarn集群中,除非手工停止。
命令运行方式:
a.启动yarn-session
bin/yarn-session.sh -n 2 -s 2 -jm 1024 -tm 1024 -nm test -d |
其中:
-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:后台执行。
执行任务
./flink run -c com.atguigu.wc.StreamWordCount FlinkTutorial-1.0-SNAPSHOT-jar-with-dependencies.jar |
3.3.2Per-Job-Cluster 模式:
一个Job会对应一个集群,每提交一个作业会根据自身的情况,都会单独向yarn申请资源,直到作业执行完成,一个作业的失败与否并不会影响下一个作业的正常提交和运行。独享Dispatcher和ResourceManager,按需接受资源申请;适合规模大长时间运行的作业。
每次提交都会创建一个新的flink集群,任务之间互相独立,互不影响,方便管理。任务执行完成之后创建的集群也会消失。
提交命令
bin/flink run -m yarn-cluster -ys 4 -yjm 1024 -ytm 1024 -p 2 -c com.lw.wc.KafkaWc job/flin2k-1.0-SNAPSHOTar-with-dependencies.jar
-ys: 插槽数
-yjm:jobmanager的堆内存
-ytm: taskmanager的堆内存
4.Flink运行时架构
Flink运行时主要是以下四个组件
- jobManager
jobmanager是一个控制应用程序的进程,每一个flink application都会被一个jobmanager控制。jobmanager会接受到要执行的应用程序,这个程序包括,作业图、逻辑视图流和打包了所有的类库已经jar包。jobmanager会把jobGraph转换成一个屋里层面的数据流图,这个图叫做执行图。包含了所有可以并发的任务。jobmanager会向resourcemanager请求任务必要的资源,也就是taskmanager上的插槽,一旦获取了到了足够的资源,就会将执行图分发到对应的taskmanager上。taskmanager来执行任务。在运行过程中。jobmanager会负责所有的中央协调操作,比如说检查点的协调
- resourceManager
主要负责管理任务管理器(TaskManager)的插槽(slot),TaskManger插槽是Flink中定义的处理资源单元。Flink为不同的环境和资源管理工具提供了不同资源管理器,比如YARN、Mesos、K8s,以及standalone部署。当JobManager申请插槽资源时,ResourceManager会将有空闲插槽的TaskManager分配给JobManager。如果ResourceManager没有足够的插槽来满足JobManager的请求,它还可以向资源提供平台发起会话,以提供启动TaskManager进程的容器。另外,ResourceManager还负责终止空闲的TaskManager,释放计算资源。
- taskManager
Flink中的工作进程。通常在Flink中会有多个TaskManager运行,每一个TaskManager都包含了一定数量的插槽(slots)。插槽的数量限制了TaskManager能够执行的任务数量。启动之后,TaskManager会向资源管理器注册它的插槽(告知资源管理器他有多少个插槽);收到资源管理器的指令后,TaskManager就会将一个或者多个插槽提供给JobManager调用。JobManager就可以向插槽分配任务(tasks)来执行了。在执行过程中,一个TaskManager可以跟其它运行同一应用程序的TaskManager交换数据。
- dispatcher
负责接受任务,将任务转交给jobmanager