Flink:特性剖踊、概念庶弃、組件棧衫贬、架構(gòu)及原理分析

簡(jiǎn)單之美 | Apache Flink:特性、概念歇攻、組件棧固惯、架構(gòu)及原理分析
http://shiyanjun.cn/archives/1508.html

Apache Flink是一個(gè)面向分布式數(shù)據(jù)流處理和批量數(shù)據(jù)處理的開源計(jì)算平臺(tái),它能夠基于同一個(gè)Flink運(yùn)行時(shí)(Flink Runtime)缴守,提供支持流處理和批處理兩種類型應(yīng)用的功能≡岷粒現(xiàn)有的開源計(jì)算方案,會(huì)把流處理和批處理作為兩種不同的應(yīng)用類型屡穗,因?yàn)樗麄兯鼈兯峁┑腟LA是完全不相同的:流處理一般需要支持低延遲贴捡、Exactly-once保證,而批處理需要支持高吞吐鸡捐、高效處理栈暇,所以在實(shí)現(xiàn)的時(shí)候通常是分別給出兩套實(shí)現(xiàn)方法,或者通過一個(gè)獨(dú)立的開源框架來(lái)實(shí)現(xiàn)其中每一種處理方案箍镜。例如源祈,實(shí)現(xiàn)批處理的開源方案有MapReduce、Tez色迂、Crunch香缺、Spark,實(shí)現(xiàn)流處理的開源方案有Samza歇僧、Storm图张。Flink在實(shí)現(xiàn)流處理和批處理時(shí),與傳統(tǒng)的一些方案完全不同诈悍,它從另一個(gè)視角看待流處理和批處理祸轮,將二者統(tǒng)一起來(lái):Flink是完全支持流處理,也就是說(shuō)作為流處理看待時(shí)輸入數(shù)據(jù)流是無(wú)界的侥钳;批處理被作為一種特殊的流處理适袜,只是它的輸入數(shù)據(jù)流被定義為有界的∠隙幔基于同一個(gè)Flink運(yùn)行時(shí)(Flink Runtime)苦酱,分別提供了流處理和批處理API,而這兩種API也是實(shí)現(xiàn)上層面向流處理给猾、批處理類型應(yīng)用框架的基礎(chǔ)疫萤。
基本特性
關(guān)于Flink所支持的特性,我這里只是通過分類的方式簡(jiǎn)單做一下梳理敢伸,涉及到具體的一些概念及其原理會(huì)在后面的部分做詳細(xì)說(shuō)明扯饶。
流處理特性
支持高吞吐、低延遲、高性能的流處理
支持帶有事件時(shí)間的窗口(Window)操作
支持有狀態(tài)計(jì)算的Exactly-once語(yǔ)義
支持高度靈活的窗口(Window)操作帝际,支持基于time蔓同、count、session蹲诀,以及data-driven的窗口操作
支持具有Backpressure功能的持續(xù)流模型
支持基于輕量級(jí)分布式快照(Snapshot)實(shí)現(xiàn)的容錯(cuò)
一個(gè)運(yùn)行時(shí)同時(shí)支持Batch on Streaming處理和Streaming處理
Flink在JVM內(nèi)部實(shí)現(xiàn)了自己的內(nèi)存管理
支持迭代計(jì)算
支持程序自動(dòng)優(yōu)化:避免特定情況下Shuffle斑粱、排序等昂貴操作,中間結(jié)果有必要進(jìn)行緩存

API支持
對(duì)Streaming數(shù)據(jù)類應(yīng)用脯爪,提供DataStream API
對(duì)批處理類應(yīng)用则北,提供DataSet API(支持Java/Scala)

Libraries支持
支持機(jī)器學(xué)習(xí)(FlinkML)
支持圖分析(Gelly)
支持關(guān)系數(shù)據(jù)處理(Table)
支持復(fù)雜事件處理(CEP)

整合支持
支持Flink on YARN
支持HDFS
支持來(lái)自Kafka的輸入數(shù)據(jù)
支持Apache HBase
支持Hadoop程序
支持Tachyon
支持ElasticSearch
支持RabbitMQ
支持Apache Storm
支持S3
支持XtreemFS

基本概念
Stream & Transformation & Operator
用戶實(shí)現(xiàn)的Flink程序是由Stream和Transformation這兩個(gè)基本構(gòu)建塊組成,其中Stream是一個(gè)中間結(jié)果數(shù)據(jù)痕慢,而Transformation是一個(gè)操作尚揣,它對(duì)一個(gè)或多個(gè)輸入Stream進(jìn)行計(jì)算處理,輸出一個(gè)或多個(gè)結(jié)果Stream掖举。當(dāng)一個(gè)Flink程序被執(zhí)行的時(shí)候快骗,它會(huì)被映射為Streaming Dataflow。一個(gè)Streaming Dataflow是由一組Stream和Transformation Operator組成塔次,它類似于一個(gè)DAG圖方篮,在啟動(dòng)的時(shí)候從一個(gè)或多個(gè)Source Operator開始,結(jié)束于一個(gè)或多個(gè)Sink Operator励负。下面是一個(gè)由Flink程序映射為Streaming Dataflow的示意圖藕溅,如下所示:

