这是我参与「第四届青训营 」笔记创作活动的的第2天
题目来源:【大数据专场 学习资料一】第四届字节跳动青训营 - 掘金
- Dataflow Model 核心设计思想是什么?
- 对于无序的流式数据提供基于 event-time 的顺序处理、基于数据本身的特征进行窗口聚合处理的能力,以及平衡正确性、延迟、成本之间的相互关系。
- What results are being computed. => Transformation,分ParDo 和 GroupByKey,
- Where in event time they are been computed. => Window,Windowing Model,支持非对齐的 event time 的窗口聚合
- When in processing time they are materialized. => Watermark and Trigger,提供强大和灵活的声明式 API 来描述 Trigger 语义,可以根据事件处理的运行时特征来决定输出次数,watermark 保证延迟数据能够基本被消费
- How earlier results relate to later refinements. => Discarding, Accumulating, Accumulating & Retracting.Discarding,窗口数据 Trigger 之后直接丢弃。Accumulating,这种方式类似 Lambda 架构,也就是 Trigger 之后,窗口的结果数据被保存下来以支持后面的数据进行更新。Accumulating & Retracting,在第二种的基础上提供了回退操作,也就是在之后再 Trigger 的时候,先触发一次撤回操作,再下发新的结果。这种方式在某些场景下还是很有用的。
- Flink 相比于 Storm、Spark Streaming 有哪些优势?
-
Storm:History of Apache Storm and lessons learned - thoughts from the red planet;
- Storm API 的 low-level 以及开发效率低下;
- 一致性问题:Storm 更多考虑到实时流计算的处理时延而非数据的一致性保证;
-
Spark Streaming:An Architecture for Fast and General Data Processing on Large Clusters;
- Spark Streaming 相比于 Storm 的低阶 API 以及无法正确性语义保证,Spark 是流处理的分水岭:第一个广泛使用的大规模流处理引擎,既提供较为高阶的 API 抽象,同时提供流式处理正确性保证。但采用min-batch处理数据,延迟教高,不是真正的流式计算。
-
Flink:从产品技术来看,Flink 作为一个最新的实时计算引擎,具备如下流计算技术特征:
-
完全一次保证:故障后应正确恢复有状态运算符中的状态;
-
低延迟:越低越好。许多应用程序需要亚秒级延迟;
-
高吞吐量:随着数据速率的增长,通过管道推送大量数据至关重要;
-
强大的计算模型:框架应该提供一种编程模型,该模型不限制用户并允许各种各样的应用程序在没有故障的情况下,容错机制的开销很低;
-
流量控制:来自慢速算子的反压应该由系统和数据源自然吸收,以避免因消费者缓慢而导致崩溃或降低性能;
-
乱序数据的支持:支持由于其他原因导致的数据乱序达到、延迟到达后,计算出正确的结果;
-
完备的流式语义:支持窗口等现代流式处理语义抽象;
-
Google Dataflow Model 的开源引擎实现。
-
- 为什么 Flink 可以做到支持 流/批/OLAP 三种业务场景?三种业务场景核心差异和挑战是哪些?
- 批式计算是流式计算的特例,Everything is Streams,有界数据集(批式数据)也是一种数据流、一种特殊的数据流;
- OLAP 计算是一种特殊的批式计算,它对并发和实时性要求更高,其他情况与普通批式作业没有特别大区别。
- 站在 Flink 的角度,Everything is Streams,无边界数据集是一种数据流,一个无边界的数据流可以按时间切段成一个个有边界的数据集,所以有界数据集(批式数据)也是一种数据流。因此,不管是有边界的数据集(批式数据)还是无边界数据集,Flink 都可以天然地支持,这是 Flink 支持流批一体的基础。并且 Flink 在流批一体上,从上面的 API 到底层的处理机制都是统一的,是真正意义上的流批一体。
-
批式计算和流式核心差异:
-
批式不需要申请所有任务资源,可以跑完一个任务再用相同资源处理下一个任务;而流式需要申请到所有资源。为解决该问题,flink分EAGER和LAZY模式,并引入pipeline region统一批流,同一个pipeline region的资源需要全部申请到
-
shuffle不同。
-
Shuffle 数据的生命周期:流作业的 Shuffle 数据与 Task 是绑定的,而批作业的 Shuffle 数据与 Task 是解耦的;
-
Shuffle 数据存储介质:流作业的生命周期比较短、而且流作业为了实时性,Shuffle 通常存储在内存中,批作业因为数据量比较大以及容错的需求,一般会存储在磁盘里;
-
Shuffle 的部署方式:流作业 Shuffle 服务和计算节点部署在一起,可以减少网络开销,从而减少 latency,而批作业则不同。
-
flink引入了Pluggable Shuffle Service,既可以满足不同 Shuffle 在策略上的定制,同时还能避免在共性需求上进行重复开发
-
-
-
OLAP挑战
-
秒级和毫秒级的小作业;
-
作业频繁启停、资源碎片;
-
Latency + 高 APS 要求;
-
OLAP 最大的特点是查询作业对 Latency 和 QPS 有要求的,需要保证作业在 Latency 的前提下提供比较高的并发调度和执行能力,这就对 Flink 引擎提出了一个新的要求。
-
- 流式场景中,反压一种经常遇到的 case,Flink 是如何处理反压的?你知道其他引擎是怎么处理的么?
- 参考:Flink 原理与实现:如何处理反压问题
- Storm 是通过监控 Bolt 中的接收队列负载情况,如果超过高水位值就会将反压信息写到 Zookeeper ,Zookeeper 上的 watch 会通知该拓扑的所有 Worker 都进入反压状态,最后 Spout 停止发送 tuple。具体实现可以看这个 JIRA STORM-886。
- JStorm 认为直接停止 Spout 的发送太过暴力,存在大量问题。当下游出现阻塞时,上游停止发送,下游消除阻塞后,上游又开闸放水,过了一会儿,下游又阻塞,上游又限流,如此反复,整个数据流会一直处在一个颠簸状态。所以 JStorm 是通过逐级降速来进行反压的,效果会较 Storm 更为稳定,但算法也更复杂。另外 JStorm 没有引入 Zookeeper 而是通过 TopologyMaster 来协调拓扑进入反压状态,这降低了 Zookeeper 的负载。
- Flink 在运行时主要由 operators 和 streams 两大组件构成。每个 operator 会消费中间态的流,并在流上进行转换,然后生成新的流。对于 Flink 的网络机制一种形象的类比是,Flink 使用了高效有界的分布式阻塞队列,就像 Java 通用的阻塞队列(BlockingQueue)一样。还记得经典的线程间通信案例:生产者消费者模型吗?使用 BlockingQueue 的话,一个较慢的接受者会降低发送者的发送速率,因为一旦队列满了(有界队列)发送者会被阻塞。
- Flink JobManager 各个组件分别是做什么的?你觉得为什么要这样设计?
-
Actor System
- 分布式通信
-
Dataflow Graph
- 将JobGraph 转换成 ExecutionGraph
-
Scheduler
- 任务调度器,调度task manager执行任务
-
Checkpoint coordinator
- 检查点协调器,发送barrier和接收ack,保证消息端到端exactly once处理
- 有兴趣的,可以参考 First steps、Intro to the DataStream API、Learn Flink Overview 几篇文档,本地跑一个 Flink Job 试下。
跑了最简单的case