Flink流式處理概念簡介

一,抽象層次數據庫

Flink提供不一樣級別的抽象來開發流/批處理應用程序。編程

1stateful streamingwindows

最底層。它經過Process Function嵌入到DataStream API中。它容許用戶從一個或多個流自由處理事件,並使用一致的容錯狀態。此外,用戶能夠註冊事件時間和處理時間回調,容許程序實現複雜的計算。後端

2Core APIs緩存

實際上,大多數應用程序不須要上述的低級別抽象,而是針對Core API(如DataStream API(有界/無界流))和DataSet API(有界數據集)進行編程。這些流暢的API爲數據處理提供了常見的構建模塊,如用戶指定的各類轉換形式,鏈接,聚合,窗口,狀態等。在這些API中處理的數據類型以各自的編程語言表示爲classes。底層的Process FunctionDataStream API的整合,使得針對一些特定的操做能夠實現更低層次的抽象。DataSet API爲有界數據集提供了額外的原函數,如循環/迭代。安全

3Table API微信

Table API是以表爲中心的聲明式DSL,多是動態更改表(表示流時)。Table API遵循(擴展)關係模型:Table 具備附加schema(與關係數據庫中的表類似),API提供操做,例如selectprojectjoingroup-byaggregate等。Table API表明的是應該作什麼邏輯操做,而不是直接指定如何編寫操做的源代碼。雖然Table API能夠經過各類類型的用戶定義的函數進行擴展,但它不如Core API那麼具備表達力,但使用起來更加簡潔(少寫不少代碼)。數據結構

此外,Table API程序還能夠經過在執行以前應用優化規則的優化器。併發

能夠在表和DataStream / DataSet之間無縫轉換,容許程序將Table APIDataStreamDataSet API混合使用。框架

4SQL

最高層次的抽象就是SQL。不管是語法仍是表達,該層次的抽象都很像Table APISQL抽象與Table API緊密交互,SQL查詢能夠在Table API中定義的表上執行。

 

二,Programs and Dataflows

Flink程序的基本構建塊是流和轉換。在概念上,stream data records的(潛在的永無止境的)flow,而且變換是將一個或多個流做爲輸入的操做,而且做爲結果產生一個或多個輸出流。

執行時,Flink程序被映射成streaming dataflows,由streams 和轉換操做符組成。每一個dataflow 從一個或多個sources開始,並以一個或多個sinks結束。dataflows 像任意的有向無環圖(DAG)。雖然經過迭代構造容許特殊形式的循環,可是爲了簡單起見,咱們大部分都會任務是DAG


一般,程序中的變換和數據流中的運算符之間存在一對一的對應關係。然而,有時,一個變換可能由多個轉換算子組成。

 

三,Parallel Dataflows

Flink中的程序本質上是並行和分發的。在執行期間,流具備一個或多個流分區,而且每一個運算符具備一個或多個運算符subtask。操做符subtask彼此獨立,並以不一樣的線程執行,可能在不一樣的機器或容器上執行。

運算符子任務的數量是該特定操做符的並行性。stream 的並行性老是其生產運算符的並行性。同一程序的不一樣運算符可能具備不一樣的並行級別。

Streams 能夠以一對一(或轉發)模式或從新分配模式在兩個運算符之間傳輸數據:

1),一對一

One-to-one streams(例如上圖中的Sourcemap()運算符之間)保留元素的分區和ordering。這意味着map()運算符的子任務[1]看到的元素的順序將和由Source 操做符產生的順序相同。

2),再分配

從新分配流(map()和上面的keyBy / window之間以及keyBy / windowSink之間)改變流的分區。每一個操做符子任務根據所選擇的轉換將數據發送到不一樣的目標子任務。

KeyBy是按照keyhash值進行從新分區,rebalance()是以隨機的方式從新分區。在從新分配交換中,元素之間的排序僅保留在每對發送和接收子任務對(例如,keyBy / windowmap()和子任務[2]的子任務[1])。上例子中僅保證相同key的元素順序性。

四,Windows