flink-streaming-dataflow-example
flink-streaming-dataflow-example
上圖中,F(xiàn)linkKafkaConsumer是一個(gè)Source Operator继榆,map巾表、keyBy、timeWindow略吨、apply是Transformation Operator集币,RollingSink是一個(gè)Sink Operator。
Parallel Dataflow
在Flink中翠忠,程序天生是并行和分布式的:一個(gè)Stream可以被分成多個(gè)Stream分區(qū)(Stream Partitions)惠猿,一個(gè)Operator可以被分成多個(gè)Operator Subtask,每一個(gè)Operator Subtask是在不同的線程中獨(dú)立執(zhí)行的负间。一個(gè)Operator的并行度,等于Operator Subtask的個(gè)數(shù)姜凄,一個(gè)Stream的并行度總是等于生成它的Operator的并行度政溃。有關(guān)Parallel Dataflow的實(shí)例,如下圖所示:
flink-parallel-dataflow
flink-parallel-dataflow
上圖Streaming Dataflow的并行視圖中态秧,展現(xiàn)了在兩個(gè)Operator之間的Stream的兩種模式:
One-to-one模式

比如從Source[1]到map()[1]董虱,它保持了Source的分區(qū)特性(Partitioning)和分區(qū)內(nèi)元素處理的有序性,也就是說(shuō)map()[1]的Subtask看到數(shù)據(jù)流中記錄的順序,與Source[1]中看到的記錄順序是一致的愤诱。
Redistribution模式

這種模式改變了輸入數(shù)據(jù)流的分區(qū)云头,比如從map()[1]、map()[2]到keyBy()/window()/apply()[1]淫半、keyBy()/window()/apply()[2]溃槐,上游的Subtask向下游的多個(gè)不同的Subtask發(fā)送數(shù)據(jù),改變了數(shù)據(jù)流的分區(qū)科吭,這與實(shí)際應(yīng)用所選擇的Operator有關(guān)系昏滴。另外,Source Operator對(duì)應(yīng)2個(gè)Subtask对人,所以并行度為2谣殊,而Sink Operator的Subtask只有1個(gè),故而并行度為1牺弄。
Task & Operator Chain
在Flink分布式執(zhí)行環(huán)境中姻几,會(huì)將多個(gè)Operator Subtask串起來(lái)組成一個(gè)Operator Chain,實(shí)際上就是一個(gè)執(zhí)行鏈势告,每個(gè)執(zhí)行鏈會(huì)在TaskManager上一個(gè)獨(dú)立的線程中執(zhí)行蛇捌,如下圖所示:

flink-tasks-chains
flink-tasks-chains
上圖中上半部分表示的是一個(gè)Operator Chain,多個(gè)Operator通過Stream連接培慌,而每個(gè)Operator在運(yùn)行時(shí)對(duì)應(yīng)一個(gè)Task豁陆;圖中下半部分是上半部分的一個(gè)并行版本,也就是對(duì)每一個(gè)Task都并行化為多個(gè)Subtask吵护。
Time & Window
Flink支持基于時(shí)間窗口操作盒音,也支持基于數(shù)據(jù)的窗口操作,如下圖所示:
flink-window
flink-window
上圖中馅而,基于時(shí)間的窗口操作祥诽,在每個(gè)相同的時(shí)間間隔對(duì)Stream中的記錄進(jìn)行處理,通常各個(gè)時(shí)間間隔內(nèi)的窗口操作處理的記錄數(shù)不固定瓮恭;而基于數(shù)據(jù)驅(qū)動(dòng)的窗口操作雄坪,可以在Stream中選擇固定數(shù)量的記錄作為一個(gè)窗口,對(duì)該窗口中的記錄進(jìn)行處理屯蹦。有關(guān)窗口操作的不同類型维哈,可以分為如下幾種:傾斜窗口(Tumbling Windows,記錄沒有重疊)登澜、滑動(dòng)窗口(Slide Windows阔挠,記錄有重疊)、會(huì)話窗口(Session Windows)脑蠕,具體可以查閱相關(guān)資料购撼。在處理Stream中的記錄時(shí)跪削,記錄中通常會(huì)包含各種典型的時(shí)間字段,F(xiàn)link支持多種時(shí)間的處理迂求,如下圖所示:
flink-event-ingestion-processing-time
flink-event-ingestion-processing-time
上圖描述了在基于Flink的流處理系統(tǒng)中碾盐,各種不同的時(shí)間所處的位置和含義,其中揩局,Event Time表示事件創(chuàng)建時(shí)間毫玖,Ingestion Time表示事件進(jìn)入到Flink Dataflow的時(shí)間 ,Processing Time表示某個(gè)Operator對(duì)事件進(jìn)行處理事的本地系統(tǒng)時(shí)間(是在TaskManager節(jié)點(diǎn)上)谐腰。這里孕豹,談一下基于Event Time進(jìn)行處理的問題,通常根據(jù)Event Time會(huì)給整個(gè)Streaming應(yīng)用帶來(lái)一定的延遲性十气,因?yàn)樵谝粋€(gè)基于事件的處理系統(tǒng)中励背,進(jìn)入系統(tǒng)的事件可能會(huì)基于Event Time而發(fā)生亂序現(xiàn)象,比如事件來(lái)源于外部的多個(gè)系統(tǒng)砸西,為了增強(qiáng)事件處理吞吐量會(huì)將輸入的多個(gè)Stream進(jìn)行自然分區(qū)叶眉,每個(gè)Stream分區(qū)內(nèi)部有序,但是要保證全局有序必須同時(shí)兼顧多個(gè)Stream分區(qū)的處理芹枷,設(shè)置一定的時(shí)間窗口進(jìn)行暫存數(shù)據(jù)衅疙,當(dāng)多個(gè)Stream分區(qū)基于Event Time排列對(duì)齊后才能進(jìn)行延遲處理。所以鸳慈,設(shè)置的暫存數(shù)據(jù)記錄的時(shí)間窗口越長(zhǎng)饱溢,處理性能越差,甚至嚴(yán)重影響Stream處理的實(shí)時(shí)性走芋。有關(guān)基于時(shí)間的Streaming處理绩郎,可以參考官方文檔,在Flink中借鑒了Google使用的WaterMark實(shí)現(xiàn)方式翁逞,可以查閱相關(guān)資料肋杖。
基本架構(gòu)
Flink系統(tǒng)的架構(gòu)與Spark類似,是一個(gè)基于Master-Slave風(fēng)格的架構(gòu)挖函,如下圖所示:
flink-system-architecture
flink-system-architecture
Flink集群?jiǎn)?dòng)時(shí)状植,會(huì)啟動(dòng)一個(gè)JobManager進(jìn)程、至少一個(gè)TaskManager進(jìn)程怨喘。在Local模式下津畸,會(huì)在同一個(gè)JVM內(nèi)部啟動(dòng)一個(gè)JobManager進(jìn)程和TaskManager進(jìn)程。當(dāng)Flink程序提交后必怜,會(huì)創(chuàng)建一個(gè)Client來(lái)進(jìn)行預(yù)處理洼畅,并轉(zhuǎn)換為一個(gè)并行數(shù)據(jù)流,這是對(duì)應(yīng)著一個(gè)Flink Job棚赔,從而可以被JobManager和TaskManager執(zhí)行。在實(shí)現(xiàn)上,F(xiàn)link基于Actor實(shí)現(xiàn)了JobManager和TaskManager靠益,所以JobManager與TaskManager之間的信息交換丧肴,都是通過事件的方式來(lái)進(jìn)行處理。如上圖所示胧后,F(xiàn)link系統(tǒng)主要包含如下3個(gè)主要的進(jìn)程:
JobManager
JobManager是Flink系統(tǒng)的協(xié)調(diào)者芋浮,它負(fù)責(zé)接收Flink Job,調(diào)度組成Job的多個(gè)Task的執(zhí)行壳快。同時(shí)纸巷,JobManager還負(fù)責(zé)收集Job的狀態(tài)信息,并管理Flink集群中從節(jié)點(diǎn)TaskManager眶痰。JobManager所負(fù)責(zé)的各項(xiàng)管理功能瘤旨,它接收到并處理的事件主要包括:
RegisterTaskManager

