1. 程序和數(shù)據(jù)流
Flink程序構(gòu)建的基本單元是stream和transformation(請注意,DataSet實質(zhì)上也是stream)杨幼。一個stream是一個中間結(jié)果嫌拣,一個transformation是一個操作颜骤,該操作以一個或多個stream為輸入唧喉,計算輸出一個或多個stream為結(jié)果。
在運行時,F(xiàn)link上運行的程序會被映射成streaming dataflows八孝,它包含了streams和transformations操作董朝。每個dataflow以一個或者多個source開始,以一個或多個sink結(jié)束干跛。dataflow類似于有向無環(huán)圖(DAG)子姜,特殊形式的環(huán)也允許通過iteration構(gòu)建。
在大多數(shù)情況下楼入,程序中的transformation和dataflow中的操作是一一對應(yīng)關(guān)系哥捕,但有時候一個transformation可能對應(yīng)了多個操作。
1.1 并行數(shù)據(jù)流 Parallel Dataflows
Flink程序與生俱來的就是并行和分布式的浅辙。Streams被分割成stream patition, Operators被被分割成operator subtasks扭弧。這些subtasks在不同的機器(容器)上的不同的線程中運行,彼此獨立记舆,互不干擾。 一個操作的operator subtask的數(shù)目呼巴,被稱為parallelism(并行度)泽腮。一個stream的并行度,總是等于生成它的(operator)操作的并行度衣赶。一個Flink程序中诊赊,不同的operator可能具有不同的并行度。
- One-to-One Streams(例如source和map()之間)維護(hù)著分區(qū)和元素的順序府瞄。這意味著map操作看到的元素個數(shù)和順序跟source操作看到的元素個數(shù)和順序是相同的碧磅。
- Redistributing Streams(例如map()和keyBy、Window之間遵馆,還有keyBy鲸郊、Window和sink之間)的分區(qū)發(fā)生改變。每個operator subtask把數(shù)據(jù)發(fā)送到不同的目標(biāo)subtask上货邓,其發(fā)送的依據(jù)是選擇何種的transformation秆撮。例如keyBy操作(基于Hash重新分區(qū)),broadcast()或者 rebalance() (隨機重新分區(qū))换况。在一個redistributing 交換中职辨,元素之間的順序僅僅在每一個發(fā)送-接受task對中才會被維持。
1.2 任務(wù)和操作鏈 Tasks & Operator Chains
為了達(dá)到分布式執(zhí)行的目的戈二,F(xiàn)link把subtasks鏈在一起形成tasks舒裤。每一個任務(wù)(task)被一個線程執(zhí)行。將操作鏈在一起形成task是非常有效的優(yōu)化觉吭,它能減少線程之間的切換腾供,提高吞吐量,降低延時。操作鏈的行為可以同API配置指定台腥。下面的圖展示了5個sub task宏赘,以5個并行的線程來執(zhí)行。
2. 分布式執(zhí)行 Distributed Execution
Flink是一個主結(jié)構(gòu)的分布式系統(tǒng)黎侈,其Master被成為JobManager,其Slave(worker)被成為TaskManager察署;Flink管理分配資源的單位是Slot。
2.1 集群角色 Master峻汉,Worker贴汪,Client
Flink集群啟動后,會有兩種進(jìn)程休吠,一種是JobManager(Master)扳埂,一種是TaskManager(Worker),我們可以通過jps
或者ps -ef | grep java
命令來查看Flink進(jìn)程瘤礁。
- Master進(jìn)程(JobManager)阳懂,用于分布式執(zhí)行,調(diào)度任務(wù)柜思,協(xié)調(diào)檢查點(checkpoint)岩调,協(xié)調(diào)失敗恢復(fù)等。Flink集群中至少有一個Master進(jìn)程赡盘;為了高可用性号枕,通常會有多個Master節(jié)點,選舉其中一個作為leader陨享,其余作為standby葱淳。
- Worker進(jìn)程(TaskManager),用于執(zhí)行dataflow上的task(subtask)抛姑,緩存和交換數(shù)據(jù)流赞厕。TaskManager至少有一個。
Flink集群的Master進(jìn)程和Worker進(jìn)程可以通過多種方式啟動途戒,既可以在物理機上部署啟動坑傅,也可以通過容器技術(shù)、或者像YARN這樣的資源管理框架啟動喷斋。Worker連接到Master唁毒,告知自身可用,并等待分配任務(wù)星爪。
Client不是Flink集群運行時的一部分浆西,它作為客戶端,用來準(zhǔn)備和發(fā)送數(shù)據(jù)流到Master顽腾,在這之后近零,客戶端可以斷開诺核,或者保持連接接受結(jié)果數(shù)據(jù)【眯牛客戶端程序可以是java或者Scala程序窖杀,也可以通過命令行的方式(bin/flink run...)來觸發(fā)Flink集群執(zhí)行。
2.2 資源管理 Workers, Slots, Resources
每個Worker都是一個JVM進(jìn)程裙士,可以在不同的線程里執(zhí)行一個或者多個subtasks入客。Worker通過task slots來管理接受處理多少個任務(wù)。每個task slot代表了固定額度的資源腿椎,是TaskManager擁有的資源的子集桌硫。例如,一個TaskManager有3個slot啃炸,那么每個slot占據(jù)其1/3的資源铆隘。 采用slot來分配資源,避免了任務(wù)之間的資源競爭南用。需要注意的是膀钠,F(xiàn)link的slot僅僅描述和隔離了內(nèi)存資源,并不包括CPU資源的隔離裹虫。
通過調(diào)整slot的數(shù)量托修,我們可以調(diào)節(jié)subtask之間的資源隔離情況。如果每個TaskManager上只有一個slot恒界,意味著該任務(wù)將會獨占資源;如果有多個slot砚嘴,意味著更多的任務(wù)共享JVM資源十酣。同一個JVM進(jìn)程中的任務(wù)將會共享TCP連接和心跳信息。它們也可能共享數(shù)據(jù)集和數(shù)據(jù)結(jié)構(gòu)际长,因此減少了每個任務(wù)的負(fù)載耸采。
默認(rèn)情況下,如果subtask來自于不同的task工育,但來自于同一個job虾宇,F(xiàn)link允許這些subtask共享slot。這樣可能致使一個slot持有該job的整個pipeline如绸。允許共享slot有兩個主要的好處:
- Flink集群需要許多slot來讓job達(dá)到最高的并行度嘱朽,不用計算一個程序需要多少task。
- 更容易提高資源利用率怔接。如果沒有slot共享搪泳,那些非密集型的任務(wù)(source、map)將會阻塞和密集的window subtask一樣多的資源扼脐。正是因為了有了slot共享岸军,可以提高2-6倍的并發(fā)度,同時仍然保證subtask之間合理的共享slot。
slot共享行為可以通過API控制艰赞,以防止不合理的共享佣谐,這個機制稱為 resource groups,它定義了哪些subtask可以共享的slot方妖。
一個約定俗成的規(guī)則是狭魂,task slot推薦的默認(rèn)值是cpu的核數(shù)。對于超線程技術(shù)吁断,每個slot占用兩個或者更多的線程上下文趁蕊。
3. 時間和窗口 Time and Window
聚合事件(例如count、sum)的工作在流計算上和批處理有些不同仔役。流計算中掷伙,不可能一次性統(tǒng)計所有的元素并且返回統(tǒng)計結(jié)果;因為流通常是無界的又兵。取而代之的是任柜,在流上做count/sum等聚合計算,可以限定window(窗口)沛厨,例如統(tǒng)計最近5分鐘的數(shù)量宙地,或?qū)ψ罱?00個元素求和。
窗口可以是時間驅(qū)動的(比如逆皮,每30秒)宅粥,也可以數(shù)據(jù)驅(qū)動的(比如,每100個元素)电谣。通常窗口可以區(qū)分為:tumbing windows(不重疊)秽梅,sliding windows(有重疊)和session window(有空隙的活動)。
3.1 時間 Time
在流計算編程過程中剿牺,當(dāng)我們提到時間(Time)企垦,可能有不同的含義:
- Event Time 是事件的創(chuàng)建時間,通常用時間戳來描述晒来,例如由傳感器或者生產(chǎn)服務(wù)來附加钞诡。Flink通過timestamp assigners訪問事件時間。
- Ingestion Time 指事件從source operator進(jìn)入Flink dataflow的時間湃崩。
-
Processing Time 指執(zhí)行一個基于時間的操作的本地時間荧降。
Paste_Image.png
更多關(guān)于處理時間的細(xì)節(jié),可以參考event time docs竹习。
4. 狀態(tài)和容錯 State and Fault Tolerance
4.1 狀態(tài) State
在dataflow中的某一時刻誊抛,許多操作僅僅關(guān)注一個獨立的事件(例如一個事件解析器),有的操作能記住多個獨立的事件(例如window操作)整陌。這些操作被成為是有狀態(tài)的(stateful)拗窃。
這些有狀態(tài)的操作的狀態(tài)是由一個可以被認(rèn)為是key/value的存儲維護(hù)的瞎领。這些狀態(tài)是分區(qū)和分布式的,和流一起被有狀態(tài)的操作(stateful operator)讀取随夸。因此九默,訪問key/value的狀態(tài)僅能在keyed Streams(執(zhí)行keyBy()函數(shù)之后產(chǎn)生)中進(jìn)行,并且只能通過當(dāng)前事件的key來訪問其值宾毒。對齊stream的key和狀態(tài)驼修,可以確保所有狀態(tài)的更新都是本地操作,在不需要事務(wù)開銷的情況下保證一致性诈铛。這個對齊也允許flink重新分步狀態(tài)乙各,并顯示的調(diào)整stream的分區(qū)。
4.2 檢查點 Checkpoints for Fault Tolerance
Flink實現(xiàn)了失敗容忍機制幢竹,采用流重放(Stream replay)和檢查點(checkpoint)結(jié)合的方式耳峦。一個檢查點定義了流和狀態(tài)的一致點,在該點streaming dataflow可以恢復(fù)并維持一致性(exactly-once的處理語義)焕毫。最新的檢查點之后的事件和狀態(tài)更新蹲坷,將會在輸入流中重放。
4.3 狀態(tài)的存儲 State Backends
為key/value構(gòu)建索引的數(shù)據(jù)結(jié)構(gòu)最終存儲的地方取決于存儲的選擇邑飒,可以是內(nèi)存中基于hash的map循签,也可以是RocksDB。為了定義持有狀態(tài)的數(shù)據(jù)結(jié)構(gòu)疙咸,狀態(tài)的存儲也實現(xiàn)了基于時間點的快照機制县匠,即對key/value的狀態(tài)做快照,并將快照作為檢查點的一部分來存儲撒轮。
5. 基于流的批處理 Batch on Streaming
Flink把批處理程序當(dāng)作一種特殊的流處理程序聚唐,把批處理看作是有界限的流(有限數(shù)量的元素)。一個DataSet在內(nèi)部被當(dāng)作是一個流腔召。因此上面的這些適用于流處理的這些概念在批處理中同樣適用,只有很少的幾個例外:
DataSet API不適用檢查點扮惦⊥沃耄恢復(fù)機制是完整重放流數(shù)據(jù),這是合理的崖蜜,因為輸入的數(shù)據(jù)是有限的浊仆。它將開銷更多的引入在恢復(fù)操作上,但另一方面也使得運行時的常規(guī)流程的代價更低豫领,因為它避免了檢查點機制抡柿。
有狀態(tài)的操作使用了簡單的in-memory/out-of-core的數(shù)據(jù)結(jié)構(gòu),而不是基于key/value的索引機制等恐。
DataSet API引進(jìn)了獨特的同步迭代機制(superstep-based)洲劣,僅限于用在有界的流备蚓。更多的內(nèi)容,可以查看這篇文檔iteration docs囱稽。
原文地址:https://ci.apache.org/projects/flink/flink-docs-release-1.1/concepts/concepts.html
(完)