寫在前面: 博主是一名大資料的初學者,昵稱來源于《愛麗絲夢游仙境》中的Alice和自己的昵稱,作為一名互聯網小白,
寫博客一方面是為了記錄自己的學習歷程,一方面是希望能夠幫助到很多和自己一樣處于起步階段的萌新,由于水平有限,博客中難免會有一些錯誤,有紕漏之處懇請各位大佬不吝賜教!個人小站:http://alices.ibilibili.xyz/ , 博客主頁:https://alice.blog.csdn.net/
盡管當前水平可能不及各位大佬,但我還是希望自己能夠做得更好,因為一天的生活就是一生的縮影,我希望在最美的年華,做最好的自己!
近幾年Flink發展得例外的火熱,對Flink還不太了解的朋友可以先去看看博主的上一篇文章👉《簡單告訴你,為什么要學 Flink,Flink 優勢在哪?》,本篇文章,既Hadoop,Hive,Spark之后,推出了關于Flink的大資料面試殺招,希望各位朋友們看完能受益~

Flink基礎
1、簡單介紹一下 Flink
Flink 是一個框架和分布式處理引擎,用于對無界和有界資料流進行有狀態計算,并且 Flink 提供了資料分布、容錯機制以及資源管理等核心功能,Flink提供了諸多高抽象層的API以便用戶撰寫分布式任務:
DataSet API, 對靜態資料進行批處理操作,將靜態資料抽象成分布式的資料集,用戶可以方便地使用Flink提供的各種運算子對分布式資料集進行處理,支持Java、Scala和Python,
DataStream API,對資料流進行流處理操作,將流式的資料抽象成分布式的資料流,用戶可以方便地對分布式資料流進行各種操作,支持Java和Scala,
Table API,對結構化資料進行查詢操作,將結構化資料抽象成關系表,并通過類SQL的DSL對關系表進行各種查詢操作,支持Java和Scala,
此外,Flink 還針對特定的應用領域提供了領域庫,例如: Flink ML,Flink 的機器學習庫,提供了機器學習Pipelines API并實作了多種機器學習演算法, Gelly,Flink 的圖計算庫,提供了圖計算的相關API及多種圖計算演算法實作,
2、Flink相比傳統的Spark Streaming區別?
這個問題是一個非常宏觀的問題,因為兩個框架的不同點非常之多,但是在面試時有非常重要的一點一定要回答出來:Flink 是標準的實時處理引擎,基于事件驅動,而 Spark Streaming 是微批(Micro-Batch)的模型 ,
下面我們就分幾個方面介紹兩個框架的主要區別:
- 架構模型Spark Streaming 在運行時的主要角色包括:Master、Worker、Driver、Executor,Flink 在運行時主要包含:Jobmanager、Taskmanager和Slot,
- 任務調度Spark Streaming 連續不斷的生成微小的資料批次,構建有向無環圖DAG,Spark Streaming 會依次創建 DStreamGraph、JobGenerator、JobScheduler,Flink 根據用戶提交的代碼生成 StreamGraph,經過優化生成 JobGraph,然后提交給 JobManager進行處理,JobManager 會根據 JobGraph 生成 ExecutionGraph,ExecutionGraph 是 Flink 調度最核心的資料結構,JobManager 根據 ExecutionGraph 對 Job 進行調度,
- 時間機制Spark Streaming 支持的時間機制有限,只支持處理時間, Flink 支持了流處理程式在時間上的三個定義:處理時間、事件時間、注入時間,同時也支持 watermark 機制來處理滯后資料,
- 容錯機制對于 Spark Streaming 任務,我們可以設定 checkpoint,然后假如發生故障并重啟,我們可以從上次 checkpoint 之處恢復,但是這個行為只能使得資料不丟失,可能會重復處理,不能做到恰好一次處理語意,Flink 則使用兩階段提交協議來解決這個問題,
3、Flink的組件堆疊有哪些?
根據 Flink 官網描述,Flink 是一個分層架構的系統,每一層所包含的組件都提供了特定的抽象,用來服務于上層組件,

