Apache Flink是一個面向分布式數(shù)據(jù)流處理和批量數(shù)據(jù)處理的開源計算平臺,它能夠基于同一個Flink運(yùn)行時(Flink Runtime),提供支持流處理和批處理兩種類型應(yīng)用的功能?,F(xiàn)有的開源計算方案,會把流處理和批處理作為兩種不同的應(yīng)用類型,因為他們它們所提供的SLA是完全不相同的:流處理一般需要支持低延遲、Exactly-once保證,而批處理需要支持高吞吐、高效處理,所以在實現(xiàn)的時候通常是分別給出兩套實現(xiàn)方法,或者通過一個獨(dú)立的開源框架來實現(xiàn)其中每一種處理方案。例如,實現(xiàn)批處理的開源方案有MapReduce、Tez、Crunch、Spark,實現(xiàn)流處理的開源方案有Samza、Storm。
Flink在實現(xiàn)流處理和批處理時,與傳統(tǒng)的一些方案完全不同,它從另一個視角看待流處理和批處理,將二者統(tǒng)一起來:Flink是完全支持流處理,也就是說作為流處理看待時輸入數(shù)據(jù)流是無界的;批處理被作為一種特殊的流處理,只是它的輸入數(shù)據(jù)流被定義為有界的?;谕粋€Flink運(yùn)行時(Flink Runtime),分別提供了流處理和批處理API,而這兩種API也是實現(xiàn)上層面向流處理、批處理類型應(yīng)用框架的基礎(chǔ)。
基本特性
關(guān)于Flink所支持的特性,我這里只是通過分類的方式簡單做一下梳理,涉及到具體的一些概念及其原理會在后面的部分做詳細(xì)說明。
流處理特性
支持高吞吐、低延遲、高性能的流處理
支持帶有事件時間的窗口(Window)操作
支持有狀態(tài)計算的Exactly-once語義
支持高度靈活的窗口(Window)操作,支持基于time、count、session,以及data-driven的窗口操作
支持具有Backpressure功能的持續(xù)流模型
支持基于輕量級分布式快照(Snapshot)實現(xiàn)的容錯
一個運(yùn)行時同時支持Batch alt="物聯(lián)網(wǎng)" width="550" height="414" />
flink-streaming-dataflow-example
上圖中,F(xiàn)linkKafkaConsumer是一個Source Operator,map、keyBy、timeWindow、apply是Transformation Operator,RollingSink是一個Sink Operator。
Parallel Dataflow
在Flink中,程序天生是并行和分布式的:一個Stream可以被分成多個Stream分區(qū)(Stream Partitions),一個Operator可以被分成多個Operator Subtask,每一個Operator Subtask是在不同的線程中獨(dú)立執(zhí)行的。一個Operator的并行度,等于Operator Subtask的個數(shù),一個Stream的并行度總是等于生成它的Operator的并行度。
有關(guān)Parallel Dataflow的實例,如下圖所示:

flink-parallel-dataflow
上圖Streaming Dataflow的并行視圖中,展現(xiàn)了在兩個Operator之間的Stream的兩種模式:
One-to-one模式
比如從Source[1]到map()[1],它保持了Source的分區(qū)特性(Partitioning)和分區(qū)內(nèi)元素處理的有序性,也就是說map()[1]的Subtask看到數(shù)據(jù)流中記錄的順序,與Source[1]中看到的記錄順序是一致的。
Redistribution模式
這種模式改變了輸入數(shù)據(jù)流的分區(qū),比如從map()[1]、map()[2]到keyBy()/window()/apply()[1]、keyBy()/window()/apply()[2],上游的Subtask向下游的多個不同的Subtask發(fā)送數(shù)據(jù),改變了數(shù)據(jù)流的分區(qū),這與實際應(yīng)用所選擇的Operator有關(guān)系。
另外,Source Operator對應(yīng)2個Subtask,所以并行度為2,而Sink Operator的Subtask只有1個,故而并行度為1。
Task & Operator Chain
在Flink分布式執(zhí)行環(huán)境中,會將多個Operator Subtask串起來組成一個Operator Chain,實際上就是一個執(zhí)行鏈,每個執(zhí)行鏈會在TaskManager上一個獨(dú)立的線程中執(zhí)行,如下圖所示:

flink-tasks-chains
上圖中上半部分表示的是一個Operator Chain,多個Operator通過Stream連接,而每個Operator在運(yùn)行時對應(yīng)一個Task;圖中下半部分是上半部分的一個并行版本,也就是對每一個Task都并行化為多個Subtask。
Time & Window
Flink支持基于時間窗口操作,也支持基于數(shù)據(jù)的窗口操作,如下圖所示:

flink-window
上圖中,基于時間的窗口操作,在每個相同的時間間隔對Stream中的記錄進(jìn)行處理,通常各個時間間隔內(nèi)的窗口操作處理的記錄數(shù)不固定;而基于數(shù)據(jù)驅(qū)動的窗口操作,可以在Stream中選擇固定數(shù)量的記錄作為一個窗口,對該窗口中的記錄進(jìn)行處理。