抽象層級(jí)
Flink提供了幾個(gè)不同的抽象層級(jí)來(lái)開(kāi)發(fā)流處理/批處理應(yīng)用程序粹庞。
- 最底層抽象簡(jiǎn)單的提供了狀態(tài)流處理。該功能主要封裝在DataStream API中的Process函數(shù)中蕾域。用戶可以使用這些函數(shù)處理多個(gè)流中的事件,以及使用一致性容錯(cuò)狀態(tài)到旦。此外旨巷,用戶也可以注冊(cè)事件時(shí)間并處理時(shí)間回調(diào),允許程序?qū)崿F(xiàn)復(fù)雜的計(jì)算添忘。
- 通常采呐,用戶不需要直接使用上面的底層抽象,直接使用核心API(例如DataStream API和DataSet API)即可搁骑。這些API提供了數(shù)據(jù)處理的通用模塊斧吐,比如轉(zhuǎn)換,連接仲器,聚合煤率,開(kāi)窗,狀態(tài)等操作乏冀。這些API中的數(shù)據(jù)類型使用對(duì)應(yīng)語(yǔ)言的類表示蝶糯。DataStream API中的Process函數(shù)可以使用底層抽象。DataSet API為綁定數(shù)據(jù)集提供了更多原語(yǔ)辆沦。
- Table API是一個(gè)以表為中心的聲明式DSL昼捍,支持動(dòng)態(tài)修改。Table API遵循關(guān)系模型:每個(gè)表都有一個(gè)schema,API提供諸如select,project妻率,join,group-by乍钻,aggregate等操作。Table API很容易擴(kuò)展铭腕,對(duì)用戶來(lái)說(shuō)也很簡(jiǎn)潔银择。此外,Table API代碼在執(zhí)行前還會(huì)進(jìn)行優(yōu)化谨履。
- 最高層抽象是SQL欢摄。這層抽象在語(yǔ)義和表達(dá)上與Table API一樣熬丧,不過(guò)是將代碼表述成SQL查詢笋粟。
程序和數(shù)據(jù)流
Flink程序最基本的構(gòu)建單元是stream和transformation怀挠。從概念上講,stream是一個(gè)數(shù)據(jù)記錄的流害捕,而transformation是一個(gè)以一個(gè)或多個(gè)stream作為輸入绿淋,產(chǎn)生一個(gè)或多個(gè)stream的操作。
執(zhí)行時(shí)尝盼,F(xiàn)link程序會(huì)映射成流式數(shù)據(jù)流吞滞,它由流和操作組成。每個(gè)數(shù)據(jù)流以一個(gè)或多個(gè)source開(kāi)始盾沫,以一個(gè)或多個(gè)sink結(jié)束裁赠。數(shù)據(jù)流類似于任意有向非循環(huán)圖(DAG)。
通常赴精,程序中的transformation操作和數(shù)據(jù)流中的操作是一對(duì)一關(guān)系佩捞,但有時(shí)一個(gè)transformation也可能對(duì)應(yīng)多個(gè)操作。
并行數(shù)據(jù)流
Flink程序天生就是并行和分布式的蕾哟。執(zhí)行期間一忱,一個(gè)流會(huì)分成幾個(gè)流分區(qū),每個(gè)操作也分成多個(gè)操作子任務(wù)谭确。子任務(wù)彼此之間是獨(dú)立的帘营,運(yùn)行在不同的線程,甚至是不同的機(jī)器和容器之中逐哈。
子任務(wù)的數(shù)量就是該操作的并行度芬迄。流的并行度等同于操作的并行度。不同操作可能有不同的并行層級(jí)鞠眉。
流可以以一對(duì)一(或轉(zhuǎn)發(fā))模式薯鼠,或者重分發(fā)模式在兩個(gè)操作之間傳輸數(shù)據(jù)。
-
一對(duì)一流(例如上圖中的source與map() 之間)保留元素的分區(qū)和順序械蹋。這意味著
map()
操作的subtask[1]
看到的元素與source
操作的subtask[1]
生成的元素一模一樣出皇。 - 重分發(fā)流(例如上圖中的map() 與KeyBy/Window之間)改變了流的分區(qū)。根據(jù)所選的操作哗戈,每個(gè)子任務(wù)將數(shù)據(jù)發(fā)送到不同的目標(biāo)子任務(wù)郊艘。
窗口
聚合事件在流處理和批處理系統(tǒng)上的工作方式是不同的。例如唯咬,統(tǒng)計(jì)流中的元素個(gè)數(shù)是不可能的纱注,因?yàn)榱魍ǔJ菬o(wú)限的(未綁定)。一般來(lái)說(shuō)胆胰,流上的聚合使用的是開(kāi)窗函數(shù)狞贱,諸如“統(tǒng)計(jì)最后5分鐘”,或者“求最后100個(gè)元素的和”蜀涨。
開(kāi)窗函數(shù)可以是時(shí)間驅(qū)動(dòng)的瞎嬉,也可以是數(shù)據(jù)驅(qū)動(dòng)的蝎毡。窗口通常分為以下幾種:翻滾窗口(沒(méi)有重疊),滑動(dòng)窗口(有重疊)氧枣,會(huì)話窗口沐兵。
時(shí)間
在流處理程序中提到時(shí)間,通常說(shuō)的是以下幾種:
- 事件時(shí)間便监,即事件創(chuàng)建的時(shí)間扎谎。通常使用時(shí)間戳表示
- 提取時(shí)間指事件進(jìn)入數(shù)據(jù)流的時(shí)間
-
處理時(shí)間指執(zhí)行操作的時(shí)間
狀態(tài)操作
數(shù)據(jù)流中絕大多數(shù)操作每次只查看一個(gè)事件(例如事件解析器),但是某些操作會(huì)記錄多個(gè)事件的信息(例如開(kāi)窗函數(shù))烧董。這些操作都是有狀態(tài)的毁靶。
狀態(tài)操作的狀態(tài)使用一個(gè)K-V結(jié)構(gòu)維護(hù)。狀態(tài)會(huì)分區(qū)逊移,并嚴(yán)格地隨著狀態(tài)操作一起分發(fā)老充。因此,只有使用了keyBy()
函數(shù)的stream才能夠訪問(wèn)K-V結(jié)構(gòu)的狀態(tài)螟左,并且僅限于當(dāng)前操作相關(guān)聯(lián)的值啡浊。對(duì)齊流和狀態(tài)的key可以確保所有狀態(tài)更新都是本地操作,從而確保一致性而不需要額外的事務(wù)開(kāi)銷胶背。此外還可以重新分布狀態(tài)以及流分區(qū)巷嚣。
檢查點(diǎn)容錯(cuò)
Flink將stream replay和checkpointing結(jié)合起來(lái)實(shí)現(xiàn)容錯(cuò)。檢查點(diǎn)與每個(gè)輸入流和操作的狀態(tài)相關(guān)钳吟。通過(guò)回復(fù)操作的狀態(tài)和檢查點(diǎn)事件重放廷粒,F(xiàn)link可以從檢查點(diǎn)回復(fù)數(shù)據(jù)里,同時(shí)保證一致性红且。
檢查點(diǎn)區(qū)間是在執(zhí)行期間用恢復(fù)時(shí)間(需要重放的事件的數(shù)量)來(lái)折衷容錯(cuò)開(kāi)銷的手段坝茎。
批處理流數(shù)據(jù)
Flink將批處理程序視為一種特殊的流處理程序。此時(shí)流是綁定的(元素?cái)?shù)量有限)暇番。這是數(shù)據(jù)使用DataSet表示嗤放,這樣處理批數(shù)據(jù)的方式與流數(shù)據(jù)的方式相同,除了以下幾點(diǎn):
- 批處理容錯(cuò)不使用檢查點(diǎn)壁酬。數(shù)據(jù)恢復(fù)會(huì)重放整個(gè)流次酌。
- 狀態(tài)操作使用內(nèi)存/核外數(shù)據(jù)結(jié)構(gòu)。
- DataSet API使用同步迭代舆乔。