自下而上,每一層分別代表:Deploy 層:該層主要涉及了Flink的部署模式,在上圖中我們可以看出,Flink 支持包括local、Standalone、Cluster、Cloud等多種部署模式 ,
Runtime 層:Runtime層提供了支持 Flink 計算的核心實作,比如:支持分布式 Stream 處理、JobGraph到ExecutionGraph的映射、調度等等,為上層API層提供基礎服務 ,
API層: API 層主要實作了面向流(Stream)處理和批(Batch)處理API,其中面向流處理對應DataStream API,面向批處理對應DataSet API,后續版本,Flink有計劃將DataStream和DataSet API進行統一 ,
Libraries層: 該層稱為Flink應用框架層,根據API層的劃分,在API層之上構建的滿足特定應用的實作計算框架,也分別對應于面向流處理和面向批處理兩類,面向流處理支持:CEP(復雜事件處理)、基于SQL-like的操作(基于Table的關系操作);面向批處理支持:FlinkML(機器學習庫)、Gelly(圖處理),
4、Flink 的運行必須依賴 Hadoop組件嗎?
Flink可以完全獨立于Hadoop,在不依賴Hadoop組件下運行,但是做為大資料的基礎設施,Hadoop體系是任何大資料框架都繞不過去的,Flink可以集成眾多Hadooop 組件,例如Yarn、Hbase、HDFS等等,例如,Flink可以和Yarn集成做資源調度,也可以讀寫HDFS,或者利用HDFS做檢查點,
5、你們的Flink集群規模多大?
大家注意,這個問題看起來是問你實際應用中的Flink集群規模,其實還隱藏著另一個問題:Flink可以支持多少節點的集群規模?在回答這個問題時候,可以將自己生產環節中的集群規模、節點、記憶體情況說明,同時說明部署模式(一般是Flink on Yarn),除此之外,用戶也可以同時在小集群(少于5個節點)和擁有 TB 級別狀態的上千個節點上運行 Flink 任務,
6、Flink的基礎編程模型了解嗎?

上圖是來自Flink官網的運行流程圖,通過上圖我們可以得知,Flink 程式的基本構建是資料輸入來自一個 Source,Source 代表資料的輸入端,經過 Transformation 進行轉換,然后在一個或者多個Sink接收器中結束,資料流(stream)就是一組永遠不會停止的資料記錄流,而轉換(transformation)是將一個或多個流作為輸入,并生成一個或多個輸出流的操作,執行時,Flink程式映射到 streaming dataflows,由流(streams)和轉換操作(transformation operators)組成,
7、Flink集群有哪些角色?各自有什么作用?

Flink 程式在運行時主要有 TaskManager,JobManager,Client 三種角色,
其中JobManager扮演著集群中的管理者Master的角色,它是整個集群的協調者,負責接收Flink Job,協調檢查點,Failover 故障恢復等,同時管理Flink集群中從節點TaskManager,
TaskManager是實際負責執行計算的Worker,在其上執行Flink Job的一組Task,每個TaskManager負責管理其所在節點上的資源資訊,如記憶體、磁盤、網路,在啟動的時候將資源的狀態向JobManager匯報,
Client是Flink程式提交的客戶端,當用戶提交一個Flink程式時,會首先創建一個Client,該Client首先會對用戶提交的Flink程式進行預處理,并提交到Flink集群中處理,所以Client需要從用戶提交的Flink程式配置中獲取JobManager的地址,并建立到JobManager的連接,將Flink Job提交給JobManager,
8、說說 Flink 資源管理中 Task Slot 的概念

在Flink架構角色中我們提到,TaskManager是實際負責執行計算的Worker,TaskManager 是一個 JVM 行程,并會以獨立的執行緒來執行一個task或多個subtask,為了控制一個 TaskManager 能接受多少個 task,Flink 提出了 Task Slot 的概念,簡單的說,TaskManager會將自己節點上管理的資源分為不同的Slot:固定大小的資源子集,這樣就避免了不同Job的Task互相競爭記憶體資源,但是需要主要的是,Slot只會做記憶體的隔離,沒有做CPU的隔離,
9、說說 Flink 的常用算子?
Flink 最常用的常用算子包括:Map:DataStream → DataStream,輸入一個引數產生一個引數,map的功能是對輸入的引數進行轉換操作,Filter:過濾掉指定條件的資料,KeyBy:按照指定的key進行分組,Reduce:用來進行結果匯總合并,Window:視窗函式,根據某些特性將每個key的資料進行分組(例如:在5s內到達的資料)
10、說說你知道的Flink磁區策略?
要搞懂什么是磁區策略,需要清楚磁區策略是用來決定資料如何發送至下游,目前 Flink 支持了8種磁區策略的實作,

