目录
1:初识Flink
1.1 Flink是什么:
1.2 unbound/bound data:
1.3 API layered:
1.4 Flink运行环境多样化:
1.5 业界流处理框架对比:
1.6 使用案列:
1.7 发展趋势:
1.8如何高效学习Flink:
2 快速上手开发第一个Flink程序
3 编程模型核心及其概念
3.1 Flink编程模型:
3.2 DataSet/DataStream:
3.3 如何获取env:
3.4 延迟执行-懒加载:
3.5 (重点)指定数据的key:
3.6 指定transformation函数:如map()方法
3.7 (重要)Flink支持的数据类型:
4:DataSet API编程
4.1 DataSet的编程流程:
4.2 source编程
4.3 transformation编程
4.4 sink编程
4.5 计数器
4.6 缓存器
4.7 broadcast 变量
5 DataStream编程
5.1 source编程
5.2 自定义 Stream Source 编程:
5.3 transformations编程:
5.4 sink编程:和DataSet保存数据很类似
5.5 (重要)自定义sink编程:
6:Table API & SQL 编程:
6.1 什么是Flink关系型API?
6.2 Table API & SQL 编程开发:详情需要参考官网
7:Flink流处理中的Time及windows操作
7.1 (重要,流处理核心)Flink中的Time类型:
7.2 如何设置Time:
7.3 (重要,流处理核心)Flink中的Windows操作:
7.3 (重要)Flink中WaterMarks:
8:Flink Connectors
8.1 connectors 概述:
8.2 Hadoop FleSystem Connector编程
8.3 (重要)Kafka Connector source/sink编程:
9:Flink 部署以及作业提交
9.1 Flink源码编译:
9.2 Flink单机部署模式:
9.3 Standalone集群安装以及配置:
9.4 Flink ON Yarn模式运行Flink job:
9.5 Flink Scala Shell使用:
9.6 JobManager HA:
9.7 实战:将测试的流和批的作业打包到standalone以及yarn上运行
10:Flink监控以及Flink常用的调优策略
10.1 (重点)HistroyServer :
10.2 Monitoring REST API
10.3 Metrics:
10.4 (重点)Flink常见的优化:
11:Flink项目实战(重要)
11.1项目背景和需求:
11.2项目架构:
11.3 Mock数据到Kafka:
11.4 (统计1分钟内每个域名访问产生的流量)实战:
11.5 (统计1分钟内每个用户id产生的流量和)编程:
12.(重要、重要)Flink作业并行度设置:
12:Flink版本升级
12.1、Flink部署包如何升级:首先下载源码,然后编译对应hadoop版本的Flink
12.2、Flink应用程序升级
12.3、Flink是7*24小时运行,中间状态如何保存,升级后继续运行呢
13:Flink on yarn 常用参数详解
Apache Flink is a framework and distributed processing engine for stateful computations over unbounded and bounded data streams,Flink是运行在有界和无界数据流的分布式有状态的计算引擎
unbound data:有头无尾,流处理;bound data:有头有尾,批处理。都可以使用Flink来进行处理。
process function -》DataSet/DataStream-》SQL/Table
和Spark一样能在各种环境下运行
Spark Streaming:流处理是批处理的特列
Flink :真正的流式处理,能支持批处理
Strom :完全流式处理,已经过时了
事件驱动程序、数据分析程序、数据管道(ETL)
发展势头很强劲,尤其再阿里注入进去了。
1)官网、 2)源码描述
2.1 开发环境准备:JDK、Maven、Idea
2.2 词频统计App:DateSet API
2.3 窗口WCAPP:DataStream API
env -》add source-》transformations->add sink -》execute(批处理可以不用)
1)都是不可变的数据集合,只能转换为新的数据集合,和RDD类似。
2)批处理使用DataSet,流处理使用DataStream
通常使用StreamExecutionEnvironment.getExecutionEnvironment()就可以满足需求了。
和Spark一样transformation并不会真正的执行,当触发execute()时才会真正的会执行,好处Flink会根据执行计划优化计算
很多的聚合操作需要指定分组的key
1)批:groupBy方式指定key 流:keyBy指定key
2)对Tuple类型数据可通过keyby(index*)来指定哪个或那几个元素为key
3)对POJO类型数据可通过keyby(FieldName *)来指定哪个或那几个元素为key,即使POJO中包含了复杂的类型也是可以指定为key的
4) 当然也可以通过select function来指定,如keyby(_.fieldName)方式来指定key
1)用户可定义一个类实现MapFunction
2)用户可使用匿名内部类
3)用户可使用java8 Lambdas表达式取代匿名内部类
4)可以通过实现RichMapFunction来实现
1)Tuple 以及 scala 的case class:注意Tuple长度为25
2)Pojos:必须有无参的构造方法,私有的变量必须要提供get set方法
3)Primitive Types:基本数据类型
4)General Class Types:通用的数据类型,非PoJO,但是能够被序列化以及反序列化
5)values:值类型
6)Hadoop Writables:实现hadoop Writables接口的类
7)Special Types:特殊类型,如scala的Either、Option和Try
流和批的编程很类似,详细见DataStream API
Source -》 transformations -》 sink
1)、source:可从 fiels、collectios等读取数据
2)、sink:可将数据写入fiels、print等
一般都是基于kafka等消息队列读取数据进行编程的
和DataStream一样可以读取fiels、collectios生成流,也可以socket等中生成流
特殊点儿的是 union 流、split流、connect流
将socker中数据保存到Mysql数据库中,通过实现RichSinkFunction类来自定义Sink
它们是Flink的关系型API,架构在DataStream和DataSet API之上
1)使用SQL语句即能同时完成DataSet以及DataStream API的编程,不用去进行两套API的编程。
2)通过Table & SQL API,实现批流处理的统一。
3)注意:Table & SQL API很多功能还在积极开发中,并不是所有的操作都同时batch和stream。
1)StreamTableEnv 的sql查询,可以不指定窗口后进行聚合操作,每来一条数据就会聚合计算输出,输出的是update流
2)BatchTableEnvironment的sql查询结果是可以的,如 group by,暂时没有进行测试
生产中最多用的是事件时间作为流数据处理的基准
1)(重要)事件时间:数据产生的时间,由记录提供时间戳给Flink,Flink根据该时间戳进行处理但是当数据延迟超过一定时间,延迟数据是不会被处理的
2)摄入时间:数据进入Flink中的时间,无法解决乱序以及数据延迟问题
3)处理时间:数据被处理的时间,一个数据可能被处理多次,以该时间为基准处理数据,不一定准确的。
env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime),默认是proceesing time,设置为EventTime时 肯定要提供解析数据对应的时间字段的方法
Flink的窗口分为两大类别,第一类:TimeWindow(根据时间生成Window),第二类:Count Window(达到一定数量生成Window)
1)Keyed /Non_Key Windows :根据Stream是否指定了key,分为 Keyed Windows(keyBy)以及Non-Keyed Windows,(重要)有key的Window数据会根据key发送到不同分区,可并行处理数据,而无key的Window数据不会发送到不同的分区,即数据不会被并行的处理。
2)Window的生命周期:当归属于该Window第一数据进来时window即会被创建,当Time达到Window的结束时间+延迟时间后窗口被移除。同时窗口有触发器(何时执行)和处理函数(怎么处理)
3)Window Assigners:窗口分配器,定义将流中的数据如何的分配到一个或多个窗口中去,内置(可自定义窗口分配器)如下窗口分配器:
tumbling windows:(重要)滚动窗口,固定大小、窗口间无数据重叠,窗口一定有[start timestamp,end timestamp),时间戳
sliding windows:(重要)滑动窗口,窗口间可以有数据重叠,窗口一定有[start timestamp,end timestamp),时间戳
session windows:会话窗口,,窗口一定有[start timestamp,end timestamp),时间戳
global windows:全局窗口,
4)Window Functions:分为ReduceFunction, AggregateFunction, FoldFunction 、ProcessWindowFunction四种,前两种是通过数据增量来实现的所以效率最高最后者是在Buffer中存储所有的元素来实现后续的计算逻辑,效率最低的,但功能更加的强大。
5)Windows编程:如何设置Time的类型、使什么样的Window,如何编写Window Functions
Flink可以通过watermark机制结合window的操作,来处理一定范围内的乱序数据、以及延迟数据问题。
参考文章:https://blog.csdn.net/lmalds/article/details/52704170
1)通过Connnectors可以与第三方系统进行数据的读写。
2)内置了kafka、ES、hadoop FleSystem等常用的Connector
自带的FleSystem Connector并不是很好用,最好是自定义hdfs sink
1)搭建虚拟机、zookeeper、kafka环境
2)Kafka Connector sink编程
3)Kafka Connector source编程:可以指定从哪里进行消费,当未启用检查点Flink会自动提交offset到Kafka
4)checkpoint:当kafka版本大于等于1.0.0版本时,无论是生产者还是消费者,启用了checkpoint后都能够提供精准一次消费语义,当启用了checkpoint,offset不在是自动提交,而是在将做完检查点状态后的offset提交
开发和测试都是可以基于本机的idea进行编码,但是作业运行都是需要打jar包提交生产环境(yarn)的。
生产中应使用自己编译的Flink,设置编译对应的hadoop版本
1)环境准备:centos、jdk1.8、maven3.3.X
2)Flink源码:https://github.com/apache/flink/releases
3)FLink编译教程:https://ci.apache.org/projects/flink/flink-docs-release-1.8/flinkDev/building.html
4)编译命令:mvn clean install -DskipTests -Dfast -Pinclude-hadoop -Pvendor-repos -Dhadoop.version=2.6.0-cdh5.7.0
注意:我编译时遇到了jar无法下载的情况,将maven中的setting.xml中配置的阿里云仓库删除,然后在pom中配置阿里云镜像即可
编译后软件路径,是已经解压后的:~/flink-dist/target/flink-1.8.1-bin
我没设置(-Pinclude-hadoop)包括hadoop的包,导致on yarn缺少类,解决方案手动拷贝:将编译的源码包下的flink-shaded-hadoop/flink-shaded-hadoop2-uber/target/flink-shaded-hadoop2-uber-3.1.2-1.8.1.jar拷贝到$FLINK_HOME/lib/下即可
用于学习以及测试
1)启动单机(standalone)命令:./bin/start-cluster.sh
查看日志: tail log/flink-*-standalonesession-*.log
查看页面:http://hadoop001:8081
2)运行WC测试任务:启动socket:nc -lk 9099 ,运行作业:./bin/flink run examples/streaming/SocketWindowWordCount.jar --port 9099
查看页面作业:可查看作业状态以及使用资源(solt即类似于Spark的core,个数决定并行度)以及取消作业
查看测试任务结果:tail -f log/flink-*-taskexecutor-*.out
3) 停止Flink:./bin/stop-cluster.sh
企业用的不是很多,了解即可
参考https://ci.apache.org/projects/flink/flink-docs-release-1.8/ops/deployment/cluster_setup.html
1)要求: Java 1.8.x or higher,1到N台机器、配置ssh免密码通信
2)(重要)配置:
conf/flink-conf.yaml:常用配置如下
jobmanager.rpc.address master节点的地址,最好使用hostname
jobmanager.heap.mb jobmanager节点可用的内存
taskmanager.heap.mb taskmanager节点可用的内存
taskmanager.numberOfTaskSlots 每个机器可用的cpu个数
parallelism.default 任务默认的并行度,代码若指定会覆盖默认值
taskmanager.tmp.dirs taskmanager的临时数据存储目录
conf/slaves:从节点的配置信息,每一行配置一个ip/host
3)扩容或者取消jobManager/taskManager:
bin/jobmanager.sh ((start|start-foreground) [host] [webui-port])|stop|stop-all
bin/taskmanager.sh start|start-foreground|stop|stop-all
1)安装Hadoop集群:省略,可以是单节点
2)Flink on yarn的两种模式:
第一种:在Yarn运行一个长Flink yarn Session服务,该服务向yarn申请一定的资源,所有提交作业公用该session,这样会导致Flink之间作业可能因为session资源不够出现资源不够排队问题
第二种:每个提交的作业都会运行自己的Flink yarn Session服务,作业完成后注销。Flink作业间互不影响
3)Flink on Yarn 第一种模式实操:
第一步:启动Flink yarn Session服务长服务:
./bin/yarn-session.sh -n 1 -jm 1024m -tm 1024m
-n taskmanager(Container)的数量 -jm jobmanager的内存 -tm taskmanager的内存
此时可从yarn的界面上看到正在运行的任务,我启动报JDK版本冲突问题,可能是我的hadoop版本问题,暂时为有时间解决,最终发现我的hadoop的hadoop-env.site配置成了1.7,打脸
第二步:提交Flink作业:
下载测试数据:wget -O LICENSE-2.0.txt http://www.apache.org/licenses/LICENSE-2.0.txt
上传测试数据:hadoop fs -copyFromLocal LICENSE-2.0.txt hdfs:/// ...
运行提交作业脚本:./bin/flink run ./examples/batch/WordCount.jar \
-input hdfs://hadoop000:8020/LICENSE-2.0.txt \
-output hdfs://hadoop000:8020/wordcount-result.txt
页面观看:可在对应的Flink界面观看作业运行情况
4)Flink on Yarn 第二种模式实操(生产个人认为用的是它):
运行提交作业的脚本:./bin/flink run -m yarn-cluster -yn 1 ./examples/batch/WordCount.jar
5)Flink配置以及UI对应关系:
配置:https://ci.apache.org/projects/flink/flink-docs-release-1.8/ops/config.html
UI:要想知道Flink的配置重启后是否生效一定要从Web UI界面去观看
同spark-shell一样。Flinlk也提供shell界面方便测试以及开发代码
启动命令:./bin/start-scala-shell.sh local,当然也可以同Spark一样以local、yarn等方式去运行
当运行在yarn上时,JobManager(AM)挂了后,yarn会有自动重启的AM的策略。参考文档:https://ci.apache.org/projects/flink/flink-docs-release-1.8/ops/jobmanager_high_availability.html
首先和Spark一样,若不依赖外部的jar,直接package打瘦包即可,若依赖外部的jar,使用assembly+在pom中指定profile。pom中重复的核心包标记为provide,在本地测试时指定profile即可,其设置为compile,然后使用assembly进行打包。
1)批作业:
standalone集群运行:
第一步:启动单点集群:./bin/start-cluster.sh
第二步:提交作业 : ./bin/flink run -c com.wsk.flink.source.BatchSourceApp /home/hadoop/newdisk/job/flink-job/flink-train-1.0-SNAPSHOT-jar-with-dependencies.jar
yarn上运行:
第一步:提交作业:./bin/flink run -m yarn-cluster -yn 1 -c com.wsk.flink.source.BatchSourceApp /home/hadoop/newdisk/job/flink-job/flink-train-1.0-SNAPSHOT-jar-with-dependencies.jar
2)流作业:
standalone集群运行: 、
第一步:启动单点集群:./bin/start-cluster.sh
第二步:提交作业 : ./bin/flink run -c com.wsk.flink.streaming.SocketWindowWCApp /home/hadoop/newdisk/job/flink-job/flink-train-1.0-SNAPSHOT-jar-with-dependencies.jar
注意:作业的的print日志要从界面的 TaskManager的logou面版去查看,非常的奇怪
yarn集群运行:
第一步:提交作业:./bin/flink run -m yarn-cluster -yn 1 -c com.wsk.flink.streaming.SocketWindowWCApp /home/hadoop/newdisk/job/flink-job/flink-train-1.0-SNAPSHOT-jar-with-dependencies.jar
通过HistroyServer页面(同时提供REST API)我们可以看到已经结束的作业的信息,方便排查问题,以及调优
参考文档:https://ci.apache.org/projects/flink/flink-docs-release-1.8/monitoring/historyserver.html
1)Flink和MR、Spark作业都是有自己的history server进程的,生产中最好是开启他们。
2)启停命令:bin/historyserver.sh (start|start-foreground|stop),默认绑定在 localhost的 8082端口
3)相关配置:flink-conf.yaml的HistoryServer模块
web绑定的地址:historyserver.web.address: 0.0.0.0
web端口号:historyserver.web.port: 8082
刷新时间:historyserver.archive.fs.refresh-interval: 10000
jobmanager归档文件存放位置:jobmanager.archive.fs.dir: hdfs://hadoop001:9000/completed-jobs-wsk/
historyserver归档文件存放位置:historyserver.archive.fs.dir: hdfs://hadoop001:9000/completed-jobs-wsk/
4)启停命令:bin/historyserver.sh (start|start-foreground|stop)
测试:执行Flink on yarn 的测试案列:./bin/flink run -m yarn-cluster -yn 1 ./examples/batch/WordCount.jar ,可在History的web页面观看到完成job信息
5)HistroyServer API:HistroyServer同时提供Rest API,供查看相应信息
通过该API可以查看正在运行的作业以及最近运行完毕的作业的状态,偏平台监控用的比较多
参考文档:https://ci.apache.org/projects/flink/flink-docs-release-1.8/monitoring/rest_api.html
访问地址,同Flink的web界面一致。http://hadoop001:8081
通过指标系统我们可以看到很多很多的指标信息(CPU、JVM、Memory、线程、GC),同时还可以定义指标,最终供外部系统查询,Metrics可以通过Monitoring REST API被查询出来
常用的四种优化策略文章参考:https://dzone.com/articles/four-ways-to-optimize-your-flink-applications
1)配置: 资源:每个taskManager可用的solt数(taskmanager.numberOfTaskSlots)决定,以及配置JM和TM的内存
并行度:,任务默认并行度是1(parallelism.default), 需要适当的调整 ==》项目实战
2)on yarn 提交作业时资源如何的设置?需要适当的调整 ==>Flink on 的常见参数
3)数据倾斜如何处理?
单表group by:二次聚合、
join :广播小表、数据更具key重分区(大表和大表)、左表打散右表扩容
背景:接入的CDN日志数据,进行数据分析:离线:实时:Kafka=》流处理引擎=》ES=》Kibana,Flume =》HDFS =》Spark 批处理。
需求:1)统计1分钟内每个域名访问产生的流量 :Flink接收Kafka的数据
2)统计一分钟内每个用户产生的流量:Flink接收Kafka的数据+Flink从Mysql中读取域名和用户的配置数据(自定义数据源) 进行处理
数据:通过Mock模仿生成的
架构没有对错,只有是否合适。
生产数据=》Kafka=》Flink流式计算引擎(首先清洗数据,其次统计分析) ==》将结果存储ES ==》Kibana大屏展示
域名用户配置信息=》kafka=>参与Flink流式计算引擎的计算,
必须学会Mock,数据敏感、多团队协作
1)设置Kafka Source
2)(极度重要) map数据,解析字段,必须加try catch,剔除无用的列,对脏数据必须做处理、不然一定会出问题。
3)给流设置时间戳和水印:.assignTimestampsAndWatermarks(xxx),
使用的是周期性的处理数据可能无序的数据,且提取消息中某个字段作为时间戳。
注意基于时间的所有操作(windows)必须先指定时间戳。
4)给流设置keyby(域名)以及 1分钟的翻滚窗口
5)进行Window 计算编程:累加流量
6)安装ES以及Kibana
第一步:安装ES,编辑:vim config/elasticsearch.yml,将 network.host: 0.0.0.0,表示所有的服务都可以访问
第二步:启动ES: bin/elasticsearch -d (-d 表示后端运行),可在页面9200端口查看
第三步:安装Kibana:编辑 vim config/kibana.yml server.host: 192.168.175.135 elasticsearch.hosts: "http://192.168.175.135:9200"
第四部:启动Kibana:bin/kibana,在5601端口即可观看启动的Kibana界面
7)编程将计算结果写入 ES中,Flink有ES的Sink,比较方便
8)创建es的索引:
第一步:创建索引:curl -XPUT 'http://192.168.175.135:9200/cdn'
第二步:创建type:
curl -H "Content-Type: application/json" -XPOST 'http://192.168.175.135:9200/cdn/traffic/_mapping?pretty' -d '{
"traffic":{
"properties":{
"domain":{"type":"text"},
"traffics":{"type":"long"},
"time":{"type":"date","format": "yyyy-MM-dd HH:mm"}
}
}
}
'
第三步:(可选)删除索引:curl -XDELETE 'http://192.168.175.135:9200/cdn'
第四部:创建domain为类型为keyword的索引,keyword相较于text,能够被检索
curl -H "Content-Type: application/json" -XPOST 'http://192.168.175.135:9200/cdn/traffic/_mapping?pretty' -d '{
"traffic":{
"properties":{
"domain":{"type":"keyword"},
"traffics":{"type":"long"},
"time":{"type":"date","format": "yyyy-MM-dd HH:mm"}
}
}
}
'
9)运行程序将数据写入 es并Kibana展示:
第一步:启动程序,向es中些数据,只有有数据了,好像才能被Kibana发现
第二步:在Kibana界面中添加索引管理:Management->Index Management 可看到我们创建的索引,
在Management->Index Patterns中可添加我索引cdn的管理,然后选择file为time字段,next创建成功
第三步:查看数据,Discover->右上角,选择时间范围 ,即可查看到数据
问题:显示的Time时间与输入的不吻合(时区问题):Management-》Advanced Settings-》Timezone for date formatting 默认是浏览器的,我们选择 ETC/GMT 时区即可
第四步:表格展示数据:
Visualize->New Visualization->Data table ,选择表格-> Select Index ,选择 cdn这个索引->表格,默认是总条数,并不是我们需要的->add metrics ,选择 sum,列选traffic ,然后执行
这个表格展示 我没有展示出来,那个domian不知道为何不显示,导致我我无法添加域名,按理说我设置为 keyword应该是可以的啊
第五步:柱状图展示数据:同样配置表信息
10)将作业打包到yarn上运行:可以通过,--XXX value,指定传入作业的参数,键值对,提交yarn的作业。直接结束提交作业的脚本,flink作业可依旧在运行。通过web页面取消flink作业
作业会取消但是,yarn界面会一直显示作业不会结束,即作业在运行--可能是我的启动flink on的 模式不对吧!
./bin/flink run -m yarn-cluster -yn 1 -c com.wsk.flink.cdnproject.LogAnalysis /home/hadoop/newdisk/job/flink-job/flink-train-1.0-SNAPSHOT-jar-with-dependencies.jar --bootstrapServer 10.199.151.15:9092
需求分析:用户一个用户id对应多个域名,一对多关系,映射关系是一张Mysql表
解决方案:自定义Mysql source源,读取Mysql数据,生成流,与数据流进行connect生成connect流,然后进行flatmap算子获取相关的数据。
和Spark一样,spark的数据集的分区数决定作业的并行。Flink也是有自己的并行度概念,一个Flink程序由多个任务组成(source、transformation和 sink),每个任务都有自己的并行度。一个任务的并行度即为task数,一个solt只能运行一个任务的一个task,不同任务的task可共享一个solt。故为列不使得资源浪费,最好将Flink的最大并行度设置为小于等于solt个数。
1)算子层面:算子、source和sink的并行度可以通过调用 setParallelism()方法来指定
2)全局层面:执行作业的默认并行度可通过env.setParallelism()指定,此时算子、source和sink并行度默认都是该值(当然可自行设置并行度别写死),最好是外面传递进来。
3)客户端层面:提交作业如:./bin/flink run -p 10 WordCount-java.jar,-p 10,表示并行度为10
4)系统层面:flink-conf.yaml文件中的parallelism.defaul配置的是系统级别的作业并行度。默认是1
并行度优先级:api>env>p>file
standalone集群:每个flink节点都要升级
yarn:只要在提交作业的那台机器上Flink升级即可
只要更改pom文件中的flink.version即可
通过savepoint方式进行升级:https://ci.apache.org/projects/flink/flink-docs-release-1.8/ops/upgrading.html
Flink部署主要是on yarn的模式。可通过 flink --help 查看“Options for yarn-cluster mode:”的信息
如命令:flink run -m yarn-cluster -ys 8 -ynm myapp -yn 4 -yjm 1024 -ytm 4096 -d -c com.paultech.MyApp ./myapp.jar
-m :运行模式,这里使用yarn-cluster,即yarn集群模式。
-ys :slot个数。
-ynm :Yarn application的名字。
-p:指定flink程序的并行度
-yn :task manager 数量。
-yjm :job manager 的堆内存大小。
-ytm task manager 的堆内存大小。
-d :detach模式。可以运行任务后无需再控制台保持连接。即程序提交完毕退出客户端,不在打印作业进度等信息!
-c :指定jar包中class全名。