作者: 王紹翾(大沙)
本文來自於王紹翾在2018年08月11日Flink China Meetup。 王紹翾,花名“大沙”,加州大學聖迭戈分校計算機工程的博士,Apache Flink Commiter。目前在阿里負責Flink平臺以及生態的一些工作。
本文內容如下:
流計算核心技術
Flink是德國data Artisans創造的,早期Flink主要是做偏批計算的,但是Spark在批處理上已經有一定優勢,正面競爭沒什麼意義,於是改變方向,基於chandy-lamport演算法開始做流計算,完成後完美的解決了低延遲問題和狀態管理。
低延遲,快速容錯
低延遲是Flink源生的,當然保證了快速容錯。大資料計算中job總是會失敗,所以需要能夠快速的恢復。如果平時延遲很低,但是job一失敗,恢復幾分鐘,肯定是無法接受的。
通用的API,易用性
Flink有了基礎的能力後,開始考慮通用的API,最開始的時候有了一些Java和Scala的一些API。但是發展到一定程度之後,因為API不只是開放於開發,而是所有使用者。怎麼樣更容易的滿足使用者的需求和支援使用者,這是流計算的很核心的一點。
彈性,高效能
彈性,高效能是大資料不變的主題。怎麼樣確保引擎在上千臺機器不出問題的執行,scalability很重要,包括Spark早期到一定規模遇到很多問題,當然Blink已經完美的解決了所有問題。在效能上,Flink不僅是在流計算還是批處理上已經有了絕對的優勢。
流和批的統一
Flink的早期interface是非常弱的,包括Spark早期也是,於是流計算的社群開始討論流計算的SQL到底是什麼樣子的,於是形成了兩派風格,一派是認為Streaming SQL是一種different SQL跟Batch Sql,另一派推的SQL跟Batch SQL是完全一致的。
為什麼會說完全一致?流計算跟批計算一個基本的區別是,都是計算,但是流計算需要提前看到結果,這需要將結果提前發出,但是後面過來的資料會對前面的結果進行修正,所以流計算跟批計算比較大的區別就是資料提前發出和資料修正,最終保證資料正確。
怎麼來處理這個問題:
-
首先要告訴使用者API,怎麼樣去計算完全是使用者的語義
-
另外兩點就是什麼時候發出去,什麼時候修正,這些跟SQL本身描述是沒什麼關係的
-
所以傳統的ANSI SQL是完全可以描述流計算的,Flink SQL的語義就是ANSI SQL
使用者要什麼?
-
高效能
-
高階分析
-
容易開發
-
開箱即用
-
低延遲
我們說的是大資料,而不僅僅是流計算。對於功能型的使用者,更關心的是易用性,如何做好分析,如何更好的開發,如何更容易上手。我沒學過計算機,但是學的是其他任何的一個行業可能是統計,生物,建築,金融……,怎麼樣才能更快的開發出來。
假如老闆說,今天要部署Flink了,於是給了你50臺機器,到了第二天,你部署完畢了,作業跑起來了,老闆嚇呆了,覺得你KPI非常的棒。所以開箱即用,更容易的去開發對使用者來說非常需要的。
傳統的批計算要追求performance,目前流計算對performance需求越來越大。
一.Flink的現狀和未來
知道了使用者想要的,我們看Flink現狀。
Flink目前被廣泛的用於超低延遲流計算場景中,但是Flink在批處理上其實已經有非常高的處理效能,並且在API上流和批是統一的,在效能上和易用性上都有不錯的表現。
帶著已知的事情和一點點未知的事情,來看看Flink能做的一些事情:流計算已經非常成熟,批計算,AI的計算,包括TF ON Flink,training也好,prediction也好,任何計算。另外還有很大的一塊IOT,Hadoop Summit 中強調各種資料中,流的也好,批的也好,最終IOT的資料最大。雖然不是每個公司都會接觸IOT,但它絕對是一個很大的future。
1.阿里巴巴的Blink
Blink1.0實際上是enterprise版的Flink,主要專注與流計算上。
Blink2.0是一個統一的引擎,支援流處理和批處理,在其他方面,例如AI方面做了很大的改進,在batch效能上已經遠超Spark。回饋社群也是這個版本。
2.Flink SQL Engine的架構
我們先看一眼Flink SQL Engine,從上面開始有Query的API,有Query Optimization,下來會翻譯到DataSteam或者DataSet運算元,然後Runtime,在各個叢集上執行。這個架構在裡面展開DataSteam和DataSet,可以看到幾個比較大的問題:
-
在設計上,從來沒想過統一起來。最終Query Optimization翻譯完之後到DataStream或者DataSet是完全兩條獨立的pipline,而且往下的程式碼是全完不復用的
-
再一個可以看批計算,DataSet下面還有一個Optimized Plan,這兩層優化給統一帶來很大的困難
3.Blink SQL Engine的架構
我們把整個的SQL Engine換成上圖所示。從上層開始的API,到下面的Query Processor包括了Query Optimizer和Query Executor,當做完這些發現,程式碼大量的減少並被複用,一個job用同樣的SQL只需要標識是Batch Mode還是Stream Mode,就會得到一樣的結果。
從API開始,翻譯成Logical Plan經過Optimizer,再到類似寫DataStream的這種Physical Plan,我們可以看到在Optimizer之前的批跟流完全一樣,SQL一樣,Logical Plan也一樣。即使用者腦子裡想的東西,在批和流中一模一樣。
二.優化流計算的挑戰和機遇
在Optimizer之後,流和批有些不一樣。
批和流在一樣的地方就是一些簡單的filter,predicate,projection還有joining reorder。
區別就是在流計算我們不去支援sort,因為每條資料一來,就要對之前的資料更新,就好比我讓在座的各位稱個體重,排個序,突然在座的哪位去上個廁所,體重變了,會影響很多人的排序,就需要改變大量的結果。所以在流上不去考慮類似sort的東西。但是流上因為有state的使用,怎麼樣把它的效能變得很高,減少Retraction,怎麼樣讓使用者的SLA用MicroBatch去優化。
流計算上一旦變成SQL,就得跑標準的SQL測試,TPC-H,TPC-DS。我們看這個TPCH13,這個是測試的是用一張Customer表和一張Order表,需要做一次join和count。
這個計算在批計算上處理很方便,因為兩個表就在那兒,它明顯的知道使用者表很小,它會把使用者表hash到各個地方先cache下來,然後讓訂單表流過去,這個效能非常高,因為Order這張最大的表只是不停的流而不落地。
在流計算上怎麼處理呢?因為根本不知道資料長什麼樣子,每邊一來就得存下來,左邊的Customer表來了之後存下來,因為一行只需存一個,所以用的是ValueState,但是每個使用者有很多的Order,右邊的Order表則需要使用MapState,這個計算量非常大,效能非常差。怎麼優化呢,我們使用的SQL就有一個天然的好處Optimizer。SQL Engine有個rule就是轉移了上面的countAgg和下面的join,SQL裡面有個代數優化,先不考慮資料是什麼樣子,我從代數上認為中間這幅圖和最右邊這幅圖的計算結果是一致的,所以我可以先對兩邊進行agg,我可以在Order那一邊先把每個使用者count完變成一行只有一個資料,預先處理好資料,這樣把Order表壓縮成和customer一樣大小的表,join上的開銷省了很多,state從龐大的MapState變成了輕量的ValueState,效能提升了25倍,這也是為什麼SQL是有意義的。
對於一些流計算的特有優化,比如知道使用者的SLA,有段時間就可以去配置mini-batch 。
做全網的count,那麼用以上左圖的紅色和紫色,分別傳送到一個地方去統計,不做預處理的話,紅色節點負載過高,很快就導致反壓。最好的辦法就是紅色和紫色的節點現在上游chain起來做預處理,相當於把一個聚合分成兩部分,先做count,再做sum。
當然上面的方案不總是有效,比如count distinct,它也需要按顏色group by還要按某一列去distinct,導致不同的資料無法被預聚合。所以在local-global上除了chain的方式還有shuffle的方式,相當於shuffle兩次,也就是大家在流計算中所說的打散。第一次按distinct key去shuffle,第二次用group by的key去做shuffle。當然這些都是SQL Engine都會自動幫你做。
三.融入開源社群,參與開源開發
開源社群除了coding的貢獻外,還有文件,生態,社群,產品,只要對這個開源的產品有幫助。更重要的是你在社群裡面的活躍度,為社群解決什麼問題。
作為一個使用者你可以提出一些問題,去mailing list回答問題,去做testing和report等等
作為一個開發你可以去review code,包括自己的idea,大的重構。還可以幫助其他使用者回答問題。
Mailing lists:
dev@flink.apache.org 開發者提問交流。
user@flink.apache.org 使用者提問交流。
JIRA: issues.apache.org/jira/browse…
是社群的工作方式。Bug,feature,improvements提出的地方,每一個code的貢獻都會關聯到一個JIRA issue。
Wiki: cwiki.apache.org/confluence/…
有許多文件,包括大量FLIP,當然也等著大家contribution。
那如何要參與開發呢?
-
你要在社群提出自己的想法,收集一些建議。
-
你還要了PMC,commiter對分別對哪部分code負責,你可以聯絡他,讓他幫你review。
-
可以依靠JIRA處理一些小的問題,但是比較重大的改進還是需要依靠FLIP。
-
完成之後,就需要去貢獻程式碼,當然要保證程式碼的質量,加入很多test case,當你pull request時,會有很多人review你的程式碼,沒有問題後就會merge上去。