上圖是整個Flink實作的磁區策略繼承圖:GlobalPartitioner 資料會被分發到下游算子的第一個實體中進行處理,ShufflePartitioner 資料會被隨機分發到下游算子的每一個實體中進行處理,RebalancePartitioner 資料會被回圈發送到下游的每一個實體中進行處理,RescalePartitioner 這種磁區器會根據上下游算子的并行度,回圈的方式輸出到下游算子的每個實體,這里有點難以理解,假設上游并行度為2,編號為A和B,下游并行度為4,編號為1,2,3,4,那么A則把資料回圈發送給1和2,B則把資料回圈發送給3和4,假設上游并行度為4,編號為A,B,C,D,下游并行度為2,編號為1,2,那么A和B則把資料發送給1,C和D則把資料發送給2,BroadcastPartitioner 廣播磁區會將上游資料輸出到下游算子的每個實體中,適合于大資料集和小資料集做Jion的場景,ForwardPartitioner ForwardPartitioner 用于將記錄輸出到下游本地的算子實體,它要求上下游算子并行度一樣,簡單的說,ForwardPartitioner用來做資料的控制臺列印,KeyGroupStreamPartitioner Hash磁區器,會將資料按 Key 的 Hash 值輸出到下游算子實體中,CustomPartitionerWrapper 用戶自定義磁區器,需要用戶自己實作Partitioner介面,來定義自己的磁區邏輯,例如:
static classCustomPartitionerimplementsPartitioner<String> {
@Override
publicintpartition(String key, int numPartitions) {
switch (key){
case "1":
return 1;
case "2":
return 2;
case "3":
return 3;
default:
return 4;
}
}
}
11、Flink的并行度了解嗎?Flink的并行度設定是怎樣的?
Flink中的任務被分為多個并行任務來執行,其中每個并行的實體處理一部分資料,這些并行實體的數量被稱為并行度,我們在實際生產環境中可以從四個不同層面設定并行度:
操作算子層面(Operator Level)
執行環境層面(Execution Environment Level)
客戶端層面(Client Level)
系統層面(System Level)
需要注意的優先級:算子層面>環境層面>客戶端層面>系統層面,
12、 Flink的Slot和parallelism有什么區別?
官網上十分經典的圖:

slot是指 taskmanager 的并發執行能力,假設我們將 taskmanager.numberOfTaskSlots 配置為3 那么每一個 taskmanager 中分配3個 TaskSlot, 3個 taskmanager 一共有9個TaskSlot,

parallelism是指taskmanager實際使用的并發能力,假設我們把 parallelism.default 設定為1,那么9個 TaskSlot 只能用1個,有8個空閑,
13、Flink有沒有重啟策略?說說有哪幾種?
Flink 實作了多種重啟策略,
- 固定延遲重啟策略(Fixed Delay Restart Strategy)
- 故障率重啟策略(Failure Rate Restart Strategy)
- 沒有重啟策略(No Restart Strategy)
- Fallback重啟策略(Fallback Restart Strategy)
14、用過Flink中的分布式快取嗎?如何使用?
Flink實作的分布式快取和Hadoop有異曲同工之妙,目的是在本地讀取檔案,并把他放在 taskmanager 節點中,防止task重復拉取,
val env = ExecutionEnvironment.getExecutionEnvironment
// register a file from HDFS
env.registerCachedFile("hdfs:///path/to/your/file", "hdfsFile")
// register a local executable file (script, executable, ...)
env.registerCachedFile("file:///path/to/exec/file", "localExecFile", true)
// define your program and execute
...
val input: DataSet[String] = ...
val result: DataSet[Integer] = input.map(new MyMapper())
...
env.execute()
15、說說Flink中的廣播變數,使用時需要注意什么?
我們知道Flink是并行的,計算程序可能不在一個 Slot 中進行,那么有一種情況即:當我們需要訪問同一份資料,那么Flink中的廣播變數就是為了解決這種情況,我們可以把廣播變數理解為是一個公共的共享變數,我們可以把一個dataset 資料集廣播出去,然后不同的task在節點上都能夠獲取到,這個資料在每個節點上只會存在一份,
16、說說Flink中的視窗?
說說Flink中的視窗?

