Flink 能夠為流式計算或批處理應(yīng)用提供多種層次的抽象接口。
低級的抽象接口是狀態(tài)化的數(shù)據(jù)流接口。這個接口是通過 ProcessFunction 集成到 數(shù)據(jù)流 API 中的。此類接口讓用戶可以使用連續(xù)的容錯狀態(tài),并且可以不受限制地處理多個數(shù)據(jù)流中的事件。另外,用戶也可以通過注冊事件時間和時間處理回調(diào)函數(shù)的方法來實現(xiàn)復(fù)雜的計算程序。
實際上,大部分程序通常會使用以數(shù)據(jù)流 API(有界/無界數(shù)據(jù)流)、數(shù)據(jù)集 API(有界數(shù)據(jù)集)為代表的核心 API,而并不會使用前述低級抽象接口。這些核心 API 為數(shù)據(jù)處理提供了大量的通用構(gòu)建模塊,包括用戶定義的各種各樣的變換、連接、聚集、窗口、狀態(tài)等等。在編程語言中,這些 API 處理的數(shù)據(jù)類型通常會表現(xiàn)為相應(yīng)的類的形式。
由于數(shù)據(jù)流 API 集成了低級處理函數(shù),因此可以通過數(shù)據(jù)流API為某些特定操作應(yīng)用低級處理接口。此外,數(shù)據(jù)集 API 也為諸如循環(huán)、迭代之類的有界數(shù)據(jù)集提供了一些補充的編程原語。
由于用戶可以在數(shù)據(jù)表與數(shù)據(jù)流/數(shù)據(jù)集之間進行無縫切換,程序也可以混合使用數(shù)據(jù)表 API 和數(shù)據(jù)流/數(shù)據(jù)集 API。
Flink 程序的基礎(chǔ)構(gòu)建單元是(數(shù)據(jù))流與變換(注意,數(shù)據(jù)集 API 中使用的數(shù)據(jù)集也是一種內(nèi)置的流,這一點我們以后會細說)。顧名思義,一個數(shù)據(jù)流就是一組數(shù)據(jù)記錄組成的(可能永遠不會停止的)流,而變換就是一種接受若干數(shù)據(jù)流作為輸入,然后再輸出結(jié)果數(shù)據(jù)流的過程。
Flink 程序在運行的時候會被映射到數(shù)據(jù)流圖中,這個數(shù)據(jù)流圖就是由程序中的數(shù)據(jù)流和相應(yīng)的變換操作組成的。數(shù)據(jù)流圖開始于一個或多個數(shù)據(jù)源(source),結(jié)束于另外一些匯聚點(sink)。數(shù)據(jù)流圖類似于有向無環(huán)圖(DAG)。雖然可以通過迭代構(gòu)造器生成某些特殊形式的環(huán),但為了簡化說明,大部分情況下我們不考慮這種結(jié)構(gòu)。
通常情況下程序中的變換和數(shù)據(jù)流圖中的運算符是一一對應(yīng)的。不過有的時候也會出現(xiàn)一個變換由多個變換運算符組成的情況。
數(shù)據(jù)源和匯聚點的相關(guān)文檔在數(shù)據(jù)流連接器和批處理連接器的說明文檔中。變換的相關(guān)文檔在數(shù)據(jù)流變換和數(shù)據(jù)集變換的說明文檔中。
本質(zhì)上說,F(xiàn)link 程序是分布式、并發(fā)執(zhí)行的。在程序運行過程中,一個數(shù)據(jù)流可能會有一個或多個流分區(qū),而一個運算符也可能會有一個或多個運算子任務(wù)。每個運算子任務(wù)與另外一個運算子任務(wù)之間都是相互獨立的,他們是在不同的線程中運行的,甚至有可能所運行的機器或者容器都完全不同。
運算子任務(wù)的數(shù)量由運算符的并發(fā)數(shù)確定。數(shù)據(jù)流的并發(fā)數(shù)就是它所生成的運算符的個數(shù)。程序中不同的運算符可以有不同等級的并發(fā)量。
在兩個運算符之間傳輸數(shù)據(jù)流既可以使用一對一的直接型模式,也可以使用重分發(fā)模式:
一對一 模式的數(shù)據(jù)流(例如上圖中 Source 和 map() 運算符之間的數(shù)據(jù)流)中元素的分組和順序會保持不變,也就是說,map() 運算符的子任務(wù)[1]所看見的元素與 Source 運算符的子任務(wù)[1]所生成的元素的順序完全一致。
重分發(fā) 模式的數(shù)據(jù)流(例如上圖中 map() 和 keyBy/window 運算符之間的數(shù)據(jù)流,以及 keyby/window 和 Sink 運算符之間的數(shù)據(jù)流)會改變數(shù)據(jù)流所在的分區(qū)。根據(jù)所選的變換的不同,每個運算子任務(wù)會將數(shù)據(jù)發(fā)送到不同的目標(biāo)子任務(wù)中去。keyBy()(通過對 key 進行哈希計算來重分區(qū))、boradcast() 和 rebalance()(隨機重分區(qū))就是重分發(fā)模式的幾個例子。在重分發(fā)模式下,元素之間的先后次序在每對發(fā)送——接收子任務(wù)(例如 map() 的子任務(wù)[1]和 keyBy/window 的子任務(wù)[2])中是保持不變的。因此,在上圖的例子中,盡管在子任務(wù)之間每個 key 的順序都是確定的,但是由于程序的并發(fā)過程引入了不確定性,終到達 Sink 的元素順序就不能保證與一開始的元素順序完全一致。
關(guān)于配置并發(fā)的更多信息可以參閱并發(fā)執(zhí)行文檔。
計數(shù)(counts)、求和(sums)等聚合事件和批處理過程的工作模式完全不同。舉個例子,由于數(shù)據(jù)流在理論上是無限的,因此直接計算數(shù)據(jù)流中的所有元素的個數(shù)基本上是無法實現(xiàn)的。因此,數(shù)據(jù)流的聚合操作(計數(shù)、求和等)都是由窗口(window)限定了范圍的,例如“計算前五分鐘的元素個數(shù)”,“對前100個元素求和”等。
窗口可以通過時間(例如以30秒為單位)或者數(shù)據(jù)(例如以100個元素為單位)來定義。有多種不同類型的窗口,例如數(shù)據(jù)不重疊的滾動窗口(tumbling window)、數(shù)據(jù)重疊的滑動窗口(sliding window),以及以非活動狀態(tài)為間隔的會話窗口(session window)。
這篇文章介紹了很多窗口的例子。另外,也可以查閱窗口文檔了解更多內(nèi)容。
流式計算程序中的時間概念(例如在定義窗口時經(jīng)常會用到時間)有以下幾種含義:
關(guān)于處理時間的更多信息請參閱事件時間文檔。
雖然數(shù)據(jù)流中有很多運算符每次只需要考慮當(dāng)前所處理的的事件(例如事件分析器),但是仍然存在很多需要記錄多個事件的信息的場景(窗口操作符就是個很好的例子),這種需要記錄信息的操作就稱為有狀態(tài)的操作。
有狀態(tài)操作的狀態(tài)可以理解成是以鍵值對(key/value)形式儲存的。這個狀態(tài)的分區(qū)和分發(fā)過程是和數(shù)據(jù)流嚴(yán)格綁定在一起的,隨后有狀態(tài)運算符讀取數(shù)據(jù)流就可以獲取狀態(tài)了。因此,在 keyBy() 函數(shù)執(zhí)行之后,只能在帶鍵的數(shù)據(jù)流中訪問 key/value 狀態(tài),而且也只能獲取與當(dāng)前事件的主鍵相對應(yīng)的值。數(shù)據(jù)流的鍵和值的對應(yīng)確保了所有狀態(tài)更新都是本地操作,同時也保證了事務(wù)的一致性。這個對應(yīng)也使得Flink可以透明地重分發(fā)狀態(tài),并調(diào)整數(shù)據(jù)流地分區(qū)。
有關(guān)狀態(tài)地更多內(nèi)容請參閱有狀態(tài)操作文檔。
Flink 通過數(shù)據(jù)重發(fā)和校驗檢查機制相結(jié)合的方式實現(xiàn)了容錯能力。檢查點和運算符中的相應(yīng)的狀態(tài)一樣直接關(guān)聯(lián)到輸入數(shù)據(jù)流中的特定的某個點。為了維護數(shù)據(jù)一致性(一次處理的語義),可以讓數(shù)據(jù)流從檢查點恢復(fù),這是通過恢復(fù)運算符的狀態(tài)并對檢查點對應(yīng)的事件進行重發(fā)的方式實現(xiàn)的。
檢查點區(qū)間是對程序的容錯能力與恢復(fù)時間(需要重發(fā)的事件數(shù)量)的折衷。
容錯區(qū)間文檔中有關(guān)于Flink如何處理檢查點以及其他相關(guān)主題的詳細說明。更多關(guān)于配置啟用檢查點的資料請參閱檢查點API文檔。
Flink 將批處理程序看成流式計算程序的一種有界數(shù)據(jù)流(即元素數(shù)量是可數(shù)的)的特例。這里,數(shù)據(jù)集(DataSet)也被看作一種數(shù)據(jù)流。因此,上面流式計算程序中的很多概念也能應(yīng)用到批處理程序中,除了以下幾處不同:
本站文章版權(quán)歸原作者及原出處所有 。內(nèi)容為作者個人觀點, 并不代表本站贊同其觀點和對其真實性負責(zé),本站只提供參考并不構(gòu)成任何投資及應(yīng)用建議。本站是一個個人學(xué)習(xí)交流的平臺,網(wǎng)站上部分文章為轉(zhuǎn)載,并不用于任何商業(yè)目的,我們已經(jīng)盡可能的對作者和來源進行了通告,但是能力有限或疏忽,造成漏登,請及時聯(lián)系我們,我們將根據(jù)著作權(quán)人的要求,立即更正或者刪除有關(guān)內(nèi)容。本站擁有對此聲明的最終解釋權(quán)。