第三次学flink

第一问Flink为何而出现

人们想要高吞吐,低延迟处理数据,以前的storm只能低延迟,做不到高吞吐,spark Streaming可以高吞吐,但是更多的场景是要根据事件数据切割,或者说要实现比较复杂。

在这里插入图片描述

deploy 部署,可以单机,基于yarn,基于云

core 分布式数据流处理

CEP 就是复杂事件处理,一般就是比如说一条流中的两个数据有关联才用到。

Flink 的分布式特点体现在它能够在成百上千台机器上运行,它将大型的计算

任务分成许多小的部分,每个机器执行一部分

第二问基本架构

TaskManager JobManager 都第三次了不再细说

在数据流方面 spark 面对批处理和流处理是两套框架 flink则是全是流(把批当成流的一种特殊形式)

任务提交流程yarn

在这里插入图片描述

slot与taskManager的关系

我的非官方理解:第一,slot相当于是把taskManager分成了多分,比如说,当把map算子的并行度设置成2时,那么就有两个slot中包含该算子,第二,每一个taskManager是一个JVM进程,但是taskManager有时会有多个,这是因为你的slot设置数量小于你设置的最大并行度的数量, 即taskManager的数量是Job的最大并行度除以每个TaskManager分配的任务槽数。

在这里插入图片描述

Graph各种图

在这里插入图片描述

第三问flink操作

执行环境

StreamExecutionEnvironment.getExecutionEnvironment
创建一个执行环境,表示当前执行程序的上下文。 如果程序是独立调用的,则
此方法返回本地执行环境;如果从命令行客户端调用程序以提交到集群,则此方法
返回此集群的执行环境,也就是说,getExecutionEnvironment 会根据查询运行的方
式决定返回什么样的运行环境,是最常用的一种创建执行环境的方式。
StreamExecutionEnvironment.createLocalEnvironment
StreamExecutionEnvironment.createRemoteEnvironment
返回集群执行环境,将 Jar 提交到远程服务器。需要在调用时指定 JobManager
的 IP 和端口号,并指定要在集群中运行的 Jar 包。

source

readTextFile(path)
readFile(fileInputFormat, path)

env.socketTextStream(“localhost”, 11111)

env.fromCollection(list)

env.fromCollection(iterator)

env.fromElement(对象)

transformation

map filter 简单的不再说

//KeyBY
		KeyStream<类,tuple> a=data.keyBy("id")
		KeyStream<类,T> a=data.keyBy(data->data.getId)
		KeyStream<类,T> a=data.keyBy(::getId)
//max
	DataStream<> resultStream=a.max("temperature");
	//maxBy 和max的区别就是maxBy返回的值带着该数据的全部值,而max除了那个求最大那个数据,其他数据都是流中接收的第一个数据

reduce向这种需要有界的进行聚和必修要先聚合,group by key by 这两个先聚合,至于这两个有啥区别,俺也不太清楚,用的时候group by针对的是DataSet ,keyBy针对的是DataStream在这里插入图片描述分流:filter , split(过期,不建议),outputTag;

聚合流:Connect(只能连接两条流,但流的类型可以不一样ConnectedStreams会对两个流的数据应用不同的处理方法,且双流之间可以共享状态。connect经常被应用在对一个数据流使用另外一个流进行控制处理的场景上。)
connect如何用呢?先把他们都放到connect,然后再开始通过其他算子进行合并操作。
在这里插入图片描述
union(可连接多条流,但是流的类型必须一样)

滚动聚合算子 sum min max minBy maxBy

时间
Processsing,IngestionTime,EventTime
第一个,过程 就是说到达算子的时间,也是flink默认时间
第二个,摄取时间 就是说到达source的时间
第三个,事件时间,一般在数据流中包含,这个时间是自己定义的呢。
在这里插入图片描述

window api

1滚动窗口
简单的用法就不说了
“windowAll(TumblingProcessingTimeWindows.of(Time.seconds(5), Time.seconds(2) ))”
正常情况下,滚动只传一个参数,但是这个却传入了两个参数,第二个参数表示的偏移量
举个例子,拿上面那个数据简单来说首先要知道,0,5,10,15…60,0,5 flink是在这些整秒进行关窗操作,即使你是从第三秒开始计时,那么第一次关窗也就是第五秒。但是当你设置第二个参数的话,那么就是从2,7,12开始关窗。
所以是不是觉得这个参数大部分呢情况下没有卵用,但是这个官方说了
input
.keyBy()
.window(TumblingEventTimeWindows.of(Time.days(1), Time.hours(-8)))
.();
在这里插入图片描述
2滑动窗口
3会话窗口
4全局窗口
计数窗口(.countWindow(10,2))10个数统计一次,划动两个,再统计一次。
窗口函数
增量聚合函数(ReduceFunction)AggregateFunction和reduceFunction区别是,他这个里边可以传个累加器。
全窗口函数
先把所有窗口函数数据收集起来,等到计算的时候会遍历所有的数据

