本文的整體結(jié)構(gòu)為 一些概念 6個(gè)問題 2個(gè)demo 一次解答
dataflow 流處理的基本概念和名詞
-
dataflow基本概念,首先至少包含一個(gè)數(shù)據(jù)源和一個(gè)數(shù)據(jù)匯,即輸入和輸出,如下圖
圖1-1
-
數(shù)據(jù),任務(wù)并行
- 數(shù)據(jù)并行 圖 1-1就是數(shù)據(jù)并行
- 任務(wù)并行 如果數(shù)據(jù)源也并行 數(shù)據(jù)匯也并行 那么全任務(wù)均并行 就是任務(wù)并行
-
數(shù)據(jù)交換策略
- 轉(zhuǎn)發(fā)
- 發(fā)送端和接收端任務(wù)一對(duì)一傳輸 如果兩個(gè)任務(wù)在同一臺(tái)物理機(jī)可以避免數(shù)據(jù)交換(由任務(wù)調(diào)度器決定)
- 廣播
- 將數(shù)據(jù)分發(fā)到下游的全部算子 數(shù)據(jù)會(huì)被復(fù)制多份 并涉及網(wǎng)絡(luò)通信 代價(jià)昂貴
- 鍵值
- 同廣播 不過不全部復(fù)制 僅根據(jù)鍵值復(fù)制 減少開銷 將同鍵值的數(shù)據(jù)交給同一個(gè)任務(wù)處理 如圖3-1圖書分類就是根據(jù)鍵值分類 保證統(tǒng)計(jì)的準(zhǔn)確性
- 隨機(jī)
- 將數(shù)據(jù)均勻分布到下游算子 實(shí)現(xiàn)任務(wù)負(fù)載均衡
- 轉(zhuǎn)發(fā)
-
窗口類型 桶
-
滾動(dòng)窗口(不重疊count-based time-based)
- 場(chǎng)景 每分鐘 流量統(tǒng)計(jì)
- 圖1-3-1
- 場(chǎng)景 每分鐘 流量統(tǒng)計(jì)
-
滑動(dòng)窗口(重疊count-based time-based)
- 兩個(gè)參數(shù) 偏移量和間隔
- 場(chǎng)景 每隔10分鐘 統(tǒng)計(jì)1小時(shí)內(nèi)的平均溫度
- 圖1-3-2
-
會(huì)話窗口(一組事件為一個(gè)會(huì)話 可以設(shè)置非活動(dòng)最大等待時(shí)間)
- 根據(jù)一個(gè)事件key分組打開窗口
- 用戶行為分析
-
-
時(shí)間語義
-
處理時(shí)間
- 場(chǎng)景 實(shí)時(shí)監(jiān)控儀表盤
- 特性 低延遲 速度快
-
事件時(shí)間
- 場(chǎng)景 用戶行為分析 用戶網(wǎng)絡(luò)突然中斷 當(dāng)網(wǎng)絡(luò)恢復(fù)后 可以完整有序的重放用戶行為
- 特性 允許延遲 支持亂序
-
-
狀態(tài)
- 某間隔一段時(shí)間 基于一定個(gè)數(shù)的事件 積累狀態(tài) 有狀態(tài)算子同時(shí)使用傳入的事件和內(nèi)部狀態(tài)計(jì)算輸出
- 場(chǎng)景 高溫?zé)熿F預(yù)警 高溫10分鐘內(nèi) 產(chǎn)生煙霧則告警
- 特性 注意避免狀態(tài)無限增長因?yàn)榱魇菬o限的 通常保存的是摘要(數(shù)量值或者累加值)
- 某間隔一段時(shí)間 基于一定個(gè)數(shù)的事件 積累狀態(tài) 有狀態(tài)算子同時(shí)使用傳入的事件和內(nèi)部狀態(tài)計(jì)算輸出
-
故障
- 任務(wù)故障 ①接收事件并保存在本地緩存區(qū) ②選擇性更新狀態(tài) ③產(chǎn)生輸出 任意節(jié)點(diǎn)都將會(huì)產(chǎn)生故障 這些故障如何恢復(fù)
- 結(jié)果保障 主要強(qiáng)調(diào)引擎內(nèi)部狀態(tài)一致 輸出一致需要靠事務(wù)或重試保證(數(shù)據(jù)匯寫出的數(shù)據(jù)不受保護(hù))
- 至多一次 其實(shí)就是沒保障 數(shù)據(jù)丟了也不需要重放
- 至少一次 事件不丟失 可能重復(fù)多次 正確性僅依賴數(shù)據(jù)完整度 可以依賴事件重放或者ack(rabbitmq就是ack)即完成后回調(diào)確認(rèn)
- 精確一次 最困難最嚴(yán)格的保障 在至少一次的基礎(chǔ)上實(shí)現(xiàn) 可以通過事務(wù)但是會(huì)有極大開銷 flink支持精確一次 但是根據(jù)輕量級(jí)的檢查點(diǎn)機(jī)制(需滿足數(shù)據(jù)可回放,且可在上次故障點(diǎn)之后回放) 在統(tǒng)計(jì)出現(xiàn)次數(shù)的時(shí)候很有必要
flink是什么
Apache Flink 是一個(gè)框架和分布式處理引擎,用于在【無邊界】和【有邊界】數(shù)據(jù)流上進(jìn)行【有狀態(tài)】的計(jì)算。Flink 能在所有常見集群環(huán)境中運(yùn)行,并能以【內(nèi)存速度】和【任意規(guī)?!窟M(jìn)行計(jì)算
-
有邊界和無邊界的數(shù)據(jù)流 【window】
- 流應(yīng)用數(shù)據(jù)源源不斷 有時(shí)候需要通過窗口的形式對(duì)數(shù)據(jù)劃分邊界 并針對(duì)窗口進(jìn)行統(tǒng)計(jì) 窗口支持time,count,session劃分 比如每分鐘的訪問量等
-
支持事件時(shí)間
- process time 當(dāng)前系統(tǒng)時(shí)間
- event time 事件產(chǎn)生時(shí)間 在窗口計(jì)算的時(shí)候 亂序的數(shù)據(jù)可以還原原本的時(shí)序性
-
有狀態(tài)
- 將計(jì)算的結(jié)果保存在內(nèi)存或者文件系統(tǒng)中 這樣下一次計(jì)算事件來了 可以直接根據(jù)上一次的計(jì)算結(jié)果進(jìn)行計(jì)算 避免將歷史數(shù)據(jù)都導(dǎo)出來重寫算一遍 比如 topN排名
-
內(nèi)存速度
- 有狀態(tài)的 Flink 程序針對(duì)本地狀態(tài)訪問進(jìn)行了優(yōu)化。任務(wù)的狀態(tài)始終保留在內(nèi)存中,如果狀態(tài)大小超過可用內(nèi)存,則會(huì)保存在能高效訪問的磁盤數(shù)據(jù)結(jié)構(gòu)中。任務(wù)通過訪問本地(通常在內(nèi)存中)狀態(tài)來進(jìn)行所有的計(jì)算,從而產(chǎn)生非常低的處理延遲。Flink 通過定期和異步地對(duì)本地狀態(tài)進(jìn)行持久化存儲(chǔ)來保證故障場(chǎng)景下精確一次的狀態(tài)一致性。
- 任務(wù)合并
-
任意規(guī)模
- Flink 旨在任意規(guī)模上運(yùn)行有狀態(tài)流式應(yīng)用。因此,應(yīng)用程序被并行化為可能數(shù)千個(gè)任務(wù),這些任務(wù)分布在集群中并發(fā)執(zhí)行。所以應(yīng)用程序能夠充分利用無盡的 CPU、內(nèi)存、磁盤和網(wǎng)絡(luò) IO。而且 Flink 很容易維護(hù)非常大的應(yīng)用程序狀態(tài)。其異步和增量的檢查點(diǎn)算法對(duì)處理延遲產(chǎn)生最小的影響,同時(shí)保證精確一次狀態(tài)的一致性。
支持精確一次
在這里我們帶著幾個(gè)問題去看flink
-
①狀態(tài)
- flink的狀態(tài)是如何管理的
- 狀態(tài)存在了哪
-
②故障
- 如何保證精確的狀態(tài)一致性(exactly-once) 即每條數(shù)據(jù)只被處理一次
-
③事件時(shí)間是如何支持的
- 如何支持亂序的
- 遲到太多了怎么處理
-
并行
- ④對(duì)于一個(gè)并行任務(wù)cpu和內(nèi)存是被如何分配的
-
反壓
- ⑤當(dāng)吞吐不夠的時(shí)候 是如何處理數(shù)據(jù)的
-
任務(wù)合并
- 什么是任務(wù)合并如何組織任務(wù)合并⑥
flink的架構(gòu)
- 首先flink是一個(gè)【并行化】【流處理】【分布式】系統(tǒng)
- 分配管理集群計(jì)算資源
- 進(jìn)程協(xié)調(diào)
- 故障恢復(fù)
- 持久且高可用的數(shù)據(jù)存儲(chǔ)(hdfs,s3,文件系統(tǒng),內(nèi)存)
-
分布式(zookeeper,k8s高可用)
圖3-2
-
flink的組件
- jobManager(job)
- 主進(jìn)程,JobManager控制單個(gè)應(yīng)用程序執(zhí)行 將任務(wù)分發(fā)給taskManager的處理槽執(zhí)行 負(fù)責(zé)所有需要集中協(xié)調(diào)的操作 如 檢查點(diǎn),狀態(tài),保存點(diǎn)的創(chuàng)建
- taskManager
- 通常需要多個(gè) 每個(gè)taskManager提供一定數(shù)量的處理槽 同應(yīng)用不同任務(wù)的taskManager需要進(jìn)行數(shù)據(jù)交換
- resourceManager
- 不同提供者有不同實(shí)現(xiàn)(k8s,yarn等)負(fù)責(zé)告知jobManager目前有多少處理槽,當(dāng)處理槽不夠自動(dòng)創(chuàng)建taskManager,任務(wù)空閑的時(shí)候自動(dòng)終止taskManager釋放計(jì)算資源
- dispatcher
- flink rest接口的提供方 提供一個(gè)WEB UI
- jobManager(job)
-
應(yīng)用部署
- 框架模式
- flink應(yīng)用會(huì)打成一個(gè)jar包 通過客戶端提交任務(wù)
- 如果任務(wù)提交到j(luò)obManager則任務(wù)直接執(zhí)行,如果提交到Y(jié)ARN ResourceManager和Dispatcher則會(huì)創(chuàng)建一個(gè)jobManager并執(zhí)行
- 庫模式
- 沒包含在官方文檔 不做具體講解 大概是將flink跟應(yīng)用綁在一個(gè)docker里面
- 框架模式
結(jié)合圖例和demo問題解答
- 問題解答
-
①狀態(tài),②故障,⑥任務(wù)合并 先跑demo BasicTransformations演示正常流程,演示服務(wù)異常后重啟服務(wù)①
-
狀態(tài)
- 理解為每個(gè)算子自己保存在flink中的一些變量
-
檢查點(diǎn)
檢查點(diǎn)是故障恢復(fù)的核心
-
檢查點(diǎn)生成過程
- 檢查點(diǎn)根據(jù)配置周期性生成
-
檢查點(diǎn)圖例
圖4-1-2
-
故障恢復(fù)
- 從圖4-1-2中不難看出要想保證至少一次 那么數(shù)據(jù)源需要支持任意游標(biāo)的重放,如果在此基礎(chǔ)上,數(shù)據(jù)匯寫入支持冪等或事務(wù)則可保證精確一次
-
保存點(diǎn)
- 生成邏輯同檢查點(diǎn)
- 手動(dòng)生成
- 可以運(yùn)行到不同集群上(系統(tǒng)遷移)
- 可以在不同并行度運(yùn)行(所擴(kuò)容)
- 可以啟動(dòng)一個(gè)不相同但是兼容的應(yīng)用(修改應(yīng)用bug)
- 何為兼容
- 生成保存點(diǎn)的時(shí)候 會(huì)將所有算子的狀態(tài)cp到保存點(diǎn)上
- 恢復(fù)的時(shí)候也根據(jù)算子id進(jìn)行恢復(fù) flink默認(rèn)會(huì)為每個(gè)算子生成一個(gè)id 但是當(dāng)應(yīng)用內(nèi)新增算子后 算子id將會(huì)發(fā)生變化 所以如果想要修改應(yīng)用結(jié)構(gòu) 而還可以通過保存點(diǎn)兼容恢復(fù) 我們最好是手動(dòng)生成算子id
- 何為兼容
-
任務(wù)合并
- demo BasicTransformations 演示任務(wù)合并③
-
-
③事件時(shí)間是如何支持的 ⑤并行時(shí)cpu和內(nèi)存的分配 先跑demo BasicTransformations 演示事件時(shí)間如何定義,當(dāng)事件時(shí)間不再更新后 水位線也不更新②
-
滾動(dòng)聚合根據(jù)code分組 并對(duì)code進(jìn)行sum
- 發(fā)現(xiàn)根據(jù)key自動(dòng)做了鍵值數(shù)據(jù)傳輸,同鍵的數(shù)據(jù)會(huì)放到一個(gè)算子中
-
事件時(shí)間是如何支持的
- flink如何定義事件時(shí)間
- 事件時(shí)間的亂序如何處理 引入水位線
- 水位線
- 根據(jù)當(dāng)前最大事件時(shí)間為根基 水位線=當(dāng)前最大事件時(shí)間-延遲時(shí)間
- 非延遲水位線
- 圖4-2-1
- 延遲水位線
- 圖4-2-2
- 水位線時(shí)間是根據(jù)事件最大時(shí)間為根 計(jì)算得出的 如果事件時(shí)間不更新則水位線不更新
- 遲到太多了怎么處理
- 丟棄(默認(rèn))
- 寫到旁路輸出 自定義進(jìn)行更新
- 重新計(jì)算
- 設(shè)置延遲容忍度 當(dāng)延遲容忍度未到時(shí) 窗口雖然執(zhí)行了但是還依然保留
- 非延遲水位線
- 根據(jù)當(dāng)前最大事件時(shí)間為根基 水位線=當(dāng)前最大事件時(shí)間-延遲時(shí)間
- 水位線
-
-