在Flink集群?jiǎn)?dòng)的時(shí)候,TaskManager會(huì)向JobManager注冊(cè)竖伯,如果注冊(cè)成功存哲,則JobManager會(huì)向TaskManager回復(fù)消息AcknowledgeRegistration。
SubmitJob

Flink程序內(nèi)部通過Client向JobManager提交Flink Job七婴,其中在消息SubmitJob中以JobGraph形式描述了Job的基本信息祟偷。
CancelJob

請(qǐng)求取消一個(gè)Flink Job的執(zhí)行,CancelJob消息中包含了Job的ID打厘,如果成功則返回消息CancellationSuccess修肠,失敗則返回消息CancellationFailure。
UpdateTaskExecutionState

TaskManager會(huì)向JobManager請(qǐng)求更新ExecutionGraph中的ExecutionVertex的狀態(tài)信息户盯,更新成功則返回true嵌施。
RequestNextInputSplit

運(yùn)行在TaskManager上面的Task,請(qǐng)求獲取下一個(gè)要處理的輸入Split先舷,成功則返回NextInputSplit艰管。
JobStatusChanged

ExecutionGraph向JobManager發(fā)送該消息,用來(lái)表示Flink Job的狀態(tài)發(fā)生的變化蒋川,例如:RUNNING牲芋、CANCELING、FINISHED等捺球。
TaskManager
TaskManager也是一個(gè)Actor缸浦,它是實(shí)際負(fù)責(zé)執(zhí)行計(jì)算的Worker,在其上執(zhí)行Flink Job的一組Task氮兵。每個(gè)TaskManager負(fù)責(zé)管理其所在節(jié)點(diǎn)上的資源信息裂逐,如內(nèi)存、磁盤泣栈、網(wǎng)絡(luò)卜高,在啟動(dòng)的時(shí)候?qū)①Y源的狀態(tài)向JobManager匯報(bào)弥姻。TaskManager端可以分成兩個(gè)階段:
注冊(cè)階段

TaskManager會(huì)向JobManager注冊(cè),發(fā)送RegisterTaskManager消息掺涛,等待JobManager返回AcknowledgeRegistration庭敦,然后TaskManager就可以進(jìn)行初始化過程。
可操作階段