processWindowFunction
WindowFunction
apply
.trigger()触发器
.evictor移除器
.allowedLateness允许处理迟到的数据
.sideOutputLateData将迟到的数据放入测输出流
.getSideOutput获取侧输出流。

watermark水位线
针对于事件时间
如何传递的呢?
上游广播给下游,

在这里插入图片描述
简单来说,每个算子有多个分区,然后有个partitionWM用来保存水位线,每到一个水位线,就判断是否广播,然后每次广播的是最小的水位线。广播过的不再广播。

在这里插入图片描述第一个就不用说了,常用的,就是来一个数据,这个数据带着watermark;
第二个周期性,等于说是过一定的时间,生成个watermark;
第三个是断点式,就是来个数据,我判断一下是不是要生成watermark;

状态:干啥子?
1 数据流中的数据有重复,想对重复数据去重,需要记录哪些数据已经流入过应用,当新数据流入时,根据已流入过的数据来判断去重。
2 检查输入流是否符合某个特定的模式,需要将之前流入的元素以状态的形式缓存下来。比如,判断一个温度传感器数据流中的温度是否在持续上升。
3 对一个时间窗口内的数据进行聚合分析,分析一个小时内某项指标的75分位或99分位的数值。

在这里插入图片描述
托管状态(Managed State)和原生状态(Raw State)。从名称中也能读出两者的区别:Managed State是由Flink管理的,Flink帮忙存储、恢复和优化,Raw State是开发者自己管理的,需要自己序列化。
我的理解:本来你运行这个项目并行度3,现在重启了,设置并行度为4,Managed就自己把状态搞好了,不用你考虑传输和分配问题,所以平时用ManagedState就行了,row别用,用了也不会。
在这里插入图片描述
在之前各算子的介绍中曾提到,为了自定义Flink的算子,我们可以重写Rich Function接口类,比如RichFlatMapFunction。使用Keyed State时,我们也可以通过重写Rich Function接口类,在里面创建和访问状态。对于Operator State,我们还需进一步实现CheckpointedFunction接口。

在这里插入图片描述
算子状态的存储 Liststate(列表状态) unionListState(联合列表状态) BroadcastState(广播状态)
区别:比如说两个分区 ,然后重启后设置为3个分区,那么这些状态该怎么从两个分区给三个分区呢? liststate 是先一一对应后把多出来的放到第三个分区里,unionListState是把这几个分区的算子状态合并到一块,然后都发给三个分区,然后这三个分区分别取他们需要的。

在这里插入图片描述各个例子博客:https://blog.csdn.net/gym02/article/details/105755814

键控算子例子 valuestate例子
总结
1 open里定义state Descriptor
2 flatmap实现更新

public class CountWindowAverage extends RichFlatMapFunction<Tuple2<Long, Long>, Tuple2<Long, Long>> {
 
    /**
     * ValueState状态句柄. 第一个值为count,第二个值为sum。
     */
    private transient ValueState<Tuple2<Long, Long>> sum;   
 
    @Override
    public void flatMap(Tuple2<Long, Long> input, Collector<Tuple2<Long, Long>> out) throws Exception {
        // 获取当前状态值
        Tuple2<Long, Long> currentSum = sum.value();
 
        // 更新
        currentSum.f0 += 1;
        currentSum.f1 += input.f1;
 
        // 更新状态值
        sum.update(currentSum);
        
        // 如果count >=2 清空状态值,重新计算
        if (currentSum.f0 >= 2) {
            out.collect(new Tuple2<>(input.f0, currentSum.f1 / currentSum.f0));
            sum.clear();
        }
    }
 
    @Override
    public void open(Configuration config) {
        ValueStateDescriptor<Tuple2<Long, Long>> descriptor =
                new ValueStateDescriptor<>(
                        "average", // 状态名称
                        TypeInformation.of(new TypeHint<Tuple2<Long, Long>>() {}), // 状态类型
                        Tuple2.of(0L, 0L)); // 状态默认值
        sum = getRuntimeContext().getState(descriptor);
    }
}
 
