Apache Flink 的命脈
"命脈" 即生命與血脈,常喻極爲重要的事物。系列的首篇,首篇的首段不聊Apache Flink的歷史,不聊Apache Flink的架構,不聊Apache Flink的功能特性,咱們用一句話聊聊什麼是 Apache Flink 的命脈?個人答案是:Apache Flink 是以"批是流的特例"的認知進行系統設計的。java
咱們常常據說 "天下武功,惟快不破",大概意思是說 "任何一種武功的招數都是有拆招的,惟有速度快,快到對手根原本不及反應,你就將對手KO了,對手沒有機會拆招,因此惟快不破"。 那麼這與Apache Flink有什麼關係呢?Apache Flink是Native Streaming(純流式)計算引擎,在實時計算場景最關心的就是"快",也就是 "低延時"。面試
就目前最熱的兩種流計算引擎Apache Spark和Apache Flink而言,誰最終會成爲No1呢?單從 "低延時" 的角度看,Spark是Micro Batching(微批式)模式,最低延遲Spark能達到0.5~2秒左右,Flink是Native Streaming(純流式)模式,最低延時能達到微秒。很顯然是相對較晚出道的 Apache Flink 後來者居上。 那麼爲何Apache Flink能作到如此之 "快"呢?根本緣由是Apache Flink 設計之初就認爲 "批是流的特例",整個系統是Native Streaming設計,每來一條數據都可以觸發計算。相對於須要靠時間來積攢數據Micro Batching模式來講,在架構上就已經佔據了絕對優點。數據庫
那麼爲何關於流計算會有兩種計算模式呢?歸其根本是由於對流計算的認知不一樣,是"流是批的特例" 和 "批是流的特例" 兩種不一樣認知產物。緩存
Micro Batching 模式
Micro-Batching 計算模式認爲 "流是批的特例", 流計算就是將接二連三的批進行持續計算,若是批足夠小那麼就有足夠小的延時,在必定程度上知足了99%的實時計算場景。那麼那1%爲啥作不到呢?這就是架構的魅力,在Micro-Batching模式的架構實現上就有一個天然流數據流入系統進行攢批的過程,這在必定程度上就增長了延時。具體以下示意圖:網絡
很顯然Micro-Batching模式有其天生的低延時瓶頸,但任何事物的存在都有兩面性,在大數據計算的發展歷史上,最初Hadoop上的MapReduce就是優秀的批模式計算框架,Micro-Batching在設計和實現上能夠借鑑不少成熟實踐。架構
Native Streaming 模式
Native Streaming 計算模式認爲 "批是流的特", 這個認知更貼切流的概念,好比一些監控類的消息流,數據庫操做的binlog,實時的支付交易信息等等天然流數據都是一條,一條的流入。Native Streaming 計算模式每條數據的到來都進行計算,這種計算模式顯得更天然,而且延時性能達到更低。具體以下示意圖:框架
很明顯Native Streaming模式佔據了流計算領域 "低延時" 的核心競爭力,固然Native Streaming模式的實現框架是一個歷史先河,第一個實現
Native Streaming模式的流計算框架是第一個吃螃蟹的人,須要面臨更多的挑戰,後續章節咱們會慢慢介紹。固然Native Streaming模式的框架實現上面很容易實現Micro-Batching和Batching模式的計算,Apache Flink就是Native Streaming計算模式的流批統一的計算引擎。機器學習
Apache Flink 按不一樣的需求支持Local,Cluster,Cloud三種部署模式,同時Apache Flink在部署上可以與其餘成熟的生態產品進行完美集成,如 Cluster模式下能夠利用YARN(Yet Another Resource Negotiator)/Mesos集成進行資源管理,在Cloud部署模式下能夠與GCE(Google Compute Engine), EC2(Elastic Compute Cloud)進行集成。分佈式
Local 模式
該模式下Apache Flink 總體運行在Single JVM中,在開發學習中使用,同時也能夠安裝到不少端類設備上。參考oop
Cluster模式
該模式是典型的投產的集羣模式,Apache Flink 既能夠Standalone的方式進行部署,也能夠與其餘資源管理系統進行集成部署,好比與YARN進行集成。Standalone Cluster 參考 YARN Cluster 參考
這種部署模式是典型的Master/Slave模式,咱們以Standalone Cluster模式爲例示意以下:
其中JM(JobManager)是Master,TM(TaskManager)是Slave,這種Master/Slave模式有一個典型的問題就是SPOF(single point of failure), SPOF如何解決呢?Apache Flink 又提供了HA(High Availability)方案,也就是提供多個Master,在任什麼時候候總有一個JM服役,N(N>=1)個JM候選,進而解決SPOF問題,示意以下:
在實際的生產環境咱們都會配置HA方案,目前Alibaba內部使用的也是基於YARN Cluster的HA方案。
Cloud 模式
該模式主要是與成熟的雲產品進行集成,Apache Flink官網介紹了Google的GCE 參考,Amazon的EC2 參考,在Alibaba咱們也能夠將Apache Flink部署到Alibaba的ECS(Elastic Compute Service)。
完善的容錯機制
什麼是容錯
容錯(Fault Tolerance) 是指容忍故障,在故障發生時可以自動檢測出來並使系統可以自動回覆正常運行。當出現某些指定的網絡故障、硬件故障、軟件錯誤時,系統仍能執行規定的一組程序,或者說程序不會因系統中的故障而停止,而且執行結果也不會因系統故障而引發計算差錯。
容錯的處理模式
在一個分佈式系統中因爲單個進程或者節點宕機都有可能致使整個Job失敗,那麼容錯機制除了要保證在遇到非預期狀況系統可以"運行"外,還要求能"正確運行",也就是數據能按預期的處理方式進行處理,保證計算結果的正確性。計算結果的正確性取決於系統對每一條計算數據處理機制,通常有以下三種處理機制:
-
At Most Once:最多消費一次,這種處理機制會存在數據丟失的可能。
-
At Least Once:最少消費一次,這種處理機制數據不會丟失,可是有可能重複消費。
-
Exactly Once:精確一次,不管何種狀況下,數據都只會消費一次,這種機制是對數據準確性的最高要求,在金融支付,銀行帳務等領域必須採用這種模式。
Apache Flink的容錯機制
Apache Flink的Job會涉及到3個部分,外部數據源(External Input), Flink內部數據處理(Flink Data Flow)和外部輸出(External Output)。以下示意圖:
目前Apache Flink 支持兩種數據容錯機制:
-
At Least Once
-
Exactly Once
其中 Exactly Once 是最嚴格的容錯機制,該模式要求每條數據必須處理且僅處理一次。那麼對於這種嚴格容錯機制,一個完整的Flink Job容錯要作到 End-to-End 的 容錯必須結合三個部分進行聯合處理,根據上圖咱們考慮三個場景:
系統內部容錯
Apache Flink利用Checkpointing機制來處理容錯,Checkpointing的理論基礎 Stephan 在 Lightweight Asynchronous Snapshots for Distributed Dataflows 進行了細節描述,該機制源於有K. MANI CHANDY和LESLIE LAMPORT 發表的 Determining-Global-States-of-a-Distributed-System Paper。Apache Flink 基於Checkpointing機制對Flink Data Flow實現了At Least Once 和 Exactly Once 兩種容錯處理模式。
Apache Flink Checkpointing的內部實現會利用 Barriers,StateBackend等後續章節會詳細介紹的技術來將數據的處理進行Marker。Apache Flink會利用Barrier將整個流進行標記切分,以下示意圖:
這樣Apache Flink的每一個Operator都會記錄當前成功處理的Checkpoint,若是發生錯誤,就會從上一個成功的Checkpoint開始繼續處理後續數據。好比 Soruce Operator會將讀取外部數據源的Position實時的記錄到Checkpoint中,失敗時候會從Checkpoint中讀取成功的position繼續精準的消費數據。每一個算子會在Checkpoint中記錄本身恢復時候必須的數據,好比流的原始數據和中間計算結果等信息,在恢復的時候從Checkpoint中讀取並持續處理流數據。
外部Source容錯
Apache Flink 要作到 End-to-End 的 Exactly Once 須要外部Source的支持,好比上面咱們說過 Apache Flink的Checkpointing機制會在Source節點記錄讀取的Position,那就須要外部數據提供讀取的Position和支持根據Position進行數據讀取。
外部Sink容錯
Apache Flink 要作到 End-to-End 的 Exactly Once 相對比較困難,如上場景三所述,當Sink Operator節點宕機,從新恢復時候根據Apache Flink 內部系統容錯 exactly once的保證,系統會回滾到上次成功的Checkpoin繼續寫入,可是上次成功Checkpoint以後當前Checkpoint未完成以前已經把一部分新數據寫入到kafka了. Apache Flink自上次成功的Checkpoint繼續寫入kafka,就形成了kafka再次接收到一份一樣的來自Sink Operator的數據,進而破壞了End-to-End 的 Exactly Once 語義(重複寫入就變成了At Least Once了),若是要解決這一問題,Apache Flink 利用Two phase commit(兩階段提交)的方式來進行處理。本質上是Sink Operator 須要感知總體Checkpoint的完成,並在總體Checkpoint完成時候將計算結果寫入Kafka。
流批統一的計算引擎
批與流是兩種不一樣的數據處理模式,如Apache Storm只支持流模式的數據處理,Apache Spark只支持批(Micro Batching)模式的數據處理。那麼Apache Flink 是如何作到既支持流處理模式也支持批處理模式呢?
統一的數據傳輸層
開篇咱們就介紹Apache Flink 的 "命脈"是以"批是流的特例"爲導向來進行引擎的設計的,系統設計成爲 "Native Streaming"的模式進行數據處理。那麼Apache FLink將批模式執行的任務看作是流式處理任務的特殊狀況,只是在數據上批是有界的(有限數量的元素)。
Apache Flink 在網絡傳輸層面有兩種數據傳輸模式:
-
PIPELINED模式 - 即一條數據被處理完成之後,馬上傳輸到下一個節點進行處理。
-
BATCH 模式 - 即一條數據被處理完成後,並不會馬上傳輸到下一個節點進行處理,而是寫入到緩存區,若是緩存寫滿就持久化到本地硬盤上,最後當全部數據都被處理完成後,纔將數據傳輸到下一個節點進行處理。
對於批任務而言一樣能夠利用PIPELINED模式,好比我要作count統計,利用PIPELINED模式能拿到更好的執行性能。只有在特殊狀況,好比SortMergeJoin,這時候咱們須要全局數據排序,才須要BATCH模式。大部分狀況流與批可用統一的傳輸策略,只有特殊狀況,纔將批看作是流的一個特例繼續特殊處理。
統一任務調度層
Apache Flink 在任務調度上流與批共享統一的資源和任務調度機制(後續章節會詳細介紹)。
統一的用戶API層
Apache Flink 在DataStremAPI和DataSetAPI基礎上,爲用戶提供了流批統一的上層TableAPI和SQL,在語法和語義上流批進行高度統一。(其中DataStremAPI和DataSetAPI對流和批進行了分別抽象,這一點並不優雅,在Alibaba內部對其進行了統一抽象)。
求同存異
Apache Flink 是流批統一的計算引擎,並不意味着流與批的任務都走統一的code path,在對底層的具體算子的實現也是有各自的處理的,在具體功能上面會根據不一樣的特性區別處理。好比 批沒有Checkpoint機制,流上不能作SortMergeJoin。
組件棧
咱們上面內容已經介紹了不少Apache Flink的各類組件,下面咱們總體概覽一下全貌,以下:
TableAPI和SQL都創建在DataSetAPI和DataStreamAPI的基礎之上,那麼TableAPI和SQL是如何轉換爲DataStream和DataSet的呢?
TableAPI&SQL到DataStrem&DataSet的架構
TableAPI&SQL最終會通過Calcite優化以後轉換爲DataStream和DataSet,具體轉換示意以下:
對於流任務最終會轉換成DataStream,對於批任務最終會轉換成DataSet。
ANSI-SQL的支持
Apache Flink 之因此利用ANSI-SQL做爲用戶統一的開發語言,是由於SQL有着很是明顯的優勢,以下:
-
Declarative - 用戶只須要表達我想要什麼,不用關心如何計算。
-
Optimized - 查詢優化器能夠爲用戶的 SQL 生成最優的執行計劃,獲取最好的查詢性能。
-
Understandable - SQL語言被不一樣領域的人所熟知,用SQL 做爲跨團隊的開發語言能夠很大地提升效率。
-
Stable - SQL 是一個擁有幾十年歷史的語言,是一個很是穩定的語言,不多有變更。
-
Unify - Apache Flink在引擎上對流與批進行統一,同時又利用ANSI-SQL在語法和語義層面進行統一。
無限擴展的優化機制
Apache Flink 利用Apache Calcite對SQL進行解析和優化,Apache Calcite採用Calcite是開源的一套查詢引擎,實現了兩套Planner:
-
HepPlanner - 是RBO(Rule Base Optimize)模式,基於規則的優化。
-
VolcanoPlanner - 是CBO(Cost Base Optimize)模式,基於成本的優化。
Flink SQL會利用Calcite解析優化以後,最終轉換爲底層的DataStrem和Dataset。上圖中 Batch rules和Stream rules能夠根據優化須要無限添加優化規則。
Apache Flink 優秀的架構就像一座摩天大廈的地基同樣爲Apache Flink 持久的生命力打下了良好的基礎,爲打造Apache Flink豐富的功能生態留下無限的空間。
豐富的類庫和算子
類庫
-
CEP - 復瑣事件處理類庫,核心是一個狀態機,普遍應用於事件驅動的監控預警類業務場景。
-
ML - 機器學習類庫,機器學習主要是識別數據中的關係、趨勢和模式,通常應用在預測類業務場景。
-
GELLY - 圖計算類庫,圖計算更多的是考慮邊和點的概念,通常被用來解決網狀關係的業務場景。
算子
Apache Flink 提供了豐富的功能算子,對於數據流的處理來說,能夠分爲單流處理(一個數據源)和多流處理(多個數據源)。
多流操做
如上經過UION和JOIN咱們能夠將多流最終變成單流,Apache Flink 在單流上提供了更多的操做算子。
單流操做
將多流變成單流以後,咱們按數據輸入輸出的不一樣歸類以下:
類型 | 輸入 | 輸出 | Table/SQL算子 | DataStream/DataSet算子 |
---|---|---|---|---|
Scalar Function | 1 | 1 | Built-in & UDF, | Map |
Table Function | 1 | N(N>=0) | Built-in & UDTF | FlatMap |
Aggregate Function | N(N>=0) | 1 | Built-in & UDAF | Reduce |
如上表格對單流上面操做作簡單歸類,除此以外還能夠作 過濾,排序,窗口等操做,咱們後續章節會逐一介紹。
存在的問題
Apache Flink 目前的架構還存在很大的優化空間,好比前面提到的DataStreamAPI和DataSetAPI實際上是流與批在API層面不統一的體現,同時看具體實現會發現DataStreamAPI會生成Transformation tree而後生成StreamGraph,最後生成JobGraph,底層對應StreamTask,但DataSetAPI會造成Operator tree,flink-optimize模塊會對Batch Plan進行優化,造成Optimized Plan 後造成JobGraph,最後造成BatchTask。具體示意以下:
這種狀況其實 DataStreamAPI到Runtime 和 DataSetAPI到Runtime的實現上並無獲得最大程度的統一和複用。在這一點上面Aalibab 企業版的Flink在架構和實現上都進行了進一步優化。
Apache Flink組件架構優化
組件棧
Alibaba 對Apache Flink進行了大量的架構優化,以下架構是一直努力的方向,大部分功能還在持續開發中,具體以下:
如上架構咱們發現較大的變化是:
-
QP/QE/QO - 咱們增長了QP/QE/QO層,在這一層進行統一的流和批的查詢優化和底層算子的轉換。
-
DAG API - 咱們在Runtime層面統一抽象API接口,在API層對流與批進行統一。
TableAPI&SQL到Runtime的架構
Apache Flink執行層是流批統一的設計,在API和算子設計上面咱們儘可能達到流批的共享,在TableAPI和SQL層不管是流任務仍是批任務最終都轉換爲統一的底層實現。這個層面最核心的變化是批最終也會生成StreamGraph,執行層運行Stream Task,以下:
小結
本篇概要的介紹了"批是流的特例"這一設計觀點是Apache Flink的"命脈",它決定了Apache Flink的運行模式是純流式的,這在實時計算場景的"低延遲"需求上,相對於Micro Batching模式佔據了架構的絕對優點,同時概要的向你們介紹了Apache Flink的部署模式,容錯處理,引擎的統一性和Apache Flink的架構,最後和你們分享了Apache Flink的優化架構。
本篇沒有對具體技術進行詳細展開,你們只要對Apache Flink有初步感知,頭腦中知道Alibaba對Apache Flink進行了架構優化,增長了衆多功能就能夠了,至於Apache Flink的具體技術細節和實現原理,以及Alibaba對Apache Flink作了哪些架構優化和增長了哪些功能後續章節會展開介紹!
- 海量【java和大數據的面試題+視頻資料】整理在公衆號,關注後能夠下載~
- 更多大數據技術歡迎和做者一塊兒探討~