該階段TaskManager可以接收并處理與Task有關(guān)的消息薪缆,如SubmitTask秧廉、CancelTask、FailTask拣帽。如果TaskManager無(wú)法連接到JobManager疼电,這是TaskManager就失去了與JobManager的聯(lián)系,會(huì)自動(dòng)進(jìn)入“注冊(cè)階段”减拭,只有完成注冊(cè)才能繼續(xù)處理Task相關(guān)的消息蔽豺。
Client
當(dāng)用戶提交一個(gè)Flink程序時(shí),會(huì)首先創(chuàng)建一個(gè)Client峡谊,該Client首先會(huì)對(duì)用戶提交的Flink程序進(jìn)行預(yù)處理茫虽,并提交到Flink集群中處理,所以Client需要從用戶提交的Flink程序配置中獲取JobManager的地址既们,并建立到JobManager的連接濒析,將Flink Job提交給JobManager。Client會(huì)將用戶提交的Flink程序組裝一個(gè)JobGraph啥纸, 并且是以JobGraph的形式提交的号杏。一個(gè)JobGraph是一個(gè)Flink Dataflow,它由多個(gè)JobVertex組成的DAG斯棒。其中盾致,一個(gè)JobGraph包含了一個(gè)Flink程序的如下信息:JobID、Job名稱荣暮、配置信息庭惜、一組JobVertex等。
組件棧
Flink是一個(gè)分層架構(gòu)的系統(tǒng)穗酥,每一層所包含的組件都提供了特定的抽象护赊,用來(lái)服務(wù)于上層組件。Flink分層的組件棧如下圖所示:

flink-component-stack
flink-component-stack
下面砾跃,我們自下而上骏啰,分別針對(duì)每一層進(jìn)行解釋說(shuō)明:
Deployment層

該層主要涉及了Flink的部署模式,F(xiàn)link支持多種部署模式:本地抽高、集群(Standalone/YARN)判耕、云(GCE/EC2)。Standalone部署模式與Spark類似翘骂,這里壁熄,我們看一下Flink on YARN的部署模式帚豪,如下圖所示:
flink-on-yarn
flink-on-yarn

了解YARN的話,對(duì)上圖的原理非常熟悉请毛,實(shí)際Flink也實(shí)現(xiàn)了滿足在YARN集群上運(yùn)行的各個(gè)組件:Flink YARN Client負(fù)責(zé)與YARN RM通信協(xié)商資源請(qǐng)求志鞍,F(xiàn)link JobManager和Flink TaskManager分別申請(qǐng)到Container去運(yùn)行各自的進(jìn)程。通過上圖可以看到方仿,YARN AM與Flink JobManager在同一個(gè)Container中,這樣AM可以知道Flink JobManager的地址统翩,從而AM可以申請(qǐng)Container去啟動(dòng)Flink TaskManager仙蚜。待Flink成功運(yùn)行在YARN集群上,F(xiàn)link YARN Client就可以提交Flink Job到Flink JobManager厂汗,并進(jìn)行后續(xù)的映射委粉、調(diào)度和計(jì)算處理。
Runtime層

Runtime層提供了支持Flink計(jì)算的全部核心實(shí)現(xiàn)娶桦,比如:支持分布式Stream處理贾节、JobGraph到ExecutionGraph的映射、調(diào)度等等衷畦,為上層API層提供基礎(chǔ)服務(wù)栗涂。
API層

API層主要實(shí)現(xiàn)了面向無(wú)界Stream的流處理和面向Batch的批處理API,其中面向流處理對(duì)應(yīng)DataStream API祈争,面向批處理對(duì)應(yīng)DataSet API斤程。
Libraries層

該層也可以稱為Flink應(yīng)用框架層,根據(jù)API層的劃分菩混,在API層之上構(gòu)建的滿足特定應(yīng)用的實(shí)現(xiàn)計(jì)算框架忿墅,也分別對(duì)應(yīng)于面向流處理和面向批處理兩類。面向流處理支持:CEP(復(fù)雜事件處理)沮峡、基于SQL-like的操作(基于Table的關(guān)系操作)疚脐;面向批處理支持:FlinkML(機(jī)器學(xué)習(xí)庫(kù))、Gelly(圖處理)邢疙。
內(nèi)部原理
容錯(cuò)機(jī)制
Flink基于Checkpoint機(jī)制實(shí)現(xiàn)容錯(cuò)棍弄,它的原理是不斷地生成分布式Streaming數(shù)據(jù)流Snapshot。在流處理失敗時(shí)秘症,通過這些Snapshot可以恢復(fù)數(shù)據(jù)流處理照卦。理解Flink的容錯(cuò)機(jī)制,首先需要了解一下Barrier這個(gè)概念:Stream Barrier是Flink分布式Snapshotting中的核心元素乡摹,它會(huì)作為數(shù)據(jù)流的記錄被同等看待役耕,被插入到數(shù)據(jù)流中,將數(shù)據(jù)流中記錄的進(jìn)行分組聪廉,并沿著數(shù)據(jù)流的方向向前推進(jìn)。每個(gè)Barrier會(huì)攜帶一個(gè)Snapshot ID夺巩,屬于該Snapshot的記錄會(huì)被推向該Barrier的前方盲再。因?yàn)锽arrier非常輕量,所以并不會(huì)中斷數(shù)據(jù)流察绷。帶有Barrier的數(shù)據(jù)流,如下圖所示:

flink-stream-barriers
flink-stream-barriers
基于上圖津辩,我們通過如下要點(diǎn)來(lái)說(shuō)明:
出現(xiàn)一個(gè)Barrier拆撼,在該Barrier之前出現(xiàn)的記錄都屬于該Barrier對(duì)應(yīng)的Snapshot,在該Barrier之后出現(xiàn)的記錄屬于下一個(gè)Snapshot
來(lái)自不同Snapshot多個(gè)Barrier可能同時(shí)出現(xiàn)在數(shù)據(jù)流中喘沿,也就是說(shuō)同一個(gè)時(shí)刻可能并發(fā)生成多個(gè)Snapshot
當(dāng)一個(gè)中間(Intermediate)Operator接收到一個(gè)Barrier后闸度,它會(huì)發(fā)送Barrier到屬于該Barrier的Snapshot的數(shù)據(jù)流中,等到Sink Operator接收到該Barrier后會(huì)向Checkpoint Coordinator確認(rèn)該Snapshot蚜印,直到所有的Sink Operator都確認(rèn)了該Snapshot莺禁,才被認(rèn)為完成了該Snapshot