Aggregating events(例如,countssums)在流上的工做方式與批處理不一樣。例如,不可能對流中的全部元素進行計數,由於流一般是無限的(無界)。相反,流上的聚合(計數,總和等)由窗口限定,例如「最後5分鐘計數」或「最後100個元素的總和」。

Windows能夠時間驅動(例如:每30秒)或數據驅動(例如:每100個元素)。一般區分不一樣類型的窗口,例如翻轉窗口(無重疊)[tumbling windows (no overlap)],滑動窗口(具備重疊)[sliding windows (with overlap)]和會話窗口(由不活動空隙劃分)[ession windows (punctuated by a gap of inactivity)]

五,Time

當在Streaming 程序中使用時間的時候,如定義窗口時,能夠參考不一樣的時間概念:

1Event Time

Event TimeEvent建立的時間。Events中的Event Time是以時間戳的格式存在。Fink經過timestamp assigners來得到event timestampstimestamp assigners後面出文章具體說。

2Ingestion time

Ingestion timeevent進入flink dataflow的時間。

3Processing Time

Processing Time是基於時間的操做算子執行的本地時間。

六,Stateful Operations

雖然dataflow 中的許多操做只是一次處理一個單獨的事件(例如事件解析器),但一些操做會記住跨多個事件的信息(例如窗口運算符)。這些操做稱爲有狀態。有狀態的操做算子,狀態保存在嵌入式的鍵/值存儲中。狀態會和被狀態操做算子讀取的streams一塊兒分區和分配。使用keyBy函數後,僅keyed streams可能獲取key/value狀態,而且僅限於與當前事件key相關的值。對齊streamstatekeys,確保全部狀態更新都是本地操做,保證一致性,無需事務開銷。此對齊還容許Flink從新分配狀態並透明地調整流分區。

七,Checkpoints 

Flink使用stream replaycheckpoint組合來實現容錯。檢查點與每一個輸入流中的特定點相關聯,以及每一個運算符的相應狀態。Streaming dataflow能夠從檢查點恢復流,同時經過恢復操做符的狀態,從檢查點從新執行事件來保持一致性(一次性處理語義)

檢查點間隔是在恢復時間(須要從新計算的事件數)的狀況下,在執行期間消除容錯的開銷的一種手段。

 

八,Batch on Streaming

Flink執行批處理程序做爲流程序的特殊狀況,其中streams 是有限的(有限數量的元素)。DataSet在內部被視爲數據流。以上概念所以適用於批處理程序,一樣適用於流式傳輸程序,但有一些例外:

1,批處理程序的容錯不使用checkpoint。恢復須要徹底執行流。這是可能的,由於輸入是有限的。恢復成本增長,可是使得處理變得廉價,由於無需進行checkpoint

2DataSet API中的有狀態操做使用簡化的in-memory/out-of-core數據結構,而不是鍵/值索引。

3DataSet API引入了特殊的同步(superstep-based)迭代,這些迭代只能在有界流上進行。具體後面出文章介紹。

 

九,Tasks and Operator Chains

爲了分佈式執行,Flink 鏈式合併operator subtaskstasks。每一個task被一個線程執行。鏈式的將操做符合併成任務是一個頗有用的優化:它減小了線程到線程切換和緩衝的開銷,而且在減小延遲的同時增長了整體吞吐量。鏈式操做是能夠配置的(後面出文章具體介紹)

下圖dataflow的例子,使用五個subtasks執行,因而須要五個併發線程。

十,flink的角色

Flink運行時由兩種類型的進程組成:

1),JobManager也叫master協調分佈式執行。他們調度任務,協調checkpoints,協調故障恢復等。至少有一個JobManager。高可用狀況下能夠啓動多個JobManager,其中一個選舉爲leader,其他爲standby

2),TaskManager也叫worker,負責執行具體的tasks。緩存,交換數據流。至少有一個TaskManager

JobManagerTaskManager能夠用不少種方式啓動:能夠直接做爲Standalone集羣啓動,也能夠被yarn或者Mesos管理。TaskManager鏈接到JobManager,宣佈本身可用,並接受分配的工做。