// ...
env.fromElements(Tuple2.of(1L, 3L), Tuple2.of(1L, 5L), Tuple2.of(1L, 7L), Tuple2.of(1L, 4L), Tuple2.of(1L, 2L))
        .keyBy(0)
        .flatMap(new CountWindowAverage())
        .print();
 
// the printed output will be (1,4) and (1,5)

sink

flink可能被问的问题

Flink on Yarn 在新版本新增了一种模式 flink on yarn application 模式 特定 原本在客户端要做的事放在了jobManager中执行,main()方法在集群中执行。客户端只需要负责发起部署请求即可。
flink on yarn application的优点在哪,不管是yarn-per-job 还是yarn-session模式,都是在客户端获取作业所需的依赖项,2通过执行环境分析逻辑得到JobGraph,这就导致了当多个用户在一个客户端上提交造成会吃掉更多的cpu和内存。

第四问flink监控数据

1 逻辑 2 指标 3 ETL

yarn可以通过8088上获取监控,也可以通过8081上调用;
例如 http://localhost:8081/jobmanager/metrics

flink Metrics提供了几种监控指标类型
Counter:计数器统计的一个指标的总量。只针对与int和long。

class MyCounter extend RichMapFunction[Long,Long]{
	@tarnsient private var counter: Counter = _
	override def open(parameters:Configuration):Unit={}
	counter =getRuntimeContext()
					.getMetricGroup()
					.counter("MyCounter")
	override def map(input :Long):Long={
if(input>0){counter.inc}
input;
}
	
}

Gauges(给旧思):Gauges: 可以支持任何类型的数据记录和统计,一般对map进行累加

class gaugeMapper extends RichMapFunction(String ,String){
@transient private var countValue=0
override def open(parameters:Configration):Unit={
   getRuntimeContext()
   .getMertricGroup()
   .gauge[Int,ScalaGauge[Int]]("MyGauge",ScalaGauge[Int](()=>countValue))}
   override def map(value :String):String={
	countValue +=1
	value
}
}

}

meter(米ter):记录算子接受数据的平均值
Histogram(黑丝tei grams): 直方图 主要是为了Long类型监控指标的分布情况。

prometheus

特点:易于管理(单独的二进制文件,需要本地磁盘)
架构: pull(服务发现)
能够监控到内部情况,数据存在磁盘,同时他有个TSDB(时序数据库)
proQL特别牛,能够比如说(预测cpu4小时后的运行情况)
性能 : 数以百万的监控指标 每秒处理数十万的数据点。

架构

在这里插入图片描述架构可以这样理解 :中间是服务,左边是要拉取的指标,右边是监控和报警,retrieval拉取先到时序数据库TSDB中然后落到本地磁盘,通过HTTPserver提供给监控和Grafana 如果有网关则pushgateway,没网关,比如说服务器(Node Exporter) 就用jobs/ exporters

安装

和普通的有一点不一样,需要分别从官网上,下载 普罗米修斯,pushgateway ,node_exporter
读取flink的指标
需要在conf中配置
vim flink-conf.yaml
在这里插入图片描述
把普罗米修斯中的 flink-metrics prometheus-1.12.0.jar 放到flink的lib中。
如果是session,一直启动的集群,必须是集群启动之前 per-job 或者application提交job时加载的类。
为什么不用flink webUI 第一,因为任务失败的时候,那个指标东西都没了,不能持久化存储,普罗米修斯也不能。

下载grafana

PramQL

http_requests_total{instance="localhost:9090"}

范围查询
瞬时向量表达式和区间向量表达式。
http_requests_total{instance=“localhost:9090”}[5m] 5分钟内的
http_requests_total offset 5m 迁移5分。

聚合操作sum(http_requests_total)

grafana报警

(flink_jobmanager_job_uptime)-(flink_jobmanager_job_uptime offset 30s)

可能问到的问题

1 flink on yarn节点不固定,怎么监控的
通过pushgateway
2 监控有哪些?
job重启,失败,网络延迟
jobmanager,jvm,内存,io
taskmanager jvm 内存 io
背压 checkpoint rocksdb kafka

第五问数据质量

目的:保证数据的健康性
数据质量标准分类:1数据完整性 2数据一致性 3数据不重复性

