Flink整理篇

spark与flink的区别?
1.架构模型不同
Spark在运行时的主要角色包括:Master、Worker、Driver、Executor
Flink 在运行时主要包含:Jobmanager、Taskmanager 和 Slot
Slot与Parallelism的关系
Slot(指taskmanager 的并发执行能力,与cpu核心数有关,一般slot 数就是每个TaskManager给的cpu 核数。taskmanager.numberOfTaskSlots可以设置,但不能超过核心数,要不然flink任务会报错)
parallelism(指 taskmanager 实际使用的并发能力,可配置、可指定的)
2.任务调度不同
Flink 根据提交的代码生成 StreamGraph,StreamGraph生成 JobGraph,然后提交给 JobManager 进行处理,JobManager 根据 JobGraph 生成的 ExecutionGraph 对 Job 进行调度。
Spark Streaming 会依次创建 DStreamGraph、JobGenerator、JobScheduler。

3.时间机制
Spark支持的时间机制有限,只支持处理时间。
Flink 支持:事件时间、注入时间、处理时间。
4.容错机制
Spark是用checkpoint,但是如果机器发生故障重启或者输出操作foreach(采用的是At-Least Once),数据不会丢失但是可能会重复处理,不能做到Exactly-Once。
Flink 则使用两阶段提交协议来解决这个问题。
Flink两阶段提交:Flink 通过实现两阶段提交和状态保存来实现端到端的一致性语义。分为以下几个步骤:
开始事务(beginTransaction)创建一个临时文件夹,来写把数据写入到这个文件夹里面
预提交(preCommit)将内存中缓存的数据写入文件并关闭
正式提交(commit)将之前写完的临时文件放入目标目录下。

JobManager负责协调Flink程序的执行,包括:任务的调度、任务运行完成与失败的处理,协调检查点与恢复等。
主要包括以下项职能:
ResourceManager:负责资源分配,管理任务slot, 这个是flink集群资源管理的单位。
Dispatcher:提供应用程序提交的REST接口,对每一个提交的作业启动JobMaster,并运行Flink WebUI提供作业执行的信息。
JobMaster:负责单个作业图(JobGraph)的执行。一个集群可以同时运行多个作业,每个作业都有自己的JobMaster。
TaskManager负责执行dataflow中的任务,缓存和交换数据流。一个作业执行时,至少要有一个TaskManager,TaskManager中资源调度的最小单位是slot。
在这里插入图片描述
在这里插入图片描述

Flink的窗口有几种?
Timewindow、Countwindow、Session Window、普通Window(window和windowall)
Time Window 是根据时间对数据流进行分组的,分为滑动和滚动窗口。
滑动窗口Sliding Time Window
但是对于某些应用,它们需要的窗口是不间断的,需要平滑地进行窗口聚合。比如,我们可以每30秒计算一次最近一分钟用户购买的商品总数。这种窗口我们称为滑动时间窗口(Sliding Time Window)。在滑窗中,一个元素可以对应多个窗口。通过使用 DataStream API,我们可以这样实现:
val slidingCnts: DataStream[(Int, Int)] = buyCnts
.keyBy(0)
// sliding time window of 1 minute length and 30 secs trigger interval
.timeWindow(Time.minutes(1), Time.seconds(30))
.sum(1)
滚动窗口Tumbling Time Window
我们需要统计每一分钟中用户购买的商品的总数,需要将用户的行为事件按每一分钟进行切分,这种切分被成为翻滚时间窗口(Tumbling Time Window)。翻滚窗口能将数据流切分成不重叠的窗口,每一个事件只能属于一个窗口。通过使用 DataStream API,我们可以这样实现:
// Stream of (userId, buyCnt)
val buyCnts: DataStream[(Int, Int)] = …

val tumblingCnts: DataStream[(Int, Int)] = buyCnts
// key stream by userId
.keyBy(0)
// tumbling time window of 1 minute length
.timeWindow(Time.minutes(1))
// compute sum over buyCnt
.sum(1)
Count Window 是根据元素个数对数据流进行分组的,也分为滑动和滚动窗口。
滑动窗口Sliding Count Window
当然Count Window 也支持 Sliding Window,虽在上图中未描述出来,但和Sliding Time Window含义是类似的,例如计算每10个元素计算一次最近100个元素的总和,代码示例如下。
val slidingCnts: DataStream[(Int, Int)] = vehicleCnts
.keyBy(0)
// sliding count window of 100 elements size and 10 elements trigger interval
.countWindow(100, 10)
.sum(1)
滚动窗口Tumbling Count Window
当我们想要每100个用户购买行为事件统计购买总数,那么每当窗口中填满100个元素了,就会对窗口进行计算,这种窗口我们称之为翻滚计数窗口(Tumbling Count Window),上图所示窗口大小为3个。通过使用 DataStream API,我们可以这样实现:
// Stream of (userId, buyCnts)
val buyCnts: DataStream[(Int, Int)] = …