這里還需要強(qiáng)調(diào)的是,Snapshot并不僅僅是對(duì)數(shù)據(jù)流做了一個(gè)狀態(tài)的Checkpoint窄赋,它也包含了一個(gè)Operator內(nèi)部所持有的狀態(tài)哟冬,這樣才能夠在保證在流處理系統(tǒng)失敗時(shí)能夠正確地恢復(fù)數(shù)據(jù)流處理。也就是說(shuō)忆绰,如果一個(gè)Operator包含任何形式的狀態(tài)浩峡,這種狀態(tài)必須是Snapshot的一部分。Operator的狀態(tài)包含兩種:一種是系統(tǒng)狀態(tài)较木,一個(gè)Operator進(jìn)行計(jì)算處理的時(shí)候需要對(duì)數(shù)據(jù)進(jìn)行緩沖红符,所以數(shù)據(jù)緩沖區(qū)的狀態(tài)是與Operator相關(guān)聯(lián)的,以窗口操作的緩沖區(qū)為例伐债,F(xiàn)link系統(tǒng)會(huì)收集或聚合記錄數(shù)據(jù)并放到緩沖區(qū)中预侯,直到該緩沖區(qū)中的數(shù)據(jù)被處理完成;另一種是用戶自定義狀態(tài)(狀態(tài)可以通過轉(zhuǎn)換函數(shù)進(jìn)行創(chuàng)建和修改)峰锁,它可以是函數(shù)中的Java對(duì)象這樣的簡(jiǎn)單變量萎馅,也可以是與函數(shù)相關(guān)的Key/Value狀態(tài)。對(duì)于具有輕微狀態(tài)的Streaming應(yīng)用虹蒋,會(huì)生成非常輕量的Snapshot而且非常頻繁糜芳,但并不會(huì)影響數(shù)據(jù)流處理性能。Streaming應(yīng)用的狀態(tài)會(huì)被存儲(chǔ)到一個(gè)可配置的存儲(chǔ)系統(tǒng)中魄衅,例如HDFS峭竣。在一個(gè)Checkpoint執(zhí)行過程中,存儲(chǔ)的狀態(tài)信息及其交互過程晃虫,如下圖所示:
flink-checkpointing
flink-checkpointing

在Checkpoint過程中皆撩,還有一個(gè)比較重要的操作——Stream Aligning。當(dāng)Operator接收到多個(gè)輸入的數(shù)據(jù)流時(shí),需要在Snapshot Barrier中對(duì)數(shù)據(jù)流進(jìn)行排列對(duì)齊扛吞,如下圖所示:
flink-stream-aligning
flink-stream-aligning
具體排列過程如下:
Operator從一個(gè)incoming Stream接收到Snapshot Barrier n呻惕,然后暫停處理,直到其它的incoming Stream的Barrier n(否則屬于2個(gè)Snapshot的記錄就混在一起了)到達(dá)該Operator

接收到Barrier n的Stream被臨時(shí)擱置滥比,來(lái)自這些Stream的記錄不會(huì)被處理亚脆,而是被放在一個(gè)Buffer中
一旦最后一個(gè)Stream接收到Barrier n,Operator會(huì)emit所有暫存在Buffer中的記錄盲泛,然后向Checkpoint Coordinator發(fā)送Snapshot n
繼續(xù)處理來(lái)自多個(gè)Stream的記錄

基于Stream Aligning操作能夠?qū)崿F(xiàn)Exactly Once語(yǔ)義濒持,但是也會(huì)給流處理應(yīng)用帶來(lái)延遲,因?yàn)闉榱伺帕袑?duì)齊Barrier寺滚,會(huì)暫時(shí)緩存一部分Stream的記錄到Buffer中弥喉,尤其是在數(shù)據(jù)流并行度很高的場(chǎng)景下可能更加明顯,通常以最遲對(duì)齊Barrier的一個(gè)Stream為處理Buffer中緩存記錄的時(shí)刻點(diǎn)玛迄。在Flink中,提供了一個(gè)開關(guān)棚亩,選擇是否使用Stream Aligning蓖议,如果關(guān)掉則Exactly Once會(huì)變成At least once。
調(diào)度機(jī)制
在JobManager端讥蟆,會(huì)接收到Client提交的JobGraph形式的Flink Job勒虾,JobManager會(huì)將一個(gè)JobGraph轉(zhuǎn)換映射為一個(gè)ExecutionGraph,如下圖所示:

flink-job-and-execution-graph
flink-job-and-execution-graph
通過上圖可以看出:JobGraph是一個(gè)Job的用戶邏輯視圖表示瘸彤,將一個(gè)用戶要對(duì)數(shù)據(jù)流進(jìn)行的處理表示為單個(gè)DAG圖(對(duì)應(yīng)于JobGraph)修然,DAG圖由頂點(diǎn)(JobVertex)和中間結(jié)果集(IntermediateDataSet)組成,其中JobVertex表示了對(duì)數(shù)據(jù)流進(jìn)行的轉(zhuǎn)換操作质况,比如map愕宋、flatMap、filter结榄、keyBy等操作中贝,而IntermediateDataSet是由上游的JobVertex所生成,同時(shí)作為下游的JobVertex的輸入臼朗。而ExecutionGraph是JobGraph的并行表示邻寿,也就是實(shí)際JobManager調(diào)度一個(gè)Job在TaskManager上運(yùn)行的邏輯視圖,它也是一個(gè)DAG圖视哑,是由ExecutionJobVertex绣否、IntermediateResult(或IntermediateResultPartition)組成,ExecutionJobVertex實(shí)際對(duì)應(yīng)于JobGraph圖中的JobVertex挡毅,只不過在ExecutionJobVertex內(nèi)部是一種并行表示蒜撮,由多個(gè)并行的ExecutionVertex所組成。另外慷嗜,這里還有一個(gè)重要的概念淀弹,就是Execution丹壕,它是一個(gè)ExecutionVertex的一次運(yùn)行Attempt,也就是說(shuō)薇溃,一個(gè)ExecutionVertex可能對(duì)應(yīng)多個(gè)運(yùn)行狀態(tài)的Execution菌赖,比如,一個(gè)ExecutionVertex運(yùn)行產(chǎn)生了一個(gè)失敗的Execution沐序,然后還會(huì)創(chuàng)建一個(gè)新的Execution來(lái)運(yùn)行琉用,這時(shí)就對(duì)應(yīng)這個(gè)2次運(yùn)行Attempt。每個(gè)Execution通過ExecutionAttemptID來(lái)唯一標(biāo)識(shí)策幼,在TaskManager和JobManager之間進(jìn)行Task狀態(tài)的交換都是通過ExecutionAttemptID來(lái)實(shí)現(xiàn)的邑时。下面看一下,在物理上進(jìn)行調(diào)度特姐,基于資源的分配與使用的一個(gè)例子晶丘,來(lái)自官網(wǎng),如下圖所示:
flink-scheduled-task-slots
flink-scheduled-task-slots
說(shuō)明如下:
左上子圖:有2個(gè)TaskManager唐含,每個(gè)TaskManager有3個(gè)Task Slot
左下子圖:一個(gè)Flink Job浅浮,邏輯上包含了1個(gè)data source、1個(gè)MapFunction捷枯、1個(gè)ReduceFunction滚秩,對(duì)應(yīng)一個(gè)JobGraph
左下子圖:用戶提交的Flink Job對(duì)各個(gè)Operator進(jìn)行的配置——data source的并行度設(shè)置為4,MapFunction的并行度也為4淮捆,ReduceFunction的并行度為3郁油,在JobManager端對(duì)應(yīng)于ExecutionGraph
右上子圖:TaskManager 1上,有2個(gè)并行的ExecutionVertex組成的DAG圖攀痊,它們各占用一個(gè)Task Slot
右下子圖:TaskManager 2上桐腌,也有2個(gè)并行的ExecutionVertex組成的DAG圖,它們也各占用一個(gè)Task Slot
在2個(gè)TaskManager上運(yùn)行的4個(gè)Execution是并行執(zhí)行的

迭代機(jī)制
機(jī)器學(xué)習(xí)和圖計(jì)算應(yīng)用蚕苇,都會(huì)使用到迭代計(jì)算哩掺,F(xiàn)link通過在迭代Operator中定義Step函數(shù)來(lái)實(shí)現(xiàn)迭代算法,這種迭代算法包括Iterate和Delta Iterate兩種類型涩笤,在實(shí)現(xiàn)上它們反復(fù)地在當(dāng)前迭代狀態(tài)上調(diào)用Step函數(shù)嚼吞,直到滿足給定的條件才會(huì)停止迭代。下面蹬碧,對(duì)Iterate和Delta Iterate兩種類型的迭代算法原理進(jìn)行說(shuō)明:
Iterate

Iterate Operator是一種簡(jiǎn)單的迭代形式:每一輪迭代舱禽,Step函數(shù)的輸入或者是輸入的整個(gè)數(shù)據(jù)集,或者是上一輪迭代的結(jié)果恩沽,通過該輪迭代計(jì)算出下一輪計(jì)算所需要的輸入(也稱為Next Partial Solution)誊稚,滿足迭代的終止條件后,會(huì)輸出最終迭代結(jié)果,具體執(zhí)行流程如下圖所示:

flink-iterations-iterate-operator
flink-iterations-iterate-operator
Step函數(shù)在每一輪迭代中都會(huì)被執(zhí)行里伯,它可以是由map城瞎、reduce、join等Operator組成的數(shù)據(jù)流疾瓮。下面通過官網(wǎng)給出的一個(gè)例子來(lái)說(shuō)明Iterate Operator脖镀,非常簡(jiǎn)單直觀,如下圖所示:
flink-iterations-iterate-operator-example
flink-iterations-iterate-operator-example
上面迭代過程中狼电,輸入數(shù)據(jù)為1到5的數(shù)字蜒灰,Step函數(shù)就是一個(gè)簡(jiǎn)單的map函數(shù),會(huì)對(duì)每個(gè)輸入的數(shù)字進(jìn)行加1處理肩碟,而Next Partial Solution對(duì)應(yīng)于經(jīng)過map函數(shù)處理后的結(jié)果强窖,比如第一輪迭代,對(duì)輸入的數(shù)字1加1后結(jié)果為2削祈,對(duì)輸入的數(shù)字2加1后結(jié)果為3翅溺,直到對(duì)輸入數(shù)字5加1后結(jié)果為變?yōu)?,這些新生成結(jié)果數(shù)字26會(huì)作為第二輪迭代的輸入髓抑。迭代終止條件為進(jìn)行10輪迭代未巫,則最終的結(jié)果為1115。
Delta Iterate