如果是那种数仓 ods-dwd-dws-dwt-ads的话,
在这里插入图片描述重复值
在这里插入图片描述

在这里插入图片描述

第六问Flink调优

第一章,资源调优

在这里插入图片描述
JVM原空间 taskmanager.memory.jvm-metaspace.size 默认256mb
jvm执行开销 taskmanager.memory.jvm-overhead.fraction 默认192mb
taskmanager.memory.jvm-overhead.max 默认1gb
总进程内存 *fraction

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

在这里插入图片描述

在这里插入图片描述在这里插入图片描述### 案例分析
基于Yarn模式,一般参数指定的是总进程内存,taskmanager.memory.process.size,比如指定为4G,每一块内存得到大小如下:
(1)计算Flink内存
在这里插入图片描述

CPU资源利用

首先,一个slot,一般是用一个cpu的核心数,要知道,当并行度设置为4,但是slot设置为2时,就会有两个taskManager,此时应该用4个cpu核心数,但是如果yarn是容量调度的时候就会出现问题,公平调度就没问题。如何改变呢?
在这里插入图片描述这个4是咋来的呢?有4个container,因为jobmanager占用一个,仨个taskmanager

在capacity-scheduler.xml中进行配置。在这里插入图片描述设置成Domin就行了,可以看到。这样cpu的数目就是slot的数目了。

并行度设置

配置文件:默认并行度
提交参数
代码
算子
全局并行度:
先让kafka积攒点数据,然后消费,看每秒多少数据,然后用总QPS/单并行度的处理能力=并行度
最好根据高峰时期QPS进行测压。
Source端并行度配置
数据源端是kafka Source的并行度设置为Kafka的topic的分区
Transform并行度配置
keyBy之前的算子和source一致
keyBy之后的算子 最好2的整数次幂
Sink端配置并行度,设置kafka topic.

第二章,状态及checkpoint调优

在这里插入图片描述在这里插入图片描述开启增量检查点和本地恢复
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述具体调优,加上这两行代码,或者运行程序的时候配置
在这里插入图片描述
这里边会自动配置成他认为合适的配置,这个具体配置什么呢?
在这里插入图片描述(State)就是啥意思呢?,flink运行的时候会有多个状态,比如分组多出来的状态呀啥的,这里具体我也没太明白。到底列族名表示啥玩意
在这里插入图片描述

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

1增大block块缓存 默认8M

在这里插入图片描述
所有调优如下:

在这里插入图片描述这些在预定义里都定义过,也可以自己定义
1 检查点自增
2 本地恢复
3 预定义
4 块缓存
5 writebuffer的大小 每个列簇名对应一个writebuffer
6 level阈值大小 (配置writebuffer需要调整这个值,如果这个值小,则会导致索引太多)
7 writebuffer的数量,每个列簇对应的writebuffer的数量
8 4线程
9 合并数3个
10 开启索引分区功能
11 状态监测

Checkpoint参数设置

checkpoint时间间隔一般设置分钟,
在这里插入图片描述 间隔 分钟,秒 (这个要根据需求判断,sink端是两提交模式,要想实时性好,就得一直保存点)
最小等待间隔:参考间隔,一半
超时时间:默认10分钟
保留ck,这样就可以把ck当作savapoint用了。

第三章 反压

1 先关闭操作链,在mertics就可以看到了
在这里插入图片描述
上图中,NetworkBufferPool 就是floatingBuffersUsage ResultSubpartition就是ExclusiveBuffersUsage
除了in和out,也可以根据下表
在这里插入图片描述在这里插入图片描述

找问题

第一:直接点mertics,就是上边说的那些
第二 : 开启或火焰图找看哪个类占用cpu时间长
第三:下面数据倾斜导致的反压

在这里插入图片描述这个就是数据倾斜,就一个46.9G,其他的都是2.27G

GC导致的反压

在这里插入图片描述在这里插入图片描述用GCViewer这个软件打开日志查看(日志从taskManagerUi那个页面下载)

外部组件交互

在这里插入图片描述

第四章 数据倾斜

在这里插入图片描述这个就是数据倾斜,就一个46.9G,其他的都是2.27G

keyBy后的聚和操作存在的数据倾斜

解决的第一个方法 localKeyBy 在keyBy之前先进行一个本地预聚合。(主要就是先批量聚合一下)
我个人感觉这个和两阶段提交思想上没啥区别…

keyBy之前发生的数据倾斜