客戶端不是runtime 和程序執行的一部分,而是用於準備併發送數據流到JobManager

以後,客戶端能夠斷開鏈接或保持鏈接以接收進度報告。客戶端做爲觸發執行的Java / Scala程序的一部分運行,或在命令行進程中運行./bin/flink運行。。

十一,Task Slots and Resources

每一個worker(或者叫TaskManager)是一個jvm進程,能夠在獨立的線程中執行一個或者多個subtasks。爲了控制worker接受tasks數,worker稱之爲任務槽數(至少有一個)。

每一個task slot表明TaskManager的一個固定部分資源。例如,一個TaskManager有三個slot,會均分其管理的內存給每一個slot。按槽分配資源意味着一個subtask不會與其它jobsubtask競爭管理的內存,而是使用保留的內存資源。這裏並無實現cpu資源的隔離。僅僅實現了基於內存的資源隔離。

經過調整task slots的數量,用戶能夠定義子任務彼此隔離的方式。每一個TaskManager擁有一個slot 意味着每一個任務組在單獨的JVM中運行(例如,能夠在單獨的容器中啓動)。擁有多個slots 意味着更多的子任務共享相同的JVM。相同JVM中的任務共享TCP鏈接(經過複用)和心跳消息。他們還能夠共享數據集和數據結構,從而減小每一個任務的開銷。


默認狀況下,Flink容許子任務共享slot,即便它們是不一樣taskssubtasks,只要它們來自相同的job。結果是一個slot能夠處理整個job pipeline。容許這個slot共享有兩個主要好處:

1),Flink集羣須要與job中使用的最高並行度徹底相同的task slot數。不須要計算一個程序總共包含多少任務(具備不一樣的並行性)。

2),更容易得到更好的資源利用率。沒有slot共享,非密集的source / map()子任務將擁有與資源密集型窗口子任務同樣多的資源。使用slot共享,經過將例子中國的基礎並行度從2增長到6,能夠充分利用slot資源,同時保證heavy subtasks均勻的分配到不一樣taskmanager中。

也有resource 組機制,能夠組織不但願的slot共享。

做爲經驗法則,task slot最佳默認數量將是CPU內核的數量。

 

十二,State Backends

 key/values索引存儲的確切數據結構取決於所選的State Backends(目前有三種:MemoryStateBackendFsStateBackendRocksDBStateBackend)。一種state backend將數據存儲於內存的hash map中,另外一種state backend使用的是RocksDB,還有就是使用文件。除了定義保存狀態的數據結構以外,state backends 還實現邏輯以獲取鍵/值狀態的 point-in-time 快照,並將該快照存儲爲checkpoint的一部分。

十三,Savepoints

使用Data Stream API編寫的程序能夠從Savepoints恢復執行。Savepoints容許更新程序和Flink集羣,而不會丟失任何狀態。

Savepoints 是手動觸發的checkpoints,它們記錄程序的快照並將其寫入狀態後端。他們依靠這個常規的檢查點機制。執行過程當中,按期在工做節點上快照並生成檢查點。爲了恢復,只須要最後完成的檢查點,一旦新的檢查點完成,能夠安全地丟棄較舊的檢查點。Savepoints 與這些按期checkpoints相似,除了它們由用戶觸發,而且在較新的檢查點完成時不會自動過時。能夠從命令行建立保存點,也能夠經過REST API取消做業。

 

十四,總結

Flink做爲一個流式處理的框架,在實時計算中也是很常見的。Flink應用程序總共有如下三個部分:

1),Data source:Flink處理的輸入數據

2),TransformationsFlink修改傳入數據時的處理步驟

3),Data sink: flink處理結束後輸出位置


        kafkahbasespark等源碼入門到深刻,spark機器學習,大數據安全,大數據運維,請關注浪尖公衆號,看高質量文章。



本文分享自微信公衆號 - 浪尖聊大數據(bigdatatip)。
若有侵權,請聯繫 support@oschina.cn 刪除。
本文參與「OSC源創計劃」,歡迎正在閱讀的你也加入,一塊兒分享。

相關文章
相關標籤/搜索