Flink入门
1. Flink执行流程
1.1 Standalone版本
1.用户提交任务给JobClient
2.JobClient发送任务给JobManager
3.JobManager返回提交成功
4.JobManager将任务分发给TaskManager执行
5.TaskManager汇报任务的执行状态给JobManager
6.任务执行结束JobManager返回执行结果给JobClient
1.2 On Yarn版本
1.Client上传Flink任务的jar包和配置到HDFS
2.Client向Yarn(ResourceManager)提交任务并申请资源
3.ResourceManager分配并启动ApplicationMaster并读取HDFS上的Flink任务配置信息
4.ApplicationMaster根据任务配置信息给Flink任务分配资源启动JobManager和TaskManager
5.JobManager将任务分发给TaskManager执行(TaskManager执行时需要去HDFS上读取任务jar包)
2. Flink角色
FlinkClient
主要职责:(类似Driver)
接收用户的提交的程序代码,然后创建DataFlow模型(类似于DAG),将DataFlow数据流提交给JobManager
JobManager
主要职责:(类似于Driver+Master)
负责整个Flink集群任务的调度和Flink内部资源的管理,包括调度计算任务task,管理Checkpoint....
TaskManager
主要职责:(类似于Worker/Executor)
负责具体的任务的执行
3. Flink Streaming DataFlow流式数据计算模型
3.1 DataFlow、Operator、Partition、SubTask、Parallelism
1.DataFlow: Flink执行的时候被映射成的一个数据模型,类似于Spark的DAG
2.Operator:Flink中的中间操作,类似于Spark中的RDD
3.Partition:DataFlow中包含的多个流分区,类似于Spark中的分区
4.SubTask:指的Flink中的最小的调度单位,Flink中一个分区上的一系列操作,类似于Spark中的task
5.Parallelism:Flink中subTask的并行度,类似于Spark中的并行度
3.2 Operator传递模式、Operator Chain
1.传递模式:
One-to-One:类似于Spark中的窄依赖
Redistributing:类似于Spark中的宽依赖
2.OperatorChain
多个One-To-One的Operator可以合并为一个OperatorChain(类似于Spark中的Stage)
3.3 TaskSlot And Slot Sharing
TaskSlot:任务槽
指的是TaskManager中可以同时运行的线程数(并行度),TaskSolt中跑Task
下面的图中每一个TaskManager中有3个TaskSolt,也就是说每个TaskManager可以并行执行3个线程!
也就是说可以通过执行TaskSlot的数量来控制Flink中TaskManager可以最多并行执行的任务的数量
Slot Sharing:槽共享
同一个Flink程序中的不同的Task中(指的阶段OperatorChain)的不同的SubTask可以共享TaskSlot
那么也就意味着:
如果有某一个TaskSlot中的SubTask执行完成了
该TaskSlot可以共享给其他的Task中的SubTask执行(前提是得属于同一个Flink任务)
4. Flink On Yarn 的两种模式
Session会话模式
1.启动yarn-session
/export/servers/flink/bin/yarn-session.sh -n 2 -tm 800 -s 1 -d
-n 2 表示申请两个TaskManager
-tm 800 表示每个TaskManager的内存
-s 1 表示申请的每个TaskManager中solts的数量
-d 表示后台方式运行在yarn上
2.在yarn上查看yarn-session的状态
http://192.168.1.101:8088/cluster
3.提交任务
/export/servers/flink/bin/flink run /export/servers/flink/examples/batch/WordCount.jar
4.停止yarn-session
yarn application -kill application_1576849337083_002
Job分离模式
1.直接使用flink run 运行大的flink作业,每个作业会自动单独启动一个yarn-session
/export/servers/flink/bin/flink run -m yarn-cluster -yn 2 -yjm 1024 -ytm 1024 /export/servers/flink/examples/batch/WordCount.jar
-m yarn-cluster表示将任务提交给yarn并每个作业单独启动yarn-session
-yn 2 表示申请的TaskManager数量
-yjm 1024 表示申请的JobManager的内存
-ytm 1024 表示申请的TaskManager的内存
5. 入门案例
import org.apache.flink.api.scala.ExecutionEnvironment
object WorldCount {
def main(args: Array[String]): Unit = {
//1.准备环境-env,注意导scala包
val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
//2.数据源-Source
//导入隐式转换,可以将本地集合/HDFS数据/本地文件数据...转为Flink的数据抽象-DataSet
import org.apache.flink.api.scala._
val linesDS: DataSet[String] = env.fromElements("Flink Spark Hadoop","Flink Spark","Flink")
//3.数据转换-Transformation
//每一行按照空格切分并压平
val wordDS: DataSet[String] = linesDS.flatMap(_.split(" "))
//每个单词记为1
val wordAndOneDS: DataSet[(String, Int)] = wordDS.map((_,1))
//分组
val groupedDS: GroupedDataSet[(String, Int)] = wordAndOneDS.groupBy(0)//0表示按照索引为0的元素即单词进行分组
//注意:聚合不支持key选择器函数,也就是不支持_._1,否则报错:Aggregate does not support grouping with KeySelector functions, yet.
//val groupedDS: GroupedDataSet[(String, Int)] = wordAndOneDS.groupBy(_._1)
//聚合
val result: AggregateDataSet[(String, Int)] = groupedDS.sum(1)//1表示按照索引为1的元素即数量进行聚合
// //4.数据输出-Sink
result.print()//print可以触发执行
//5.调用执行操作
// env.execute()//latest call to 'execute()', 'count()', 'collect()', or 'print()'
}
}
6.提交到Yarn
package cn.itcast.hello
import org.apache.flink.api.scala.ExecutionEnvironment
object WorldCount1 {
def main(args: Array[String]): Unit = {
//1.准备环境-env,注意导scala包
val env: ExecutionEnvironment = ExecutionEnvironment.getExecutionEnvironment
//2.数据源-Source
//导入隐式转换,可以将本地集合/HDFS数据/本地文件数据...转为Flink的数据抽象-DataSet
import org.apache.flink.api.scala._
val linesDS: DataSet[String] = env.fromElements("Flink Spark Hadoop","Flink Spark","Flink")
//3.数据转换-Transformation
//每一行按照空格切分并压平
val wordDS: DataSet[String] = linesDS.flatMap(_.split(" "))
//每个单词记为1
val wordAndOneDS: DataSet[(String, Int)] = wordDS.map((_,1))
//分组
val groupedDS: GroupedDataSet[(String, Int)] = wordAndOneDS.groupBy(0)//0表示按照索引为0的元素即单词进行分组
//注意:聚合不支持key选择器函数,也就是不支持_._1,否则报错:Aggregate does not support grouping with KeySelector functions, yet.
//val groupedDS: GroupedDataSet[(String, Int)] = wordAndOneDS.groupBy(_._1)
//聚合
val result: AggregateDataSet[(String, Int)] = groupedDS.sum(1)//1表示按照索引为1的元素即数量进行聚合
//4.数据输出-Sink
//result.print()//print可以触发执行
System.setProperty("HADOOP_USER_NAME","root")//避免HDFS文件写入权限问题
result.setParallelism(1)//设置并行度为1,等一下生成的文件就1个
result.writeAsText("hdfs://node01:9000/wordcount/output_flink_yarn")
//5.调用执行操作
env.execute()//latest call to 'execute()', 'count()', 'collect()', or 'print()'
}
}
/export/servers/flink/bin/flink run -m yarn-cluster -yn 2 -yjm 1024 -ytm 1024 -c cn.itcast.hello.WordCount1 /root/wc.jar