Delta Iterate Operator實(shí)現(xiàn)了增量迭代启昧,它的實(shí)現(xiàn)原理如下圖所示:

flink-iterations-delta-iterate-operator
flink-iterations-delta-iterate-operator
基于Delta Iterate Operator實(shí)現(xiàn)增量迭代,它有2個(gè)輸入劈伴,其中一個(gè)是初始Workset密末,表示輸入待處理的增量Stream數(shù)據(jù),另一個(gè)是初始Solution Set跛璧,它是經(jīng)過Stream方向上Operator處理過的結(jié)果严里。第一輪迭代會(huì)將Step函數(shù)作用在初始Workset上,得到的計(jì)算結(jié)果Workset作為下一輪迭代的輸入追城,同時(shí)還要增量更新初始Solution Set刹碾。如果反復(fù)迭代知道滿足迭代終止條件,最后會(huì)根據(jù)Solution Set的結(jié)果座柱,輸出最終迭代結(jié)果迷帜。比如,我們現(xiàn)在已知一個(gè)Solution集合中保存的是色洞,已有的商品分類大類中購(gòu)買量最多的商品戏锹,而Workset輸入的是來(lái)自線上實(shí)時(shí)交易中最新達(dá)成購(gòu)買的商品的人數(shù),經(jīng)過計(jì)算會(huì)生成新的商品分類大類中商品購(gòu)買量最多的結(jié)果火诸,如果某些大類中商品購(gòu)買量突然增長(zhǎng)锦针,它需要更新Solution Set中的結(jié)果(原來(lái)購(gòu)買量最多的商品,經(jīng)過增量迭代計(jì)算,可能已經(jīng)不是最多)奈搜,最后會(huì)輸出最終商品分類大類中購(gòu)買量最多的商品結(jié)果集合悉盆。更詳細(xì)的例子,可以參考官網(wǎng)給出的“Propagate Minimum in Graph”馋吗,這里不再累述焕盟。
Backpressure監(jiān)控
Backpressure在流式計(jì)算系統(tǒng)中會(huì)比較受到關(guān)注,因?yàn)樵谝粋€(gè)Stream上進(jìn)行處理的多個(gè)Operator之間耗美,它們處理速度和方式可能非常不同京髓,所以就存在上游Operator如果處理速度過快,下游Operator處可能機(jī)會(huì)堆積Stream記錄商架,嚴(yán)重會(huì)造成處理延遲或下游Operator負(fù)載過重而崩潰(有些系統(tǒng)可能會(huì)丟失數(shù)據(jù))堰怨。因此,對(duì)下游Operator處理速度跟不上的情況蛇摸,如果下游Operator能夠?qū)⒆约禾幚頎顟B(tài)傳播給上游Operator备图,使得上游Operator處理速度慢下來(lái)就會(huì)緩解上述問題,比如通過告警的方式通知現(xiàn)有流處理系統(tǒng)存在的問題赶袄。Flink Web界面上提供了對(duì)運(yùn)行Job的Backpressure行為的監(jiān)控揽涮,它通過使用Sampling線程對(duì)正在運(yùn)行的Task進(jìn)行堆棧跟蹤采樣來(lái)實(shí)現(xiàn),具體實(shí)現(xiàn)方式如下圖所示:
flink-back-pressure-sampling
flink-back-pressure-sampling
JobManager會(huì)反復(fù)調(diào)用一個(gè)Job的Task運(yùn)行所在線程的Thread.getStackTrace()饿肺,默認(rèn)情況下蒋困,JobManager會(huì)每間隔50ms觸發(fā)對(duì)一個(gè)Job的每個(gè)Task依次進(jìn)行100次堆棧跟蹤調(diào)用,根據(jù)調(diào)用調(diào)用結(jié)果來(lái)確定Backpressure敬辣,F(xiàn)link是通過計(jì)算得到一個(gè)比值(Radio)來(lái)確定當(dāng)前運(yùn)行Job的Backpressure狀態(tài)雪标。在Web界面上可以看到這個(gè)Radio值,它表示在一個(gè)內(nèi)部方法調(diào)用中阻塞(Stuck)的堆棧跟蹤次數(shù)溉跃,例如村刨,radio=0.01,表示100次中僅有1次方法調(diào)用阻塞撰茎。Flink目前定義了如下Backpressure狀態(tài):
OK: 0 <= Ratio <= 0.10
LOW: 0.10 < Ratio <= 0.5
HIGH: 0.5 < Ratio <= 1

另外嵌牺,F(xiàn)link還提供了3個(gè)參數(shù)來(lái)配置Backpressure監(jiān)控行為:
參數(shù)名稱
默認(rèn)值
說(shuō)明

jobmanager.web.backpressure.refresh-interval
60000
默認(rèn)1分鐘,表示采樣統(tǒng)計(jì)結(jié)果刷新時(shí)間間隔