Flink 支持兩種劃分視窗的方式,按照time和count,如果根據時間劃分視窗,那么它就是一個time-window ,如果根據資料劃分視窗,那么它就是一個 count-window,flink支持視窗的兩個重要屬性(size和interval)如果size=interval,那么就會形成tumbling-window(無重疊資料) ;如果size>interval,那么就會形成sliding-window(有重疊資料) 如果size< interval, 那么這種視窗將會丟失資料,比如每5秒鐘,統計過去3秒的通過路口汽車的資料,將會漏掉2秒鐘的資料,通過組合可以得出四種基本視窗:
- time-tumbling-window 無重疊資料的時間視窗,設定方式舉例:timeWindow(Time.seconds(5))
- time-sliding-window 有重疊資料的時間視窗,設定方式舉例:timeWindow(Time.seconds(5), Time.seconds(3))
- count-tumbling-window無重疊資料的數量視窗,設定方式舉例:countWindow(5)
- count-sliding-window 有重疊資料的數量視窗,設定方式舉例:countWindow(5,3)
17、說說Flink中的狀態存盤?
Flink在做計算的程序中經常需要存盤中間狀態,來避免資料丟失和狀態恢復,選擇的狀態存盤策略不同,會影響狀態持久化如何和 checkpoint 互動,
Flink提供了三種狀態存盤方式:MemoryStateBackend、FsStateBackend、RocksDBStateBackend,
18、Flink中的時間有哪幾類
Flink 中的時間和其他流式計算系統的時間一樣分為三類:事件時間,攝入時間,處理時間三種,如果以 EventTime為基準來定義時間視窗將形成EventTimeWindow,要求訊息本身就應該攜帶EventTime,如果以IngesingtTime 為基準來定義時間視窗將形成 IngestingTimeWindow,以 source 的systemTime為準,如果以 ProcessingTime 基準來定義時間視窗將形成 ProcessingTimeWindow,以 operator 的systemTime 為準,
19、Flink中的水印是什么概念,起到什么作用?
Watermark 是 Apache Flink 為了處理 EventTime 視窗計算提出的一種機制, 本質上是一種時間戳, 一般來講Watermark經常和Window一起被用來處理亂序事件,
20、Flink Table & SQL 熟悉嗎?TableEnvironment這個類有什么作用
TableEnvironment是Table API和SQL集成的核心概念,這個類主要用來:
- 在內部 catalog 中注冊表
- 注冊外部 catalog
- 執行SQL查詢
- 注冊用戶定義(標量,表或聚合)函式
- 將DataStream或DataSet轉換為表
- 持有對 ExecutionEnvironment 或 StreamExecutionEnvironment 的參考
21、Flink SQL的實作原理是什么?是如何實作 SQL 決議的呢?
首先大家要知道 Flink 的SQL決議是基于Apache Calcite這個開源框架,

基于此,一次完整的SQL決議程序如下:
- 用戶使用對外提供Stream SQL的語法開發業務應用
- 用calcite對StreamSQL進行語法檢驗,語法檢驗通過后,轉換成calcite的邏輯樹節點;最終形成calcite的邏輯計劃
- 采用Flink自定義的優化規則和calcite火山模型、啟發式模型共同對邏輯樹進行優化,生成最優的Flink物理計劃
- 對物理計劃采用janino codegen生成代碼,生成用低階API DataStream 描述的流應用,提交到Flink平臺執行
Flink中級
22、Flink是如何支持批流一體的?

