記錄一下個人看了一些Flink文章后的理解與個人關(guān)注點趟据,目錄如下队萤,
0. Overview
1. 基本概念
2. 并行Dataflow
3. 基本模塊
- JobManager
- TaskManagers
- Client
4. 組件棧
- Deployment層
- Runtime層
- API層
- Libraries層
5. 內(nèi)部原理
- 容錯機制
- 調(diào)度機制
- 迭代機制
- 反壓機制
6. Reference
Overview
基于Flink 1.4油吭。
先來看看大數(shù)據(jù)計算引擎的發(fā)展路線下愈,
- 第一代纽绍,hadoop的MapReduce
- 第二代,DAG框架的Tez势似,Oozie
- 第三代拌夏,Job內(nèi)部的DAG支持,以及強調(diào)實時計算履因,spark
- 第四代障簿,迭代,流栅迄,批站故,SQL
基本概念
source -> transformation -> sink
- stream是算子的中間結(jié)果數(shù)據(jù)
- transformation是一個操作,它對一個或多個輸入stream進行計算處理毅舆,輸出一個或多個結(jié)果stream
- streaming dataflow是一個執(zhí)行中的flink程序西篓,啟動于一個或多個source,結(jié)束于一個或多個sink
并行Dataflow
一個stream可以被分成多個stream分區(qū)(stream partition)憋活。
一個operator可以被分成多個operator subTask岂津。
基本模塊
flink類似spark,是一個基于master-slave風格的架構(gòu)余掖。
運行時runtime主要有2個進程寸爆,一個是JobManagers,另一個是TaskManagers盐欺;client不屬于運行時和程序執(zhí)行的一部分赁豆,而是用于準備dataflow并將其發(fā)送到JobManager。
jobManager(master)是flink系統(tǒng)的協(xié)調(diào)者冗美,負責接收flink job魔种,調(diào)度組成job的多個task的執(zhí)行;手機job的狀態(tài)信息粉洼,管理flink集群中從節(jié)點taskManager节预,
- registerTaskManager,在Flink集群啟動的時候属韧,TaskManager會向JobManager注冊
- submitJob安拟,F(xiàn)link程序內(nèi)部通過Client向JobManager提交Flink Job,其中在消息SubmitJob中以JobGraph形式描述了Job的基本信息
- cancelJob宵喂,請求取消一個Flink Job的執(zhí)行糠赦,CancelJob消息中包含了Job的ID
- updateTaskExecutionState,TaskManager向JobManager請求更新狀態(tài)信息
- requestNextInputSplit,運行在TaskManager上面的Task拙泽,請求獲取下一個要處理的輸入Split
- jobStatusChanged淌山,表示Flink Job的狀態(tài)發(fā)生的變化
taskManager是一個actor(akka),負責執(zhí)行計算的worker顾瞻,在其上執(zhí)行flink job的一組task泼疑。每個taskManager負責管理其所在節(jié)點上的資源信息,如mem, disk, network荷荤,在啟動的時候?qū)①Y源狀態(tài)向jobManager匯報退渗,
- 注冊階段,TaskManager會向JobManager注冊蕴纳,發(fā)送registerTaskManager消息
- 可操作階段氓辣,接收并處理與Task有關(guān)的消息,如SubmitTask袱蚓、CancelTask、FailTask
client几蜻,當用戶提交一個flink程序時喇潘,會首先創(chuàng)建一個client,該client首先會對用戶提交的flink程序進行預處理梭稚,并提交到flink集群中颖低,
- client需要從用戶提交的flink程序配置中獲取jobManager的地址,并建立到jobManager的連接弧烤,將flink job提交給jobManager
- client會將用戶提交的flink程序組裝成一個jobGraph忱屑,并且是以jobGraph的形式提交。一個jobGraph是一個flink dataflow暇昂,它是由多個jobVertex組成的DAG莺戒。JobManager會將一個JobGraph轉(zhuǎn)換映射為一個ExecutionGraph
組件棧
Flink是一個分層架構(gòu)的系統(tǒng),每一層所包含的組件都提供了特定的抽象急波,用來服務于上層組件从铲,
- Deployment層,涉及了Flink的部署模式
啟動flink yarn session的時候澄暮,
- 最左邊的模塊
Flink YARN Client
check requested resources (containers and memory) are available名段,檢查資源可得性 - Client uploads a jar that contains Flink and the configuration to HDFS,上傳代碼和配置
- Client request a
YARN container
to start theApplicationMaster
(AM泣懊,單個作業(yè)的資源管理和任務監(jiān)控模塊伸辟,以前是一個全局的JobTracker負責的,現(xiàn)在每個作業(yè)都一個)馍刮,啟動yarn AM - AM starts allocating the containers for Flink’s TaskManagers, which will download the jar file and the modified configuration from the HDFS
客戶端client負責向ResourceManager(RM)提交ApplicationMaster信夫,并查詢應用程序運行狀態(tài),ApplicationMaster(AM)負責向ResourceManager申請資源(以Container形式表示),并與NodeManager(NM)通信以啟動各個Container忙迁,此外脐彩,ApplicationMaster還負責監(jiān)控各個任務運行狀態(tài),并在失敗是為其重新申請資源姊扔。
flink RM Dispatcher惠奸,用于統(tǒng)一發(fā)布Job并監(jiān)控實例的運行。但是可以選擇是否使用Dispatcher恰梢。
- Runtime層佛南,提供了支持Flink計算的全部核心實現(xiàn)
- API層,實現(xiàn)了面向無界streaming的流處理和面向有界Batch的批處理接口
- Libraries層嵌言,F(xiàn)link應用框架層嗅回,CEP復雜事件處理、Table基于SQL-like的關(guān)系操作摧茴、FlinkML機器學習绵载、Gelly圖處理
內(nèi)部原理
容錯機制
Flink基于Checkpoint機制實現(xiàn)容錯,它的原理是不斷地生成分布式Streaming數(shù)據(jù)流Snapshot苛白。在流處理失敗時娃豹,通過這些Snapshot可以恢復數(shù)據(jù)流處理。
checkpoint, snapshot, stream aligning, exactly once, at least once
調(diào)度機制
在jobManager购裙,會接收到client提交的jobGraph形式的flink job懂版,并將其轉(zhuǎn)換映射為executionGraph
- jobGraph是一個job的用戶邏輯視圖表示,將一個用戶要對數(shù)據(jù)流進行的處理表示為單個DAG圖
- executionGraph是jobGraph的并行表示躏率,也就是實際jobManager調(diào)度一個job在taskManager上運行的邏輯視圖躯畴,也是一個DAG
上圖用戶提交的Flink Job對各個Operator進行的配置(從下往上),即data source的并行度設置為4(最底層1個data source薇芝,但是其parallel=4)蓬抄,MapFunction的并行度也為4(中間層),ReduceFunction的并行度為3(頂層)夯到。
迭代機制
機器學習和圖計算應用倡鲸,都會使用到迭代計算。flink通過迭代operator中定義step函數(shù)來實現(xiàn)迭代算法黄娘,包括Iterate和Delta Iterate兩類峭状,
反壓機制
flink使用了高效有界的分布式阻塞隊列,就像java通用的blockingQueue逼争。一個較慢的接收者會降低發(fā)送者的發(fā)送速率优床,因為一旦有界隊列滿了發(fā)送者會被阻塞。
- 當netty接收端發(fā)送數(shù)據(jù)時誓焦,為了將netty中的數(shù)據(jù)拷貝到task中(往task寫入數(shù)據(jù))胆敞,InputChannel會向其對應的緩沖池localBufferPool申請內(nèi)存塊着帽,
- 如果localBufferPool也沒有可用內(nèi)存塊且申請的數(shù)量還沒到池子(隊列)上限,則就向networkBufferPool申請內(nèi)存塊
- 如果localBufferPool已申請的數(shù)量達到上限了移层,或者networkBufferPool也沒有可用內(nèi)存塊仍翰,此時task的netty channel會暫停讀取,上游的發(fā)送端會立即響應停止發(fā)送观话,拓撲進入反壓狀態(tài)
- 當task線程寫數(shù)據(jù)到resultPartition時(task數(shù)據(jù)往外寫)予借,也會向池子請求內(nèi)存塊,如果沒有可用內(nèi)存塊時频蛔,也阻塞在請求內(nèi)存塊的地方灵迫,達到暫停寫入的目的
- 在一個內(nèi)存塊被消費完成之后(在輸出端是指內(nèi)存塊中的字節(jié)寫入到netty channel;在輸入端是指內(nèi)存塊中的字節(jié)被反序列化成對象)晦溪,會調(diào)用buffer.recycle()方法瀑粥,將內(nèi)存塊還給localBufferPool,如果localBufferPool中當前申請的數(shù)量超過了池子容量三圆,則localBufferPool會將該內(nèi)存塊回收給networkBufferPool狞换。如果沒超池子容量,則繼續(xù)留在localBufferPool中舟肉,減少反復申請的開銷
backPressure在流式計算系統(tǒng)中用于協(xié)調(diào)上哀澈、下游operator的處理速度。因為在一個stream上進行處理的多個operator之間度气,它們的處理速度和方式可能非常不同,所以就存在上游operator如果處理速度過快膨报,下游operator可能會堆積stream記錄磷籍。因此,對下游operator處理速度跟不上的情況现柠,如果下游operator能夠?qū)⒆约禾幚頎顟B(tài)傳播給上游operator院领,使得上游operator處理速度慢下來,從而緩解上述問題够吩。
JobManager會反復調(diào)用Task運行所在線程的Thread.getStackTrace()比然,默認情況下,JobManager會每隔50ms觸發(fā)對每個Task依次進行100次堆棧跟蹤調(diào)用周循,根據(jù)調(diào)用調(diào)用結(jié)果來確定Backpressure强法,通過計算得到一個比值radio來確定當前運行Job的Backpressure狀態(tài)。在Web界面上可以看到這個Radio值湾笛,它表示在一個內(nèi)部方法調(diào)用中阻塞(Stuck)的堆棧跟蹤次數(shù)饮怯,例如,radio=0.01嚎研,表示100次中僅有1次方法調(diào)用阻塞蓖墅。Flink目前定義了如下Backpressure狀態(tài):
- OK: 0 <= Ratio <= 0.10
- LOW: 0.10 < Ratio <= 0.5
- HIGH: 0.5 < Ratio <= 1