jobmanager.web.backpressure.num-samples
100
評(píng)估Backpressure狀態(tài)龄糊,所使用的堆棧跟蹤調(diào)用次數(shù)

jobmanager.web.backpressure.delay-between-samples
50
默認(rèn)50毫秒逆粹,表示對(duì)一個(gè)Job的每個(gè)Task依次調(diào)用的時(shí)間間隔

通過上面?zhèn)€定義的Backpressure狀態(tài),以及調(diào)整相應(yīng)的參數(shù)炫惩,可以確定當(dāng)前運(yùn)行的Job的狀態(tài)是否正常枯饿,并且保證不影響JobManager提供服務(wù)。
參考鏈接
http://flink.apache.org/
http://flink.apache.org/features.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/internals/general_arch.html
http://data-artisans.com/high-throughput-low-latency-and-exactly-once-stream-processing-with-apache-flink/
https://ci.apache.org/projects/flink/flink-docs-release-1.0/internals/stream_checkpointing.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/internals/job_scheduling.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/apis/streaming/event_time.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/setup/yarn_setup.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/setup/jobmanager_high_availability.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/apis/streaming/libs/cep.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/apis/batch/libs/gelly.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/apis/batch/libs/ml/index.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/apis/batch/libs/table.html
https://ci.apache.org/projects/flink/flink-docs-release-1.0/apis/batch/connectors.html
http://geek.csdn.net/news/detail/56272
http://samza.apache.org/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末诡必,一起剝皮案震驚了整個(gè)濱河市奢方,隨后出現(xiàn)的幾起案子搔扁,更是在濱河造成了極大的恐慌,老刑警劉巖蟋字,帶你破解...
    沈念sama閱讀 207,248評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件稿蹲,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡鹊奖,警方通過查閱死者的電腦和手機(jī)苛聘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,681評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)忠聚,“玉大人设哗,你說(shuō)我怎么就攤上這事×襟埃” “怎么了网梢?”我有些...
    開封第一講書人閱讀 153,443評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)赂毯。 經(jīng)常有香客問我战虏,道長(zhǎng),這世上最難降的妖魔是什么党涕? 我笑而不...
    開封第一講書人閱讀 55,475評(píng)論 1 279
  • 正文 為了忘掉前任烦感,我火速辦了婚禮,結(jié)果婚禮上膛堤,老公的妹妹穿的比我還像新娘手趣。我一直安慰自己,他們只是感情好肥荔,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,458評(píng)論 5 374
  • 文/花漫 我一把揭開白布回懦。 她就那樣靜靜地躺著,像睡著了一般次企。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上潜圃,一...
    開封第一講書人閱讀 49,185評(píng)論 1 284
  • 那天缸棵,我揣著相機(jī)與錄音,去河邊找鬼谭期。 笑死堵第,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的隧出。 我是一名探鬼主播踏志,決...
    沈念sama閱讀 38,451評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼胀瞪!你這毒婦竟也來(lái)了针余?” 一聲冷哼從身側(cè)響起饲鄙,我...
    開封第一講書人閱讀 37,112評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎圆雁,沒想到半個(gè)月后忍级,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,609評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡伪朽,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,083評(píng)論 2 325
  • 正文 我和宋清朗相戀三年轴咱,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片烈涮。...
    茶點(diǎn)故事閱讀 38,163評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡朴肺,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坚洽,到底是詐尸還是另有隱情戈稿,我是刑警寧澤,帶...
    沈念sama閱讀 33,803評(píng)論 4 323
  • 正文 年R本政府宣布酪术,位于F島的核電站器瘪,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏绘雁。R本人自食惡果不足惜橡疼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,357評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望庐舟。 院中可真熱鬧欣除,春花似錦、人聲如沸挪略。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,357評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)杠娱。三九已至挽牢,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間摊求,已是汗流浹背禽拔。 一陣腳步聲響...
    開封第一講書人閱讀 31,590評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留室叉,地道東北人睹栖。 一個(gè)月前我還...
    沈念sama閱讀 45,636評(píng)論 2 355
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像茧痕,于是被迫代替她去往敵國(guó)和親野来。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,925評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理踪旷,服務(wù)發(fā)現(xiàn)曼氛,斷路器豁辉,智...
    卡卡羅2017閱讀 134,601評(píng)論 18 139
  • 介紹 概述 Apache Flink是一個(gè)面向數(shù)據(jù)流處理和批量數(shù)據(jù)處理的可分布式的開源計(jì)算框架,它基于同一個(gè)Fli...
    stephen_k閱讀 50,736評(píng)論 0 22
  • 1. 程序和數(shù)據(jù)流 Flink程序構(gòu)建的基本單元是stream和transformation(請(qǐng)注意搪锣,DataSe...
    郭尋撫閱讀 14,942評(píng)論 0 10
  • 我可以一個(gè)人搬家一個(gè)人吃飯秋忙,一個(gè)人逛街一個(gè)人去爬山,一個(gè)人看電影哭到講不出話构舟,做噩夢(mèng)醒來(lái)不知道該叫誰(shuí)的名字灰追。 如果...
    雪漫楊閱讀 249評(píng)論 0 0
  • 時(shí)間過的真快啊,好久沒有寫日記狗超,現(xiàn)在春節(jié)剛過完弹澎,大年初一了,時(shí)間像流水一樣逝去了努咐,一轉(zhuǎn)眼又過去一年苦蒿,歲月不饒人,又...
    志梅閱讀 135評(píng)論 0 0