本道面試題考察的其實就是一句話:Flink的開發者認為批處理是流處理的一種特殊情況,批處理是有限的流處理,Flink 使用一個引擎支持了DataSet API 和 DataStream API,
23、Flink是如何做到高效的資料交換的?
在一個Flink Job中,資料需要在不同的task中進行交換,整個資料交換是由 TaskManager 負責的,TaskManager 的網路組件首先從緩沖buffer中收集records,然后再發送,Records 并不是一個一個被發送的,二是積累一個批次再發送,batch 技術可以更加高效的利用網路資源,
24、Flink是如何做容錯的?
Flink實作容錯主要靠強大的CheckPoint機制和State機制,Checkpoint 負責定時制作分布式快照、對程式中的狀態進行備份;State 用來存盤計算程序中的中間狀態,
24、Flink 分布式快照的原理是什么?
Flink的分布式快照是根據Chandy-Lamport演算法量身定做的,簡單來說就是持續創建分布式資料流及其狀態的一致快照,

核心思想是在 input source 端插入 barrier,控制 barrier 的同步來實作 snapshot 的備份和 exactly-once 語意,
25、Flink是如何保證Exactly-once語意的?
Flink通過實作兩階段提交和狀態保存來實作端到端的一致性語意, 分為以下幾個步驟:
- 開始事務(beginTransaction)創建一個臨時檔案夾,來寫把資料寫入到這個檔案夾里面
- 預提交(preCommit)將記憶體中快取的資料寫入檔案并關閉
- 預提交(preCommit)將記憶體中快取的資料寫入檔案并關閉
- 預提交(preCommit)將記憶體中快取的資料寫入檔案并關閉
- 若失敗發生在預提交成功后,正式提交前,可以根據狀態來提交預提交的資料,也可洗掉預提交的資料
26、Flink 的 kafka 連接器有什么特別的地方?
Flink原始碼中有一個獨立的connector模塊,所有的其他connector都依賴于此模塊,Flink 在1.9版本發布的全新kafka連接器,摒棄了之前連接不同版本的kafka集群需要依賴不同版本的connector這種做法,只需要依賴一個connector即可,
27、說說 Flink的記憶體管理是如何做的?
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本身的資料結構,
28、說說 Flink的序列化如何做的?
Java本身自帶的序列化和反序列化的功能,但是輔助資訊占用空間比較大,在序列化物件時記錄了過多的類資訊,Apache Flink摒棄了Java原生的序列化方法,以獨特的方式處理資料型別和序列化,包含自己的型別描述符,泛型型別提取和型別序列化框架,TypeInformation 是所有型別描述符的基類,它揭示了該型別的一些基本屬性,并且可以生成序列化器,TypeInformation 支持以下幾種型別:
BasicTypeInfo: 任意Java 基本型別或 String 型別
BasicArrayTypeInfo: 任意Java基本型別陣列或 String 陣列
WritableTypeInfo: 任意 Hadoop Writable 介面的實作類
WritableTypeInfo: 任意 Hadoop Writable 介面的實作類
CaseClassTypeInfo: 任意的 Scala CaseClass(包括 Scala tuples)
CaseClassTypeInfo: 任意的 Scala CaseClass(包括 Scala tuples)
GenericTypeInfo: 任意無法匹配之前幾種型別的類
針對前六種型別資料集,Flink皆可以自動生成對應的TypeSerializer,能非常高效地對資料集進行序列化和反序列化,
29、Flink中的Window出現了資料傾斜,你有什么解決辦法?
window產生資料傾斜指的是資料在不同的視窗內堆積的資料量相差過多,本質上產生這種情況的原因是資料源頭發送的資料量速度不同導致的,出現這種情況一般通過兩種方式來解決:
- 在資料進入視窗前做預聚合
- 重新設計視窗聚合的key
30、Flink中在使用聚合函式 GroupBy、Distinct、KeyBy 等函式時出現資料熱點該如何解決?
資料傾斜和資料熱點是所有大資料框架繞不過去的問題,處理這類問題主要從3個方面入手:
- 在業務上規避這類問題
例如一個假設訂單場景,北京和上海兩個城市訂單量增長幾十倍,其余城市的資料量不變,這時候我們在進行聚合的時候,北京和上海就會出現資料堆積,我們可以單獨資料北京和上海的資料,
- Key的設計上
把熱key進行拆分,比如上個例子中的北京和上海,可以把北京和上海按照地區進行拆分聚合,
- 引數設定
Flink 1.9.0 SQL(Blink Planner) 性能優化中一項重要的改進就是升級了微批模型,即 MiniBatch,原理是快取一定的資料后再觸發處理,以減少對State的訪問,從而提升吞吐和減少資料的輸出量,
31、Flink任務延遲高,想解決這個問題,你會如何入手?
在Flink的后臺任務管理中,我們可以看到Flink的哪個算子和task出現了反壓,最主要的手段是資源調優和算子調優,資源調優即是對作業中的Operator的并發數(parallelism)、CPU(core)、堆記憶體(heap_memory)等引數進行調優,作業引數調優包括:并行度的設定,State的設定,checkpoint的設定,
32、Flink是如何處理反壓的?
Flink 內部是基于 producer-consumer 模型來進行訊息傳遞的,Flink的反壓設計也是基于這個模型,Flink 使用了高效有界的分布式阻塞佇列,就像 Java 通用的阻塞佇列(BlockingQueue)一樣,下游消費者消費變慢,上游就會受到阻塞,
33、Flink的反壓和Strom有哪些不同?
Storm 是通過監控 Bolt 中的接收佇列負載情況,如果超過高水位值就會將反壓資訊寫到 Zookeeper ,Zookeeper 上的 watch 會通知該拓撲的所有 Worker 都進入反壓狀態,最后 Spout 停止發送 tuple,Flink中的反壓使用了高效有界的分布式阻塞佇列,下游消費變慢會導致發送端阻塞,二者最大的區別是Flink是逐級反壓,而Storm是直接從源頭降速,
34、 Operator Chains(算子鏈)這個概念你了解嗎?
為了更高效地分布式執行,Flink會盡可能地將operator的subtask鏈接(chain)在一起形成task,每個task在一個執行緒中執行,將operators鏈接成task是非常有效的優化:它能減少執行緒之間的切換,減少訊息的序列化/反序列化,減少資料在緩沖區的交換,減少了延遲的同時提高整體的吞吐量,這就是我們所說的算子鏈,
35、說說Flink1.9的新特性?
- 支持hive讀寫,支持UDF
- Flink SQL TopN和GroupBy等優化
- Checkpoint跟savepoint針對實際業務場景做了優化
- Flink state查詢
36、消費kafka資料的時候,如何處理臟資料?
可以在處理前加一個fliter算子,將不符合規則的資料過濾出去,
Flink高級
37、Flink Job的提交流程
用戶提交的Flink Job會被轉化成一個DAG任務運行,分別是:StreamGraph、JobGraph、ExecutionGraph,Flink中JobManager與TaskManager,JobManager與Client的互動是基于Akka工具包的,是通過訊息驅動,整個Flink Job的提交還包含著ActorSystem的創建,JobManager的啟動,TaskManager的啟動和注冊,
38、Flink所謂"三層圖"結構是哪幾個"圖"?
一個Flink任務的DAG生成計算圖大致經歷以下三個程序:
StreamGraph 最接近代碼所表達的邏輯層面的計算拓撲結構,按照用戶代碼的執行順序向StreamExecutionEnvironment添加StreamTransformation構成流式圖,
JobGraph 從StreamGraph生成,將可以串聯合并的節點進行合并,設定節點之間的邊,安排資源共享slot槽位和放置相關聯的節點,上傳任務所需的檔案,設定檢查點配置等,相當于經過部分初始化和優化處理的任務圖,
ExecutionGraph 由JobGraph轉換而來,包含了任務具體執行所需的內容,是最貼近底層實作的執行圖,
39、JobManger在集群中扮演了什么角色?
JobManager 負責整個 Flink 集群任務的調度以及資源的管理,從客戶端中獲取提交的應用,然后根據集群中 TaskManager 上 TaskSlot 的使用情況,為提交的應用分配相應的 TaskSlot 資源并命令 TaskManager 啟動從客戶端中獲取的應用,JobManager 相當于整個集群的 Master 節點,且整個集群有且只有一個活躍的 JobManager ,負責整個集群的任務管理和資源管理,JobManager 和 TaskManager 之間通過 Actor System 進行通信,獲取任務執行的情況并通過 Actor System 將應用的任務執行情況發送給客戶端,同時在任務執行的程序中,Flink JobManager 會觸發 Checkpoint 操作,每個 TaskManager 節點 收到 Checkpoint 觸發指令后,完成 Checkpoint 操作,所有的 Checkpoint 協調程序都是在 Fink JobManager 中完成,當任務完成后,Flink 會將任務執行的資訊反饋給客戶端,并且釋放掉 TaskManager 中的資源以供下一次提交任務使用,
40、JobManger在集群啟動程序中起到什么作用?
JobManager的職責主要是接收Flink作業,調度Task,收集作業狀態和管理TaskManager,它包含一個Actor,并且做如下操作:
RegisterTaskManager: 它由想要注冊到JobManager的TaskManager發送,注冊成功會通過AcknowledgeRegistration訊息進行Ack,
SubmitJob: 由提交作業到系統的Client發送,提交的資訊是JobGraph形式的作業描述資訊,
CancelJob: 請求取消指定id的作業,成功會回傳CancellationSuccess,否則回傳CancellationFailure,
UpdateTaskExecutionState: 由TaskManager發送,用來更新執行節點(ExecutionVertex)的狀態,成功則回傳true,否則回傳false,
RequestNextInputSplit: TaskManager上的Task請求下一個輸入split,成功則回傳NextInputSplit,否則回傳null,
JobStatusChanged: 它意味著作業的狀態(RUNNING, CANCELING, FINISHED,等)發生變化,這個訊息由ExecutionGraph發送,
41、TaskManager在集群中扮演了什么角色?
TaskManager 相當于整個集群的 Slave 節點,負責具體的任務執行和對應任務在每個節點上的資源申請和管理,客戶端通過將撰寫好的 Flink 應用編譯打包,提交到 JobManager,然后 JobManager 會根據已注冊在 JobManager 中 TaskManager 的資源情況,將任務分配給有資源的 TaskManager節點,然后啟動并運行任務,TaskManager 從 JobManager 接收需要部署的任務,然后使用 Slot 資源啟動 Task,建立資料接入的網路連接,接收資料并開始資料處理,同時 TaskManager 之間的資料互動都是通過資料流的方式進行的,可以看出,Flink 的任務運行其實是采用多執行緒的方式,這和 MapReduce 多 JVM 進行的方式有很大的區別,Flink 能夠極大提高 CPU 使用效率,在多個任務和 Task 之間通過 TaskSlot 方式共享系統資源,每個 TaskManager 中通過管理多個 TaskSlot 資源池進行對資源進行有效管理,
42、TaskManager在集群啟動程序中起到什么作用?
TaskManager的啟動流程較為簡單:
啟動類:org.apache.flink.runtime.taskmanager.TaskManager
核心啟動方法 : selectNetworkInterfaceAndRunTaskManager
啟動后直接向JobManager注冊自己,注冊完成后,進行部分模塊的初始化,
43、Flink 計算資源的調度是如何實作的?
TaskManager中最細粒度的資源是Task slot,代表了一個固定大小的資源子集,每個TaskManager會將其所占有的資源平分給它的slot,
通過調整 task slot 的數量,用戶可以定義task之間是如何相互隔離的,每個 TaskManager 有一個slot,也就意味著每個task運行在獨立的 JVM 中,每個 TaskManager 有多個slot的話,也就是說多個task運行在同一個JVM中,
通過調整 task slot 的數量,用戶可以定義task之間是如何相互隔離的,每個 TaskManager 有一個slot,也就意味著每個task運行在獨立的 JVM 中,每個 TaskManager 有多個slot的話,也就是說多個task運行在同一個JVM中,

