Flink重磅 | Flink重構核心執行緒模型
最近,社群提交了一個新的Proposal: 《Change threading-model in StreamTask to a mailbox-based approach》(來自Ververica的Stefan Richter, Piotr Nowojski),用於改進當前StreamTask這一核心類的執行緒模型。這個Proposal可謂是千呼萬喚始出來,從去年就開始討論,之前一直遲遲沒有太大的動靜,最近終於給出了概要設計。接下來,我們就來簡單地介紹一下這個Proposal。
改進動機
改進的動機肯定來自於先前實現的不足或缺陷。StreamTask現有的執行緒模型存在著一些缺陷,它可能導致多個潛在的執行緒去併發訪問其內部狀態,比如事件處理以及檢查點的觸發執行緒。當前,他們都通過一個全域性鎖(檢查點鎖)來保證彼此互斥。這種機制有一些劣勢:
-
鎖物件必須在類的各種互斥訪問的程式碼段中進行傳遞,程式碼可讀性很差,使用不當或者漏用則容易造成許多難以定位的問題;
-
設計不夠優雅,鎖物件暴露給了面向使用者的API(SourceContext)。
改進機制
改進機制希望採用類Actor模型的 Mailbox 機制來取代現有的多執行緒模型,變成:單執行緒 ( Mailbox 執行緒 ) + 阻塞佇列 ( Mail box ) 的形式。這樣action會入Mail Box,而對狀態的變更則由單一的執行緒來完成,這種方式阻止了資料的共享 ( 這是大部分情況下併發問題的萬惡之源 ) 。
當前檢查點鎖的使用場景分析
檢查點鎖用於實現對以下三個併發源之間對StreamTask的元件狀態的互斥訪問:
-
事件處理
-
檢查點
-
Processing-Time的定時器(Event time的觸發是同步的,可以歸屬到第一點 )
下一小節會介紹如何對這三個併發源的處理邏輯進行改進。
提議的改進點
文件所包含的改進點主要有如下四個。
1.Stream Task中的改變
預期會引入一個mailbox例項欄位,它的型別是一個阻塞佇列(ArrayBlockingQueue ) 。 Mailbox 主執行緒將承擔當前StreamTask#run()中的任務,不同於現有的實現,以上三個併發源相關的處理邏輯都將會變成letter事件入隊 Mailbox 並被順序處理。這些事件預期可能以Runnable作為共同抽象。虛擬碼如下:
BlockingQueue<Runnable> mailbox = ... void runMailboxProcessing() { //TODO: can become a cancel-event through mailbox eventually Runnable letter; while (isRunning()) { while ((letter = mailbox.poll()) != null) { letter.run(); } defaultAction(); } } void defaultAction() { // e.g. event-processing from an input }
當然這段程式碼只是描述了實現的核心思想,還有很多待優化的細節尚不明確。
2.客戶端使用檢查點鎖的通用實現
Mailbox 的概念其實沒有對外暴露,它被隱藏在Queue介面的後面,我們可以將Queue傳遞給檢查點鎖來保證向後的相容性。
3.事件生成與處理
基於 Mailbox 的機制將大大簡化這部分的邏輯,很多加鎖的程式碼段將可以被移除。當前的事件處理主迴圈也將被打破並改寫,當前的迴圈(One/TwoInputStreamTask):
while (running && inputProcessor.processInput())
將會被簡化為如下的每一次呼叫:
inputProcessor.processInput();
在再次檢查 Mailbox 的letter之前。
4.檢查點與定時觸發器
Mailbox 機制天然適合這兩種併發源(2,3)。試想一下,其實當前Flink的processing-timer就是用的佇列排隊非同步執行來實現的。
與遺留Source的相容性問題
由於歷史原因,當前Flink Source被實現為執行一個無限迴圈來進行事件生成,這種實現在後續也將會被進行重構(FLIP-27)。但這種模型跟 Mailbox 無法較好地相容,目前SourceFunction的Task實現是SourceStreamTask而常規運算元對應的Task則是StreamTask(SourceStreamTask繼承自StreamTask)。
相容的核心思想是以兩個不同的執行緒來獨立執行,SourceFunction對應的事件生成在一個執行緒上,而Mailbox是另一個執行緒,並且兩者以檢查點鎖來保持互斥。時序圖如下:
這樣針對遺留的Source迴圈還是以獨立的一套機制執行,而絕大部分運算元的task則執行在 Mailbox 執行緒上。
大家工作學習遇到HBase技術問題,把問題釋出到HBase技術社群論壇http://hbase.group,歡迎大家論壇上面提問留言討論。想了解更多HBase技術關注HBase技術社群公眾號(微訊號:hbasegroup),非常歡迎大家積極投稿。
技術社群
【HBase生態+Spark社群大群】
群福利:群內每週進行群直播技術分享及問答
加入方式1:https://dwz.cn/Fvqv066s?spm=a2c4e.11153940.blogcont688191.19.1fcd1351nOOPvI
加入方式2:釘釘掃碼加入