一朽基、基本特性
1布隔、Flink簡(jiǎn)介
? ????????Flink 是分布式實(shí)時(shí)和離線計(jì)算引擎,用于在無(wú)界數(shù)據(jù)流和有界數(shù)據(jù)流上進(jìn)行有狀態(tài)的計(jì)算稼虎,能在常見(jiàn)集群環(huán)境中運(yùn)行衅檀,并能以內(nèi)存速度和任意規(guī)模進(jìn)行計(jì)算。
????????要的應(yīng)用場(chǎng)景包括:實(shí)時(shí)數(shù)據(jù)計(jì)算霎俩、實(shí)時(shí)數(shù)據(jù)倉(cāng)庫(kù)和ETL哀军、事件驅(qū)動(dòng)型場(chǎng)景学密,如告警、監(jiān)控铺坞;此外,隨著Flink 對(duì)機(jī)器學(xué)習(xí)的支持越來(lái)越完善巨柒,還可以被用作機(jī)器學(xué)習(xí)和人工智能
?
2垫蛆、Flink特性
(1)批流一體:Flink從另一個(gè)視角看待流處理和批處理疹味,將二者統(tǒng)一起來(lái),流處理看待時(shí)輸入數(shù)據(jù)流是無(wú)界的;批處理被作為一種特殊的流處理边臼,只是它的輸入數(shù)據(jù)流被定義為有界的窄锅。
(2)Exactly-Once:Flink 通過(guò)實(shí)現(xiàn)==兩階段提交==和==狀態(tài)保存==來(lái)實(shí)現(xiàn)端到端的精確一致性語(yǔ)義
(3)狀態(tài)管理:Flink在做計(jì)算的過(guò)程中經(jīng)常需要存儲(chǔ)中間狀態(tài)丙曙,來(lái)避免數(shù)據(jù)丟失和狀態(tài)恢復(fù)。
(4)時(shí)間處理:Flink支持事件時(shí)間EventTime、注入時(shí)間IngestionTime、處理時(shí)間ProcessingTime三種時(shí)間,同時(shí)也支持watermark來(lái)處理滯后數(shù)據(jù)。
(5)支持窗口:支持時(shí)間驅(qū)動(dòng)的timeWindow晤揣、數(shù)據(jù)驅(qū)動(dòng)的countWindow,同時(shí)支持滾動(dòng)窗口tumbling windows缕碎、滑動(dòng)窗口sliding windows寨典、會(huì)話窗口session windows骗卜。滾動(dòng)窗口中的數(shù)據(jù)不會(huì)疊加近她;
(6)利用內(nèi)存性能:任務(wù)的狀態(tài)始終保留在內(nèi)存中汤徽,如果狀態(tài)大小超過(guò)可用內(nèi)存娩缰,則會(huì)保存在能高效訪問(wèn)的磁盤(pán)數(shù)據(jù)結(jié)構(gòu)中,非常低的處理延遲,
性能上:ProcessingTime性能最好谒府, IngestTime次之漆羔, EventTime最差
延遲上:EventTime延遲最低,IngestTime次之狱掂, ProcessingTime延遲最高
確定性:EventTime確定性最高, IngestTime次之亲轨, ProcessingTime最低
3趋惨、Exactly-Once精確一次
Flink可以通過(guò)實(shí)現(xiàn)兩階段提交和狀態(tài)保存來(lái)實(shí)現(xiàn)端到端的一致性語(yǔ)義。 分為以下幾個(gè)步驟:
1)開(kāi)始事務(wù)(beginTransaction)創(chuàng)建一個(gè)臨時(shí)文件夾惦蚊,來(lái)寫(xiě)把數(shù)據(jù)寫(xiě)入到這個(gè)文件夾里面
2)預(yù)提交(preCommit)將內(nèi)存中緩存的數(shù)據(jù)寫(xiě)入文件并關(guān)閉
3)正式提交(commit)將之前寫(xiě)完的臨時(shí)文件放入目標(biāo)目錄下器虾。這代表著最終的數(shù)據(jù)會(huì)有一些延遲
4)丟棄(abort)丟棄臨時(shí)文件
5)若失敗發(fā)生在預(yù)提交成功后讯嫂,正式提交前≌咨常可以根據(jù)狀態(tài)來(lái)提交預(yù)提交的數(shù)據(jù)欧芽,也可刪除預(yù)提交的數(shù)據(jù)。
下級(jí)存儲(chǔ)不支持事務(wù):
具體實(shí)現(xiàn)是冪等寫(xiě)入葛圃,需要下級(jí)存儲(chǔ)具有冪等性寫(xiě)入特性千扔。
·一旦Flink開(kāi)始做checkpoint操作,就會(huì)進(jìn)入pre-commit “預(yù)提交”階段库正,同時(shí)JobManager的Coordinator會(huì)將Barrier注入數(shù)據(jù)流中曲楚。
·當(dāng)所有的barrier在算子中成功進(jìn)行一遍傳遞(就是Checkpoint完成),并完成快照后褥符,“預(yù)提交”階段完成龙誊。
·等所有的算子完成“預(yù)提交”,就會(huì)發(fā)起一個(gè)commit “提交”動(dòng)作喷楣,但是任何一個(gè)“預(yù)提交” 失敗都會(huì)導(dǎo)致Flink回滾到最近的checkpoint趟大。
.兩階段提交API
beginTransaction:在開(kāi)啟事務(wù)之前,我們?cè)谀繕?biāo)文件系統(tǒng)的臨時(shí)目錄中創(chuàng)建一個(gè)臨時(shí)文件铣焊,后面在處理數(shù)據(jù)時(shí)將數(shù)據(jù)寫(xiě)入此文件逊朽。
preCommit:在預(yù)提交階段,刷寫(xiě)(flush)文件粗截,然后關(guān)閉文件惋耙,之后就不能寫(xiě)入到文件了,我們還將為屬于下一個(gè)檢查點(diǎn)的任何后續(xù)寫(xiě)入啟動(dòng)新事務(wù)熊昌。
commit:在提交階段绽榛,我們將預(yù)提交的文件原子性移動(dòng)到真正的目標(biāo)目錄中,請(qǐng)注意婿屹,這回增加輸出數(shù)據(jù)可見(jiàn)性的延遲灭美。
abort:在中止階段,我們刪除臨時(shí)文件昂利。
4届腐、狀態(tài)
????????Flink在做計(jì)算的過(guò)程中經(jīng)常需要存儲(chǔ)中間狀態(tài),來(lái)避免數(shù)據(jù)丟失和狀態(tài)恢復(fù)蜂奸。?中間狀態(tài)?state:指一個(gè)具體的task/operator的狀態(tài)犁苏,State可以被記錄,在失敗的情況下數(shù)據(jù)還可以恢復(fù)扩所。
????????Flink中state有兩種基本類(lèi)型的Keyed State與Operator State围详,他們都能以兩種形式存在:原始狀態(tài)(raw state)和托管狀態(tài)(managed state)。
? ??托管狀態(tài):由Flink框架管理的狀態(tài),我們通常使用的就是這種助赞;原始狀態(tài):由用戶自行管理狀態(tài)具體的數(shù)據(jù)結(jié)構(gòu)买羞,一般不常用。
(1)keyed state 記錄的是每個(gè)key的狀態(tài)Keyed state托管狀態(tài)有六種類(lèi)型:ValueState雹食、ListState畜普、MapState、ReducingState群叶、AggregatingState吃挑、FoldingState
(2)operator state是task級(jí)別的state,也就是每個(gè)task對(duì)應(yīng)一個(gè)state盖呼,只有一種托管狀態(tài):ValueState`
5儒鹿、watermark
????????(1)watermark是一個(gè)時(shí)間戳,不是固定值几晤,通過(guò)結(jié)合EventTime與window约炎,來(lái)處理遲到的事件,
????????(2)每個(gè)事件都有一個(gè)CurrentWatermark蟹瘾,相當(dāng)于每個(gè)事件的計(jì)算觸發(fā)時(shí)間圾浅,由ProcessTime 或者EventTime ?改變?yōu)?當(dāng)前watermark時(shí)間
????? (3)計(jì)算方式一般為;
currentMaxEventTime = Math.max(currentMaxEventTime, currentElementEventTime);
new Watermark(currentMaxEventTime - maxOutOfOrderness);
????????正常事件:EventTime大于currentMaxEventTime憾朴,窗口的currentMaxEventTime等于EventTime狸捕,不受影響;
????????? 晚到事件众雷,EventTime小于currentMaxEventTime灸拍,窗口的currentMaxEventTime等于上一個(gè)大的EventTime,
????有了watermark砾省,窗口觸發(fā)的時(shí)間改變鸡岗,window延遲秒觸發(fā),window觸發(fā)的時(shí)間编兄;
(1)watermark 時(shí)間 >= window_end_time
(2)在[window_start_time, window_end_time) 區(qū)間中有數(shù)據(jù)存在轩性,注意是左閉右開(kāi)的區(qū)間,而且是以 event time 來(lái)計(jì)算的
多個(gè)waterMark請(qǐng)看:
????一個(gè)線程觸發(fā)當(dāng)前窗口的waterMark時(shí)間狠鸳,為最大的waterMark時(shí)間揣苏;多并行度時(shí),多個(gè)線程有多個(gè)waterMark件舵,觸發(fā)當(dāng)前窗口的waterMark時(shí)間卸察,取線程間最小的線程內(nèi)最大waterMark時(shí)間。
6铅祸、Flink 容錯(cuò)checkpoint概述
????????Flink 實(shí)現(xiàn)容錯(cuò)蛾派,主要靠強(qiáng)大的CheckPoint 和 State 機(jī)制。Checkpoint 負(fù)責(zé)定時(shí)制作分布式快照、對(duì)程序中的狀態(tài)進(jìn)行備份洪乍;State 用來(lái)存儲(chǔ)計(jì)算過(guò)程中的中間狀態(tài)。
????????Flink 提供了三種可用的狀態(tài)后端用于在不同情況下進(jìn)行狀態(tài)后端的保存:MemoryStateBackend夜焦、FsStateBackend壳澳、RocksDBStateBackend
????????Checkpoint是Flink實(shí)現(xiàn)容錯(cuò)機(jī)制最核心的功能,它能夠根據(jù)配置周期性地基于Stream中各個(gè)Operator/task的狀態(tài)來(lái)生成快照茫经,從而將這些狀態(tài)數(shù)據(jù)定期持久化存儲(chǔ)下來(lái)巷波,當(dāng)Flink程序一旦意外崩潰時(shí),重新運(yùn)行程序時(shí)可以有選擇地從這些快照進(jìn)行恢復(fù)卸伞,從而修正因?yàn)楣收蠋?lái)的程序數(shù)據(jù)異常抹镊;
????Flink的checkpoint機(jī)制,可以與(stream和state)的持久化存儲(chǔ)交互的前提:持久化的source荤傲,它需要支持在一定時(shí)間內(nèi)重放事件垮耳。這種sources的典型例子是持久化的消息隊(duì)列(如 Kafka,RabbitMQ等)或文件系統(tǒng)(比如HDFS等?
7遂黍、Flink 中的分布式快照機(jī)制
????????Flink 容錯(cuò)機(jī)制的核心部分是终佛,制作分布式數(shù)據(jù)流和操作算子狀態(tài)的==一致性快照==,這些快照充當(dāng)一致性 Checkpoint雾家,系統(tǒng)可以在發(fā)生故障時(shí)==回滾==铃彰。Flink 用于制作這些快照的機(jī)制在“分布式數(shù)據(jù)流的輕量級(jí)異步快照”中進(jìn)行了描述,它受到分布式快照的標(biāo)準(zhǔn)Chandy-Lamport 算法的啟發(fā)芯咧,專門(mén)針對(duì) Flink 的執(zhí)行模型而定制牙捉。
????? barrier 在數(shù)據(jù)流源處被注入并行數(shù)據(jù)流中【挫快照 n 的 barrier 被插入的位置(我們稱為 Sn)是快照所包含的數(shù)據(jù)在數(shù)據(jù)源中最大位置邪铲。例如,在 Apache Kafka 中驶拱,此位置將是分區(qū)中最后一條記錄的偏移量霜浴,將該位置 Sn 報(bào)告給 Checkpoint 協(xié)調(diào)器(Flink 的 JobManager)。
????????接著barrier 向下游流動(dòng)蓝纲。當(dāng)一個(gè)中間操作算子從其所有輸入流中收到快照 n 的 barrier 時(shí)阴孟,它會(huì)為快照 n 發(fā)出 barrier 進(jìn)入其所有輸出流中。 一旦 sink 操作算子(流式 DAG 的末端)從其所有輸入流接收到 barrier n税迷,它就向 checkpoint 協(xié)調(diào)器確認(rèn)快照 n 完成永丝。在所有 sink 確認(rèn)快照后,意味著快照已完成箭养。
????????一旦完成快照n慕嚷,job 將永遠(yuǎn)不再向數(shù)據(jù)源請(qǐng)求 Sn 之前的記錄,因?yàn)榇藭r(shí)這些記錄(及其后續(xù)記錄)將已經(jīng)通過(guò)整個(gè)數(shù)據(jù)流拓?fù)洌布匆呀?jīng)被處理結(jié)束喝检。
8嗅辣、Flink 中的內(nèi)存管理
????????Flink并不是將大量對(duì)象存在堆上,而是將對(duì)象都序列化到一個(gè)預(yù)分配的內(nèi)存塊上挠说,此外澡谭,F(xiàn)link 大量使用了堆外內(nèi)存。如果需要處理的數(shù)據(jù)超出了內(nèi)存限制损俭,則會(huì)將部分?jǐn)?shù)據(jù)存儲(chǔ)到硬盤(pán)上蛙奖。Flink 為了直接操作二進(jìn)制數(shù)據(jù),實(shí)現(xiàn)了自己的序列化框架杆兵。
理論上Flink 的內(nèi)存管理分為以下 3 部分雁仲。
(1)Network Buffers:這個(gè)是在 TaskManager 啟動(dòng)的時(shí)候分配的,這是一組用于緩存網(wǎng)絡(luò)數(shù)據(jù)的內(nèi)存琐脏,每個(gè)塊是 32K攒砖,默認(rèn)分配 2048 個(gè),可以通過(guò)“taskmanager.network .numberOfBuffers”修改骆膝。
(2)Memory Manage pool:大量的 Memory Segment 塊祭衩,用于運(yùn)行時(shí)的算法(Sort/Join/Shuffle 等),這部分啟動(dòng)時(shí)會(huì)被分配阅签。根據(jù)配置文件中的各種參數(shù)來(lái)計(jì)算內(nèi)存的分配方法掐暮,并且內(nèi)存的分配支持預(yù)分配和 lazy load,默認(rèn)懶加載的方式政钟。
(3)User Code路克,這個(gè)是除了 Memory Manager 之外的內(nèi)存用于 User Code 和 TaskManager 本身的數(shù)據(jù)結(jié)構(gòu)。
二养交、與其他框架的異同
1精算、Flink 和 Spark Streaming 的異同點(diǎn)有哪些?
1碎连、架構(gòu)上:
????????Flink 是實(shí)時(shí)處理引擎灰羽,基于事件驅(qū)動(dòng),會(huì)根據(jù)用戶的代碼處理成Stream Graph鱼辙,然后優(yōu)化成為 JobGraph廉嚼,與 Storm 形成的拓?fù)?Topology 結(jié)構(gòu)類(lèi)似。
????????而 Spark Streaming 是微批(Micro-Batch)的模型倒戏,架構(gòu)是基于Spark怠噪,可以把 Spark Streaming 理解為時(shí)間維度上的 Spark DAG。
2杜跷、時(shí)間機(jī)制:
????????Spark Streaming只支持處理時(shí)間傍念。
????????Flink支持處理時(shí)間矫夷、事件時(shí)間、注入時(shí)間憋槐。同時(shí)也支持watermark來(lái)處理滯后數(shù)據(jù)双藕。
3、容錯(cuò)機(jī)制:
????????Spark Streaming 通過(guò)checkpoint實(shí)現(xiàn)數(shù)據(jù)不丟失阳仔,但無(wú)法做到恰好一次處理語(yǔ)義蔓彩。
????????Flink 則使用兩階段提交協(xié)議和checkpoint實(shí)現(xiàn)精準(zhǔn)一次處理,容錯(cuò)性好驳概。
4、反壓機(jī)制:
????????Flink 在數(shù)據(jù)傳輸過(guò)程中使用了分布式阻塞隊(duì)列旷赖;
????????Spark Streaming 用到PID 算法顺又,構(gòu)造了一個(gè)速率控制器,任務(wù)的結(jié)束時(shí)間等孵、處理時(shí)長(zhǎng)稚照、處理消息的條數(shù)。
?2俯萌、flink kafka
????flink提供了一個(gè)特有的kafka connector去讀寫(xiě)kafka topic的數(shù)據(jù)果录。
????flink消費(fèi)kafka數(shù)據(jù),并不是完全通過(guò)跟蹤kafka消費(fèi)組的offset來(lái)實(shí)現(xiàn)去保證exactly-once的語(yǔ)義咐熙,而是flink內(nèi)部去跟蹤offset和做checkpoint去實(shí)現(xiàn)exactly-once的語(yǔ)義弱恒,而且對(duì)于kafka的partition,F(xiàn)link會(huì)啟動(dòng)對(duì)應(yīng)的并行度去處理kafka當(dāng)中的每個(gè)分區(qū)的數(shù)據(jù)
????flink整合kafka官網(wǎng)介紹
????????實(shí)際工作當(dāng)中一般都是將kafka作為flink的source來(lái)使用棋恼,先創(chuàng)建好kafka的topic返弹,在建maven工程時(shí)porm文件導(dǎo)入flink-connector-kafka的包,在代碼里配置好fink的sour為kafka爪飘。
3义起、Flink 的運(yùn)行必須依賴 Hadoop組件嗎?
????????Flink可以完全獨(dú)立于Hadoop师崎,在不依賴Hadoop組件下運(yùn)行默终。但是做為大數(shù)據(jù)的基礎(chǔ)設(shè)施,Hadoop體系是任何大數(shù)據(jù)框架都繞不過(guò)去的犁罩。Flink可以集成眾多Hadooop 組件齐蔽,例如Yarn、Hbase昼汗、HDFS等等肴熏。例如,F(xiàn)link可以和Yarn集成做資源調(diào)度顷窒,也可以讀寫(xiě)HDFS蛙吏,或者利用HDFS做檢查點(diǎn)源哩。
4、Flink 的 checkpoint 機(jī)制對(duì)比 spark 有什么不同和優(yōu)勢(shì)鸦做?
????????spark streaming 的 checkpoint 僅僅是針對(duì) driver 的故障恢復(fù)做了數(shù)據(jù)和元數(shù)據(jù)的 checkpoint励烦。
????????而 flink 的 checkpoint 機(jī)制 要復(fù)雜了很多,它采用的是輕量級(jí)的分布式快照泼诱,實(shí)現(xiàn)了每個(gè)算子的快照坛掠,及流動(dòng)中的數(shù)據(jù)的快照。
三治筒、架構(gòu)
1屉栓、Flink架構(gòu)
(1)JobManager:管理者M(jìn)aster,它是整個(gè)集群的協(xié)調(diào)者耸袜,負(fù)責(zé)接收 Job友多、協(xié)調(diào)檢查點(diǎn)、Failover 故障恢復(fù)等堤框,同時(shí)管理 Flink 集群中從節(jié)點(diǎn) TaskManager域滥。
(2)TaskManager:負(fù)責(zé)執(zhí)行計(jì)算的Worker,執(zhí)行 Flink Job 的一組 Task蜈抓,每個(gè) TaskManager 負(fù)責(zé)管理其所在節(jié)點(diǎn)上的資源信息启绰,比如內(nèi)存、磁盤(pán)沟使、網(wǎng)絡(luò)委可,在啟動(dòng)的時(shí)候?qū)①Y源的狀態(tài)向 JobManager 匯報(bào)。
(3)Client:Flink 程序提交的客戶端格带,當(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虎眨。
2、JobManger 在集群中扮演了什么角色镶摘?
????????JobManager 負(fù)責(zé)整個(gè) Flink 集群==任務(wù)調(diào)度==及==資源管理==嗽桩,從客戶端中獲取提交的應(yīng)用,然后根據(jù)集群中 TaskManager 上 TaskSlot 的使用情況凄敢,為提交的應(yīng)用分配相應(yīng)的 TaskSlot 資源并命令 TaskManager 啟動(dòng)從客戶端中獲取的應(yīng)用碌冶。
????????JobManager 相當(dāng)于整個(gè)集群的 Master 節(jié)點(diǎn),且整個(gè)集群有且只有一個(gè)活躍的 JobManager涝缝,負(fù)責(zé)整個(gè)集群的任務(wù)管理和資源管理扑庞。
????????JobManager 和 TaskManager 之間通過(guò)Actor System進(jìn)行通信譬重,獲取任務(wù)執(zhí)行的情況并通過(guò)Actor System 將應(yīng)用的任務(wù)執(zhí)行情況發(fā)送給客戶端。
????????在任務(wù)執(zhí)行的過(guò)程中罐氨,JobManager 會(huì)觸發(fā)Checkpoint操作臀规,每個(gè)TaskManager 節(jié)點(diǎn)收到 Checkpoint 觸發(fā)指令后,完成 Checkpoint 操作栅隐,所有的 Checkpoint 協(xié)調(diào)過(guò)程都是在 Fink JobManager 中完成塔嬉。
????????任務(wù)完成后,F(xiàn)link 會(huì)將任務(wù)執(zhí)行的信息反饋給客戶端租悄,并且釋放掉 TaskManager 中的資源以供下一次提交任務(wù)使用谨究。
3、JobManger 在集群?jiǎn)?dòng)過(guò)程中起到什么作用泣棋?
????????首先记盒,我們要回答出JobManager 的主要職責(zé),主要包括負(fù)責(zé)整個(gè) Flink 集群任務(wù)調(diào)度和資源的管理外傅,并且負(fù)責(zé)接收 Flink 作業(yè)、調(diào)度 Task俩檬、收集作業(yè)狀態(tài)和管理 TaskManager萎胰。
????????然后,如果開(kāi)發(fā)者能從源碼層面回答出涉及的關(guān)鍵方法棚辽,會(huì)大大增加面試官的印象
(1)RegisterTaskManager:它由想要注冊(cè)到 JobManager 的 TaskManager 發(fā)送技竟,注冊(cè)成功則通過(guò) AcknowledgeRegistration 消息進(jìn)行 Ack。
(2)SubmitJob:將 Job 提交給 Client屈藐,提交的信息是 JobGraph 形式的作業(yè)描述信息榔组。
(3)CancelJob:請(qǐng)求取消指定ID的作業(yè),成功會(huì)返回 CancellationSuccess联逻,否則返回 CancellationFailure搓扯。
(4)UpdateTaskExecutionState:由 TaskManager 發(fā)送,用來(lái)更新執(zhí)行節(jié)點(diǎn)(ExecutionVertex)的狀態(tài)包归;成功則返回 true锨推,否則返回 false。
(5)RequestNextInputSplit:TaskManager 上的 Task 請(qǐng)求下一個(gè)輸入 split公壤,成功則返回 NextInputSplit换可,否則返回 null。
(6)JobStatusChanged:它意味著作業(yè)的狀態(tài)(RUNNING厦幅、CANCELING沾鳄、FINISHED等)發(fā)生變化,這個(gè)消息由 ExecutionGraph 發(fā)送确憨。
4译荞、TaskManager 在集群中扮演了什么角色瓤的?
????????TaskManager 相當(dāng)于整個(gè)集群的 Slave 節(jié)點(diǎn),負(fù)責(zé)具體的==任務(wù)執(zhí)行==和對(duì)應(yīng)任務(wù)在每個(gè)節(jié)點(diǎn)上的==資源申請(qǐng)和管理==磁椒。
????????客戶端通過(guò)將編寫(xiě)好的Flink 應(yīng)用編譯打包堤瘤,提交到 JobManager,然后 JobManager 會(huì)根據(jù)已注冊(cè)在 JobManager 中 TaskManager 的資源情況浆熔,將任務(wù)分配給有資源的 TaskManager 節(jié)點(diǎn)本辐,然后啟動(dòng)并運(yùn)行任務(wù)看杭。
????????TaskManager 從 JobManager 接收需要部署的任務(wù)碑定,然后使用 Slot 資源啟動(dòng) Task,建立數(shù)據(jù)接入的網(wǎng)絡(luò)連接咱旱,接收數(shù)據(jù)并開(kāi)始數(shù)據(jù)處理叶骨。同時(shí) TaskManager 之間的數(shù)據(jù)交互都是通過(guò)數(shù)據(jù)流的方式進(jìn)行的茫多。
????????Flink 的任務(wù)運(yùn)行其實(shí)是采用多線程的方式,這和 MapReduce 多 JVM 并行的方式有很大的區(qū)別忽刽,F(xiàn)link 能夠極大提高 CPU 使用效率天揖,在多個(gè)任務(wù)和 Task 之間通過(guò) TaskSlot 方式共享系統(tǒng)資源,每個(gè) TaskManager 中通過(guò)管理多個(gè) TaskSlot 資源池對(duì)資源進(jìn)行有效管理跪帝。
5今膊、TaskManger 的啟動(dòng)過(guò)程是怎樣的?
????????相比JobManager而言伞剑,TaskManager 的啟動(dòng)流程較為簡(jiǎn)單斑唬,啟動(dòng)類(lèi)入口為`org.apache.flink.runtime.taskexecutor.TaskManagerRunner`。
啟動(dòng)過(guò)程中主要進(jìn)行Slot 資源的分配黎泣、RPC 服務(wù)的初始化恕刘,以及JobManager 進(jìn)行通信等。
6抒倚、Flink 組件棧和數(shù)據(jù)流模型褐着。
(1)DataStream API:對(duì)數(shù)據(jù)流進(jìn)行流處理操作,將流式的數(shù)據(jù)抽象成分布式的數(shù)據(jù)流托呕,支持 Java 和 Scala献起;
(2)DataSet API:對(duì)靜態(tài)數(shù)據(jù)進(jìn)行批處理操作,將靜態(tài)數(shù)據(jù)抽象成分布式的數(shù)據(jù)集镣陕,支持 Java谴餐、Scala 和 Python;
(3)Table API:對(duì)結(jié)構(gòu)化數(shù)據(jù)進(jìn)行查詢操作呆抑,將結(jié)構(gòu)化數(shù)據(jù)抽象成關(guān)系表岂嗓,并通過(guò)類(lèi) SQL 的 DSL 對(duì)關(guān)系表進(jìn)行各種查詢操作,支持 Java 和 Scala鹊碍。
(4)Flink ML:提供了機(jī)器學(xué)習(xí) Pipelines API 并實(shí)現(xiàn)了多種機(jī)器學(xué)習(xí)算法厌殉;Gelly食绿、Flink 的圖計(jì)算庫(kù)提供了圖計(jì)算的相關(guān) API 及多種圖計(jì)算算法的實(shí)現(xiàn)。
????????這些流暢的API 提供了用于數(shù)據(jù)處理的通用構(gòu)建塊公罕,比如各種形式用戶指定的轉(zhuǎn)換器紧、連接、聚合楼眷、窗口铲汪、狀態(tài)等。
????????Flink 程序的基本構(gòu)建是數(shù)據(jù)輸入來(lái)自一個(gè) Source罐柳,Source 代表數(shù)據(jù)的輸入端掌腰,經(jīng)過(guò) Transformation 進(jìn)行轉(zhuǎn)換,然后在一個(gè)或者多個(gè) Sink 接收器中結(jié)束张吉。數(shù)據(jù)流(Stream)就是一組永遠(yuǎn)不會(huì)停止的數(shù)據(jù)記錄流齿梁,而轉(zhuǎn)換(Transformation)是將一個(gè)或多個(gè)流作為輸入,并生成一個(gè)或多個(gè)輸出流的操作肮蛹。在執(zhí)行時(shí)勺择,F(xiàn)link 程序映射到 Streaming Dataflows,由流(Streams)和轉(zhuǎn)換操作(Transformation Operators)組成伦忠。
四酵幕、計(jì)算資源
1、Flink計(jì)算資源 Task Slot缓苛。
????在Flink 中,一個(gè) TaskManger 就是一個(gè) JVM 進(jìn)程邓深,會(huì)用獨(dú)立的線程來(lái)執(zhí)行 Task未桥。為了控制一個(gè)TaskManger能接受多少個(gè)Task,F(xiàn)link 提出了Task Slot的概念芥备,可以把Task Slot理解為T(mén)askManager的計(jì)算資源子集冬耿。
????????假如一個(gè)TaskManager 擁有5個(gè)Slot,那么該TaskManager的計(jì)算資源會(huì)被平均分為5份萌壳,不同的Task在不同的Slot中執(zhí)行亦镶,避免資源競(jìng)爭(zhēng)。Slot 僅僅用來(lái)做內(nèi)存的隔離袱瓮,對(duì) CPU 不起作用缤骨。
????????運(yùn)行在同一個(gè)JVM 的 Task 可以共享 TCP 連接,以減少網(wǎng)絡(luò)傳輸尺借,在一定程度上提高了程序的運(yùn)行效率绊起,降低了資源消耗。
2燎斩、Flink 計(jì)算資源的調(diào)度是如何實(shí)現(xiàn)的虱歪?
????????TaskManager 中最細(xì)粒度的資源是 Task slot蜂绎,代表了一個(gè)固定大小的資源子集,每個(gè) TaskManager 會(huì)將其所占有的資源平分給它的 slot笋鄙。
????????通過(guò)調(diào)整task slot 的數(shù)量师枣,用戶可以定義 task 之間是如何相互隔離的。每個(gè) TaskManager 有一個(gè) slot萧落,也就意味著每個(gè) task 運(yùn)行在獨(dú)立的 JVM 中践美;每個(gè) TaskManager中有多個(gè) slot 的話,也就意味著多個(gè) task 運(yùn)行在同一個(gè) JVM 中铐尚。
????????而在同一個(gè)JVM 進(jìn)程中的 task拨脉,可以共享 TCP 連接(基于多路復(fù)用)和心跳消息,可以減少數(shù)據(jù)的網(wǎng)絡(luò)傳輸宣增,也能共享一些數(shù)據(jù)結(jié)構(gòu)玫膀,在一定程度上減少了每個(gè) task 的消耗。
????????每個(gè)slot 可以接受單個(gè) task爹脾,也可以接受多個(gè)連續(xù) task 組成的 pipeline.
????????FlatMap 函數(shù)占用一個(gè) taskslot帖旨,而 key Agg 函數(shù)和 sink 函數(shù)共用一個(gè) taskslot:
3、Flink 的數(shù)據(jù)抽象及數(shù)據(jù)交換過(guò)程灵妨?
????????JVM 在對(duì)象序列化上有一些固有的缺陷解阅,主要體現(xiàn)在存儲(chǔ)對(duì)象的密度較低,含有大量不需要的信息泌霍,并且FGC 還會(huì)對(duì)整體的吞吐和響應(yīng)有嚴(yán)重影響货抄。
????????為了降低這些影響,F(xiàn)link 實(shí)現(xiàn)了自己的內(nèi)存管理朱转。主要體現(xiàn)在蟹地,F(xiàn)link 定義了自己的內(nèi)存抽象:`MemorySegment`,可以把MemorySegment 看作是一個(gè) 32KB大的內(nèi)存塊的抽象,這塊內(nèi)存既可以是 JVM 里的一個(gè) byte[]藤为,也可以是堆外內(nèi)存(DirectByteBuffer)怪与。在 MemorySegment 這個(gè)抽象之上,F(xiàn)link 抽象出了兩個(gè)關(guān)鍵的進(jìn)行數(shù)據(jù)轉(zhuǎn)換的類(lèi):
Buffer缅疟,用于各個(gè) TaskManager 進(jìn)行數(shù)據(jù)傳輸分别;
StreamRecord,用于 Java 對(duì)象和 Buffer 對(duì)象互相轉(zhuǎn)換存淫。
4耘斩、Flink 中的并行度設(shè)置
并行度,某一個(gè)算子被切分成多少個(gè)子任務(wù)桅咆。
Flink 本并行度的優(yōu)先級(jí)依次是:1算子級(jí)別 > 2環(huán)境級(jí)別 > 3客戶端級(jí)別 > 4集群配置級(jí)別煌往。
5、Operator Chain ?
????????算子鏈?zhǔn)俏覀冞M(jìn)行任務(wù)調(diào)優(yōu)一定會(huì)遇到的問(wèn)題,主要考察我們對(duì)于概念是否正確理解刽脖,實(shí)際操作中有怎樣的指導(dǎo)作用羞海。
????????為了更高效地分布式執(zhí)行,F(xiàn)link 會(huì)盡可能地將Operator的Subtask鏈接(Chain)在一起形成 Task曲管,每個(gè) Task 在一個(gè)線程中執(zhí)行却邓。
????????將Operators 鏈接成 Task 是非常有效的優(yōu)化,它能減少:①線程之間的切換院水; ②消息的序列化/反序列化腊徙;③數(shù)據(jù)在緩沖區(qū)的交換;④延遲的同時(shí)提高整體的吞吐量檬某。
6撬腾、Flink什么情況下才會(huì)把Operator chain在一起形成算子鏈?
(1)上下游并行度一致
(2)下游數(shù)據(jù)沒(méi)有其他的輸入
(3)上下游節(jié)點(diǎn)都在同一個(gè)soltgroup中恢恼,默認(rèn)是一樣的民傻,如果不是,單獨(dú)指定的算子資源场斑,會(huì)獨(dú)占TaskSolt
(4)沒(méi)有keyed操作
(5)數(shù)據(jù)發(fā)送策略是forward
(6)用戶沒(méi)有禁用chain
7漓踢、數(shù)據(jù)傾斜問(wèn)題?Flink 中的 Window 出現(xiàn)了數(shù)據(jù)傾斜漏隐,你有什么解決辦法喧半?
產(chǎn)生數(shù)據(jù)傾斜的原因主要有2 個(gè)方面:
①業(yè)務(wù)上有嚴(yán)重的數(shù)據(jù)熱點(diǎn),比如滴滴打車(chē)的訂單數(shù)據(jù)中北京青责、上海等幾個(gè)城市的訂單量遠(yuǎn)遠(yuǎn)超過(guò)其他地區(qū)挺据;
②技術(shù)上大量使用了 KeyBy、GroupBy 等操作脖隶,錯(cuò)誤使用了分組 Key扁耐,人為產(chǎn)生數(shù)據(jù)熱點(diǎn)。
因此解決問(wèn)題的思路也很清晰:
①業(yè)務(wù)上要盡量避免熱點(diǎn) key 的設(shè)計(jì)浩村,例如我們可以把北京、上海等熱點(diǎn)城市分成不同的區(qū)域占哟,并進(jìn)行單獨(dú)處理心墅;
②技術(shù)上出現(xiàn)熱點(diǎn)時(shí),要調(diào)整方案打散原來(lái)的 key榨乎,避免直接聚合怎燥;此外 Flink 還提供了大量的功能可以避免數(shù)據(jù)傾斜。
?五蜜暑、任務(wù)提交
1铐姚、任務(wù)提交流程(YARN)
· (1)Flink任務(wù)提交后,Client向HDFS上傳Flink的Jar包和配置
· (2)隨后向Yarn ResourceManager提交任務(wù),ResourceManager分配Container資源并通知對(duì)應(yīng)的NodeManager啟動(dòng)
· (3)ApplicationMaster隐绵,ApplicationMaster啟動(dòng)后加載Flink的Jar包和配置構(gòu)建環(huán)境之众,然后啟動(dòng)JobManager,之后ApplicationMaster向ResourceManager申請(qǐng)資源啟動(dòng) TaskManager
· (4)ResourceManager分配Container資源后依许,由ApplicationMaster通知資源所在節(jié)點(diǎn)的NodeManager啟動(dòng)TaskManager
· (5)NodeManager加載Flink的Jar包和配置構(gòu)建環(huán)境并啟動(dòng)TaskManager
· (6)TaskManager啟動(dòng)后向JobManager發(fā)送心跳包棺禾,并等待JobManager向其分配任務(wù)。
2峭跳、Flink 任務(wù)出現(xiàn)很高的延遲膘婶,你會(huì)如何入手解決類(lèi)似問(wèn)題?
(1)在Flink 的后臺(tái)任務(wù)管理中蛀醉,可以看到 Flink 的哪個(gè)算子和 task 出現(xiàn)了反壓悬襟;
(2)資源調(diào)優(yōu)和算子調(diào)優(yōu),對(duì)作業(yè)中的并發(fā)數(shù)(Parallelism)拯刁、CPU(Core)脊岳、堆內(nèi)存(Heap_memory)等參數(shù)進(jìn)行調(diào)優(yōu);
作業(yè)參數(shù)調(diào)優(yōu)筛璧,并行度的設(shè)置逸绎、State 的設(shè)置、Checkpoint 的設(shè)置夭谤。
請(qǐng)談?wù)勀銈兪侨绾翁幚砼K數(shù)據(jù)的棺牧?
????????????這也是一個(gè)開(kāi)放性的面試題,建議你結(jié)合自己的實(shí)際業(yè)務(wù)來(lái)談朗儒。比如可以通過(guò)一個(gè)fliter 算子將不符合規(guī)則的數(shù)據(jù)過(guò)濾出去颊乘。當(dāng)然了,我們也可以在數(shù)據(jù)源頭就將一些不合理的數(shù)據(jù)拋棄醉锄,不允許進(jìn)入 Flink 系統(tǒng)參與計(jì)算乏悄。
2、Flink Job 的提交流程恳不。
(1)用戶提交的Flink Job 會(huì)被轉(zhuǎn)化成一個(gè) DAG 任務(wù)運(yùn)行檩小。Flink Job 的提交涉及的類(lèi)主要包括:`StreamGraph、JobGraph烟勋、ExecutionGraph规求、TaskManager、JobManager卵惦、ResourceManager`阻肿。
(2)JobManager 會(huì)把接收到的需要執(zhí)行的應(yīng)用程序進(jìn)行打包,然后把 JobGraph 轉(zhuǎn)換成可以執(zhí)行的ExecutionGraph沮尿,接著向 ResourceManager 請(qǐng)求執(zhí)行任務(wù)所需要的資源丛塌,也就是我們之前課程中提到的 Slot,如果資源獲取成功 JobManager 會(huì)負(fù)責(zé)所有的任務(wù)調(diào)度,比如 Checkpoint赴邻,并且將任務(wù)派發(fā)給 TaskManager 去執(zhí)行印衔。
3、Flink 的“三層圖”結(jié)構(gòu)是什么意思乍楚?
> 這道題要求面試者掌握Flink 框架引擎劃分執(zhí)行計(jì)劃的詳細(xì)過(guò)程当编。
一個(gè)Flink 任務(wù)的 DAG 生成計(jì)算圖,大致經(jīng)歷以下3個(gè)過(guò)程徒溪。
(1)首先忿偷,StreamGraph的拓?fù)浣Y(jié)構(gòu),最接近代碼層面臊泌,主要由 StreamNode和 StreamEdge構(gòu)成鲤桥,其中 StreamNode`對(duì)應(yīng)著 Operator,它們通過(guò) StreamEdge進(jìn)行鏈接渠概。
(2)其次茶凳,JobGraph,是能被Flink引擎識(shí)別的數(shù)據(jù)結(jié)構(gòu)播揪,由JobVertex贮喧、JobEdge和 IntermediateDataSet3個(gè)元素組成。我們可以把JobGraph形象地比喻為一個(gè)抽水系統(tǒng)猪狈,JobVertex`是水泵箱沦,JobEdge`是水管,而 IntermediateDataSet則是中間的蓄水池雇庙。
(3)最后谓形,ExecutionGraph,由 JobGraph 轉(zhuǎn)換而來(lái)疆前,包含了任務(wù)具體執(zhí)行所需的內(nèi)容寒跳,是最貼近底層實(shí)現(xiàn)的執(zhí)行圖。
4竹椒、談?wù)凢link 的 SQL 部分是如何實(shí)現(xiàn)的童太?
????????Table SQL 是 Flink 提供的高級(jí) API 操作。Flink SQL 是 Flink 實(shí)時(shí)計(jì)算為簡(jiǎn)化計(jì)算模型胸完,降低用戶使用實(shí)時(shí)計(jì)算門(mén)檻而設(shè)計(jì)的一套符合標(biāo)準(zhǔn) SQL 語(yǔ)義的開(kāi)發(fā)語(yǔ)言书释。
????????????Flink 把 SQL 的 解析、優(yōu)化 和 執(zhí)行**教給了==Calcite==舶吗。從圖中可以看到征冷,無(wú)論是批查詢 SQL 還是流式查詢 SQL择膝,都會(huì)經(jīng)過(guò)對(duì)應(yīng)的轉(zhuǎn)換器 Parser 轉(zhuǎn)換成為節(jié)點(diǎn)樹(shù) SQLNode tree誓琼,然后生成邏輯執(zhí)行計(jì)劃 Logical Plan,邏輯執(zhí)行計(jì)劃在經(jīng)過(guò)優(yōu)化后生成真正可以執(zhí)行的物理執(zhí)行計(jì)劃,交給 DataSet 或者 DataStream 的 API 去執(zhí)行腹侣。
https://mp.weixin.qq.com/s/xRqrojjFITuhswtjNJo7OQ
6叔收、Flink的CEP機(jī)制
????????CEP全稱為Complex Event Processing,復(fù)雜事件處傲隶。Flink CEP是在 Flink 中實(shí)現(xiàn)的復(fù)雜事件處理(CEP)庫(kù)饺律,CEP 允許在無(wú)休止的事件流中檢測(cè)事件模式,讓我們有機(jī)會(huì)掌握數(shù)據(jù)中重要的部分跺株。一個(gè)或多個(gè)由簡(jiǎn)單事件構(gòu)成的事件流通過(guò)一定的規(guī)則匹配复濒,然后輸出用戶想得到的數(shù)據(jù)—— 滿足規(guī)則的復(fù)雜事件
7、Flink-On-Yarn常見(jiàn)的提交模式有哪些乒省,分別有什么優(yōu)缺點(diǎn)巧颈?
1.yarn-session模式:
????????這種方式需要先啟動(dòng)集群,然后在提交作業(yè)袖扛,接著會(huì)向yarn申請(qǐng)一塊空間后砸泛,資源永遠(yuǎn)保持不變。如果資源滿了蛆封,下一個(gè)就任務(wù)就無(wú)法提交唇礁,只能等到y(tǒng)arn中其中一個(gè)作業(yè)完成后,釋放了資源惨篱,那下一個(gè)作業(yè)才會(huì)正常提交盏筐,這種方式資源被限制在session中,不能超過(guò)妒蛇,比較適合特定的運(yùn)行環(huán)境或測(cè)試環(huán)境机断。
2.per-job模式:
????????這種方式直接在yarn上提交任務(wù)運(yùn)行Flink作業(yè),這種方式的好處是一個(gè)任務(wù)會(huì)對(duì)應(yīng)一個(gè)job绣夺,即每提交一個(gè)作業(yè)會(huì)根據(jù)自身的情況,向yarn中申請(qǐng)資源奋蔚,直到作業(yè)執(zhí)行完成烈钞,并不會(huì)影響下一個(gè)作業(yè)的正常運(yùn)行泊碑,除非是yarn上面沒(méi)有任何資源的情況下。一般生產(chǎn)環(huán)境是采用此方式運(yùn)行馒过。這種方式需要保證集群資源足夠酗钞。
六腹忽、代碼相關(guān)
1.Flink連接API
(1)union 多流合并来累,類(lèi)型一致
(2)connect 兩條流分別處理,類(lèi)型可不一致嘹锁,可共享狀態(tài)
(3)join 相當(dāng)于innerjoin
(4)coGroup 實(shí)現(xiàn)左外連接着裹,第一個(gè)流沒(méi)有join上,也要輸出