44、簡述Flink的資料抽象及資料交換程序?
Flink 為了避免JVM的固有缺陷例如java物件存盤密度低,FGC影響吞吐和回應等,實作了自主管理記憶體,MemorySegment就是Flink的記憶體抽象,默認情況下,一個MemorySegment可以被看做是一個32kb大的記憶體塊的抽象,這塊記憶體既可以是JVM里的一個byte[],也可以是堆外記憶體(DirectByteBuffer),在MemorySegment這個抽象之上,Flink在資料從operator內的資料物件在向TaskManager上轉移,預備被發給下個節點的程序中,使用的抽象或者說記憶體物件是Buffer,對接從Java物件轉為Buffer的中間物件是另一個抽象StreamRecord,
45、Flink 中的分布式快斬訓制是如何實作的?
Flink的容錯機制的核心部分是制作分布式資料流和操作算子狀態的一致性快照, 這些快照充當一致性checkpoint,系統可以在發生故障時回滾, Flink用于制作這些快照的機制在“分布式資料流的輕量級異步快照”中進行了描述, 它受到分布式快照的標準Chandy-Lamport演算法的啟發,專門針對Flink的執行模型而定制,

barriers在資料流源處被注入并行資料流中,快照n的barriers被插入的位置(我們稱之為Sn)是快照所包含的資料在資料源中最大位置,例如,在Apache Kafka中,此位置將是磁區中最后一條記錄的偏移量, 將該位置Sn報告給checkpoint協調器(Flink的JobManager),然后barriers向下游流動,當一個中間操作算子從其所有輸入流中收到快照n的barriers時,它會為快照n發出barriers進入其所有輸出流中, 一旦sink操作算子(流式DAG的末端)從其所有輸入流接收到barriers n,它就向checkpoint協調器確認快照n完成,在所有sink確認快照后,意味快照著已完成,一旦完成快照n,job將永遠不再向資料源請求Sn之前的記錄,因為此時這些記錄(及其后續記錄)將已經通過整個資料流拓撲,也即是已經被處理結束,
46、簡單說說FlinkSQL是如何實作的?
Flink 將 SQL 校驗、SQL 決議以及 SQL 優化交給了Apache Calcite,Calcite 在其他很多開源專案里也都應用到了,譬如 Apache Hive, Apache Drill, Apache Kylin, Cascading,Calcite 在新的架構中處于核心的地位,如下圖所示,