也就是说map,fliter就数据倾斜
这时候让flink任务强制进行shuffle.使用shuffle,rebalance或rescale算子即可将数据均匀分配,从而解决数据倾斜的问题。

keyBy后的窗口聚合操作存在数据倾斜

因为使用了窗口,变成了有界数据(赞批)的处理,窗口默认是触发时才会输出一条结果发往下游,所以可以使用两阶段聚合的方式。
具体做法就是先打散再聚合。

第五章 Job优化

算子指定UUID

当恢复的时候,如果增删算子,那不得必须指定一个UUID? 建议每个算子都给个UUID.

链路延迟测量

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

对象重用

env.getconfig.enableObjectReuse
这个具体啥意思呢? 就是说默认对象重用不开启,比如说一个Stream流但是下方有两个map算子给他对接时,要关闭对象重用,因为每个map都是可能要改变这个值的,若开启对象重用,则会导致线程安全。
总结: 如果只有一条流的话可以开启对象重用,两条或者多流的话,得看看是不是其他流修改了对象数值,其他流不修改的话才能重用,比如说(filter)

细粒度滑动窗口

比如说窗口为1天,划动1分钟,这样就会造成大量数据重叠

第六章 Sql调优

第七章 常见故障排除

非法配置异常

比如说内存为负呀啥的

java堆空间异常

就是配置呗

直接缓冲存储器异常

就是配置呗

元空间异常

就是配置呗

网络缓冲区数量不足

就是配置呗

超出容器内存异常

这个没有预留足够的本机内存,这个比较难解决

checkpoint失败

1decline衰退
2expire

反压

kafka动态发现分区

在这里插入图片描述

Watermark 不更新

依赖冲突

安装个插件MavenHelper

补充

(1)flink的metrics 监控可以用普罗米修斯 加 grafa或者InfluxDB + grafa
(2) 程序写完后,造测试数据的工具DataFactory,datafaker,DBMonster,Data-Processer,Nexmark,Jmeter

第八章 flink各行各业现状

总结 :FLINK SQL是未来主题

理想汽车:两个问题:一 T+1 离线计算出前面的,1是flink算的 二 生产线上两个流join,当两个事件的间隔时间不确定多大怎么处理,
设置一个合适的TTL,关联不到就直接关联表。这个想法和美团一样,冷热数据,
美团:实时数仓 Nau(钠五)
19年调研实时数仓 FLINKSQL
20年给业务对接 发现对FLINKSQL运维不太好
21年主要针对FLINkSQL运维
问题:两个流join大状态问题,采用冷热处理, (两天内叫热数据,直接用flinkSQL,其他的保存至kv中)
有状态SQL变更后,状态如何恢复?(正常情况下,应该暂停业务,重新消费,但是很多时候不想让自己原有的业务暂停服务)解法一 采用备用链路(就是同一个业务搞两份,现在备用上做回溯,当他的输出合适的时候,再切换对应的表) 解法二 旁路状态生成(和第一种差不多吧,只不过是部分) 解法三 历史状态迁移(不能保证数据的完整性)
快手:

2022年5月6日flink的复习

之前一个小公司面试我,问我flink一些简单的问题没有回答出来,几个月没用到flink都快忘完了,今天回顾一下。

flink的诞生

2010-2014年德国柏林大学等几个学校联合,发表stratophere这个项目,后来这几个人离开学校共同创建了一家DataArtisana的公司,主要业务就是stratophere
2014年12月,成为apache顶级项目

flink的优点

1高吞吐 低延迟
2exactly-once语义
3基于流式计算引擎处理批量数据的计算能力
4支持事件时间
5支持状态计算
6支持高度灵活的窗口
7基于轻量级分布式快照实现的容错-通过checkpoints中进行任务的自动恢复
8基于JVM实现独立的内存管理 不会因为JVMGC等问题而影响整个应用的运行
9SavePoints(保存点)

主要参考尚硅谷和官网

第一次学建议https://www.bilibili.com/video/BV1yZ4y1A74d这个老师讲的好,适合入门。
第二次学再看 https://www.bilibili.com/video/BV1gp4y1e71T 武老师讲的不适合第一次学。
调优https://www.bilibili.com/video/BV1Q5411f76P?p=2&spm_id_from=pageDriver
还有张力兵的flink书
flink中文社区 https://flink-learning.org.cn/ (我还没仔细研究过,里边有好的文章)

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值