val tumblingCnts: DataStream[(Int, Int)] = buyCnts
// key stream by sensorId
.keyBy(0)
// tumbling count window of 100 elements size
.countWindow(100)
// compute the buyCnt sum
.sum(1)
Session Window
在这种用户交互事件流中,我们首先想到的是将事件聚合到会话窗口中(一段用户持续活跃的周期),由非活跃的间隙分隔开。如上图所示,就是需要计算每个用户在活跃期间总共购买的商品数量,如果用户30秒没有活动则视为会话断开(假设raw data stream是单个用户的购买行为流)。Session Window 的示例代码如下:

// Stream of (userId, buyCnts)
val buyCnts: DataStream[(Int, Int)] = …

val sessionCnts: DataStream[(Int, Int)] = vehicleCnts
.keyBy(0)
// session window based on a 30 seconds session gap interval
.window(ProcessingTimeSessionWindows.withGap(Time.seconds(30)))
.sum(1)
普通窗口
Window算子:是可以设置并行度的
dataStream.keyBy(0).window(TumblingEventTimeWindows.of(Time.seconds(5)));
WindowAll 算子:并行度始终为1
dataStream.windowAll(TumblingEventTimeWindows.of(Time.seconds(5)));

Flink的checkpoint和barrier
checkpoint是保存的一个阶段计算的数据和状态,barrier是一种轻量级异步快照,跟kafka的offset差不多。
流程:JobManager 定时广播barrier给计算任务所有的 Source,其后伴随数据流一起流至下游。每当接收到屏障,算子便会将对当前的状态做一次快照,、最后屏障流至作业的 Sink(就是最后一个算子),Sink 接受到屏障后立即向 JobManager 发送消息确认sink收到后,这就是一个完整的快照。快照完成后,当前的快照窗口随之关闭,算子不会再向上游请求早于这个时间的数据。

Flink 是如何支持批流一体的?
DataSet和DataStream两个API

Flink 是如何容错的?
CheckPoint 机制和 State 机制。Checkpoint 负责定时制作分布式快照、对程序中的状态进行备份;State 用来存储计算过程中的中间状态。

Flink中window 出现数据倾斜怎么解决?
window 产生数据倾斜指的是数据在不同的窗口内堆积的数据量相差过多。本质上产生这种情况的原因是数据源头发送的数据量速度不同导致的。出现这种情况一般通过两种方式来解决:
在数据进入窗口前做预聚合
重新设计窗口聚合的 key

Flink 任务延时高,如何入手?
在 Flink 的后台任务管理中,我们可以看到 Flink 的哪个算子和 task 出现了反压。最主要的手段是资源调优和算子调优。资源调优即是对作业中的 Operator 的并发数(parallelism)、CPU(core)、堆内存(heap_memory)等参数进行调优。作业参数调优包括:并行度的设置,State 的设置,checkpoint 的设置。

Flink 反压?
Flink 内部是基于 producer-consumer 模型来进行消息传递的,Flink 的反压设计也是基于这个模型。Flink 使用了高效有界的分布式阻塞队列,就像 Java 通用的阻塞队列(BlockingQueue)一样。下游消费者消费变慢,上游就会受到阻塞。

Flimk 的内存管理?
Flink 并不是将大量对象存在堆上,而是将对象都序列化到一个预分配的内存块上。此外,Flink 大量的使用了堆外内存。如果需要处理的数据超出了内存限制,则会将部分数据存储到硬盘上。Flink 为了直接操作二进制数据实现了自己的序列化框架。
Flink 的内存管理分为三部分:
Network Buffers:这个是在 TaskManager 启动的时候分配的,这是一组用于缓存网络数据的内存,每个块是 32K,默认分配 2048 个,可以通过“taskmanager.network.numberOfBuffers”修改
Memory Manage pool:大量的 Memory Segment 块,用于运行时的算法(Sort/Join/Shuffle 等),这部分启动的时候就会分配。下面这段代码,根据配置文件中的各种参数来计算内存的分配方法。(heap or off-heap,这个放到下节谈),内存的分配支持预分配和 lazy load,默认懒加载的方式。
User Code,这部分是除了 Memory Manager 之外的内存用于 User code 和 TaskManager 本身的数据结构。

FlinkSQL 的是如何实现的?
构建抽象语法树的事情交给了 Calcite 去做。SQL query 会经过 Calcite 解析器转变成 SQL 节点树,提交任务后会分发到各个 TaskManager 中运行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值