構建抽象語法樹的事情交給了 Calcite 去做,SQL query 會經過 Calcite 決議器轉變成 SQL 節點樹,通過驗證后構建成 Calcite 的抽象語法樹(也就是圖中的 Logical Plan),另一邊,Table API 上的呼叫會構建成 Table API 的抽象語法樹,并通過 Calcite 提供的 RelBuilder 轉變成 Calcite 的抽象語法樹,然后依次被轉換成邏輯執行計劃和物理執行計劃,在提交任務后會分發到各個 TaskManager 中運行,在運行時會使用 Janino 編譯器編譯代碼后運行,
小結
本篇從Flink初級,再到中級,以及最后的Flink高級難度,對于Flink的常見面試題算是做了一個梳理,
想在大資料領域扎根,有所建樹的朋友可不能忽略對于Flink的"研究",作為未來大資料發展的大勢所趨,Flink勢必會更加的“火熱” !!!
看完還對Flink意猶未盡的朋友,可以嘗試去閱讀Flink的權威知識圖譜,關注“猿人菌”后臺回復“Flink知識圖譜”即可獲得,更有更多博主為大家準備的“大資料干糧”,隨時準備上車,期待您的加入!


一鍵三連,養成習慣~
文章持續更新,可以微信搜一搜「 猿人菌 」第一時間閱讀,思維導圖,大資料書籍,大資料高頻面試題,海量一線大廠面經,300G大資料全套視頻等你獲取…期待您的關注!
猜你喜歡
大資料面試殺招——Hive高頻考點,就怕你都會!
大資料面試殺招——Hadoop高頻考點,正在重繪你的認知!
大資料面試殺招——Spark高頻考點,必知必會!
CSDN認證博客專家
CSDN博客專家
大資料學者
追夢人
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/202516.html
標籤:其他
