感謝胖子大佬提供的企業面試題。本文由於時間關係只有部分答案,後續的答案小編會持續補全,請持續關注本系列。年後升職加薪就靠它了。胖子大佬就在交流羣裏,須要加羣的公衆號回覆【加羣】。
更多面試題能夠參考:《Flink面試通關手冊》web
Flink 保證精確一次性消費主要依賴於兩種Flink機制面試
一、Checkpoint機制數據庫
二、二階段提交機制編程
Checkpoint機制後端
主要是當Flink開啓Checkpoint的時候,會往Source端插入一條barrir,而後這個barrir隨着數據流向一直流動,當流入到一個算子的時候,這個算子就開始製做checkpoint,製做的是從barrir來到以前的時候當前算子的狀態,將狀態寫入狀態後端當中。而後將barrir往下流動,當流動到keyby 或者shuffle算子的時候,例如當一個算子的數據,依賴於多個流的時候,這個時候會有barrir對齊,也就是當全部的barrir都來到這個算子的時候進行製做checkpoint,依次進行流動,當流動到sink算子的時候,而且sink算子也製做完成checkpoint會向jobmanager 報告 checkpoint n 製做完成。api
二階段提交機制緩存
Flink 提供了CheckpointedFunction與CheckpointListener這樣兩個接口,CheckpointedFunction中有snapshotState方法,每次checkpoint觸發執行方法,一般會將緩存數據放入狀態中,能夠理解爲一個hook,這個方法裏面能夠實現預提交,CheckpointListyener中有notifyCheckpointComplete方法,checkpoint完成以後的通知方法,這裏能夠作一些額外的操做。例如FLinkKafkaConumerBase使用這個來完成Kafka offset的提交,在這個方法裏面能夠實現提交操做。在2PC中提到若是對應流程例如某個checkpoint失敗的話,那麼checkpoint就會回滾,不會影響數據一致性,那麼若是在通知checkpoint成功的以後失敗了,那麼就會在initalizeSate方法中完成事務的提交,這樣能夠保證數據的一致性。最主要是根據checkpoint的狀態文件來判斷的。網絡
flink是一個相似spark的「開源技術棧」,由於它也提供了批處理,流式計算,圖計算,交互式查詢,機器學習等。flink也是內存計算,比較相似spark,可是不同的是,spark的計算模型基於RDD,將流式計算當作是特殊的批處理,他的DStream其實仍是RDD。而flink吧批處理當成是特殊的流式計算,可是批處理和流式計算的層的引擎是兩個,抽象了DataSet和DataStream。flink在性能上也表現的很好,流式計算延遲比spark少,能作到真正的流式計算,而spark只能是準流式計算。並且在批處理上,當迭代次數變多,flink的速度比spark還要快,因此若是flink早一點出來,或許比如今的Spark更火。session
Flink狀態主要有兩種使用方式:數據結構
Flink 中的watermark機制是用來處理亂序的,flink的時間必須是event time ,有一個簡單的例子就是,假如窗口是5秒,watermark是2秒,那麼 總共就是7秒,這個時候何時會觸發計算呢,假設數據初始時間是1000,那麼等到6999的時候會觸發5999窗口的計算,那麼下一個就是13999的時候觸發10999的窗口
其實這個就是watermark的機制,在多並行度中,例如在kafka中會全部的分區都達到纔會觸發窗口
Event Time 事件產生的時間
Ingestion time 事件進入Flink的時間
processing time 事件進入算子的時間
一、window join,即按照指定的字段和滾動滑動窗口和會話窗口進行 inner join
二、是coGoup 其實就是left join 和 right join,
三、interval join 也就是 在窗口中進行join 有一些問題,由於有些數據是真的會後到的,時間還很長,那麼這個時候就有了interval join可是必需要是事件時間,而且還要指定watermark和水位以及獲取事件時間戳。而且要設置 偏移區間,由於join 也不能一直等的。
Tumbing window
Silding window
Session window
Count winodw
keyedProcessFunction 是有一個ontime 操做的,假如是 event時間的時候 那麼 調用的時間就是查看,event的watermark 是否大於 trigger time 的時間,若是大於則進行計算,不大於就等着,若是是kafka的話,那麼默認是分區鍵最小的時間來進行觸發。
一、async io
二、broadcast
三、async io + cache
四、open方法中讀取,而後定時線程刷新,緩存更新是先刪除,以後再來一條以後再負責寫入緩存
DataSet Api 和 DataStream Api、Table Api
Flink數據傾斜如何查看:
在flink的web ui中能夠看到數據傾斜的狀況,就是每一個subtask處理的數據量差距很大,例若有的只有一M 有的100M 這就是嚴重的數據傾斜了。
KafkaSource端發生的數據傾斜
例如上游kafka發送的時候指定的key出現了數據熱點問題,那麼就在接入以後,作一個負載均衡(前提下游不是keyby)。
聚合類算子數據傾斜
預聚合加全局聚合
一、async io
二、broadcast
三、async io + cache
四、open方法中讀取,而後定時線程刷新,緩存更新是先刪除,以後再來一條以後再負責寫入緩存
一、是否網絡問題
二、是不是barrir問題
三、查看webui,是否有數據傾斜
四、有數據傾斜的話,那麼解決數據傾斜後,會有改善,
topn 不管是在離線仍是在實時計算中都是比較常見的功能,不一樣於離線計算中的topn,實時數據是持續不斷的,這樣就給topn的計算帶來很大的困難,由於要持續在內存中維持一個topn的數據結構,當有新數據來的時候,更新這個數據結構
sparkstreaming 的checkpoint會致使數據重複消費
可是flink的 checkpoint能夠 保證精確一次性,同時能夠進行增量,快速的checkpoint的,有三個狀態後端,memery、rocksdb、hdfs
Complex Event Processing(CEP):
FLink Cep 是在FLink中實現的複雜時間處理庫,CEP容許在無休止的時間流中檢測事件模式,讓咱們有機會掌握數據中重要的部分,一個或多個由簡單事件構成的時間流經過必定的規則匹配,而後輸出用戶想獲得的數據,也就是知足規則的復瑣事件。
Flink 沒有使用任何複雜的機制來解決反壓問題,Flink 在數據傳輸過程當中使用了分佈式阻塞隊列。咱們知道在一個阻塞隊列中,當隊列滿了之後發送者會被自然阻塞住,這種阻塞功能至關於給這個阻塞隊列提供了反壓的能力。
當你的任務出現反壓時,若是你的上游是相似 Kafka 的消息系統,很明顯的表現就是消費速度變慢,Kafka 消息出現堆積。
若是你的業務對數據延遲要求並不高,那麼反壓其實並無很大的影響。可是對於規模很大的集羣中的大做業,反壓會形成嚴重的「併發症」。首先任務狀態會變得很大,由於數據大規模堆積在系統中,這些暫時不被處理的數據一樣會被放到「狀態」中。另外,Flink 會由於數據堆積和處理速度變慢致使 checkpoint 超時,而 checkpoint 是 Flink 保證數據一致性的關鍵所在,最終會致使數據的不一致發生。
Flink Web UI
Flink 的後臺頁面是咱們發現反壓問題的第一選擇。Flink 的後臺頁面能夠直觀、清晰地看到當前做業的運行狀態。
Web UI,須要注意的是,只有用戶在訪問點擊某一個做業時,纔會觸發反壓狀態的計算。在默認的設置下,Flink的TaskManager會每隔50ms觸發一次反壓狀態監測,共監測100次,並將計算結果反饋給JobManager,最後由JobManager進行反壓比例的計算,而後進行展現。
在生產環境中Flink任務有反壓有三種OK、LOW、HIGH
OK正常
LOW通常
HIGH高負載
Flink的優化執行實際上是借鑑的數據庫的優化器來生成的執行計劃。
CBO,成本優化器,代價最小的執行計劃就是最好的執行計劃。傳統的數據庫,成本優化器作出最優化的執行計劃是依據統計信息來計算的。Flink 的成本優化器也同樣。Flink 在提供最終執行前,優化每一個查詢的執行邏輯和物理執行計劃。這些優化工做是交給底層來完成的。根據查詢成本執行進一步的優化,從而產生潛在的不一樣決策:如何排序鏈接,執行哪一種類型的鏈接,並行度等等。
// TODO
valueState 用於保存單個值
ListState 用於保存list元素
MapState 用於保存一組鍵值對
ReducingState 提供了和ListState相同的方法,返回一個ReducingFunction聚合後的值。
AggregatingState和 ReducingState相似,返回一個AggregatingState內部聚合後的值
Memery、RocksDB、HDFS
異常數據在咱們的場景中,通常分爲缺失字段和異常值數據。
異常值: 例如寶寶的年齡的數據,例如對於母嬰行業來說,一個寶寶的年齡是一個相當重要的數據,能夠說是最重要的,由於寶寶大於3歲幾乎就不會在母嬰上面購買物品。像咱們的有當日、未知、以及好久的時間。這樣都屬於異常字段,這些數據咱們會展現出來給店長和區域經理看,讓他們知道多少個年齡是不許的。若是要處理的話,能夠根據他購買的時間來進行實時矯正,例如孕婦服裝、奶粉的段位、紙尿褲的大小,以及奶嘴啊一些可以區分年齡段的來進行處理。咱們並無實時處理這些數據,咱們會有一個底層的策略任務夜維去跑,一個星期跑一次。
缺失字段: 例若有的字段真的缺失的很厲害,能修補就修補。不能修補就放棄,就像上家公司中的新聞推薦過濾器。
一、咱們監控了Flink的任務是否中止
二、咱們監控了Flink的Kafka的LAG
三、咱們會進行實時數據對帳,例如銷售額。
Flink有三種數據消費語義:
flink 新版本已經不提供 At-Most-Once 語義。
DataStream<T> keyed1 = ds1.keyBy(o -> o.getString("key")) DataStream<T> keyed2 = ds2.keyBy(o -> o.getString("key")) //右邊時間戳-5s<=左邊流時間戳<=右邊時間戳-1s keyed1.intervalJoin(keyed2).between(Time.milliseconds(-5), Time.milliseconds(5))
並行度根據kafka topic的並行度,一個並行度3個G
利用 broadcast State 將維度數據流廣播到下游全部 task 中。這個 broadcast 的流能夠與咱們的事件流進行 connect,而後在後續的 process 算子中進行關聯操做便可。
會有報警,監控的kafka偏移量也就是LAG。
window join 啊 cogroup 啊 map flatmap,async io 等
Flink 的watermark是一種延遲觸發的機制。
通常watermark是和window結合來進行處理亂序數據的,Watermark最根本就是一個時間機制,例如我設置最大亂序時間爲2s,窗口時間爲5秒,那麼就是當事件時間大於7s的時候會觸發窗口。固然假若有數據分區的狀況下,例如kafka中接入watermake的話,那麼watermake是會流動的,取的是全部分區中最小的watermake進行流動,由於只有最小的可以保證,以前的數據都已經來到了,能夠觸發計算了。
默認狀況下,若是設置了Checkpoint選項,Flink只保留最近成功生成的1個Checkpoint。當Flink程序失敗時,能夠從最近的這個Checkpoint來進行恢復。可是,若是咱們但願保留多個Checkpoint,並可以根據實際須要選擇其中一個進行恢復,這樣會更加靈活。Flink支持保留多個Checkpoint,須要在Flink的配置文件conf/flink-conf.yaml中,添加以下配置指定最多須要保存Checkpoint的個數。
關於小文件問題能夠參考代達羅斯之殤-大數據領域小文件問題解決攻略。
Spark 默認使用的是 Java序列化機制,同時還有優化的機制,也就是kryo
Flink是本身實現的序列化機制,也就是TypeInformation
Flink 的watermark是一種延遲觸發的機制。
通常watermark是和window結合來進行處理亂序數據的,Watermark最根本就是一個時間機制,例如我設置最大亂序時間爲2s,窗口時間爲5秒,那麼就是當事件時間大於7s的時候會觸發窗口。固然假若有數據分區的狀況下,例如kafka中接入watermake的話,那麼watermake是會流動的,取的是全部分區中最小的watermake進行流動,由於只有最小的可以保證,以前的數據都已經來到了,能夠觸發計算了。
Flink的狀態後端是Flink在作checkpoint的時候將狀態快照持久化,有三種狀態後端 Memery、HDFS、RocksDB
Flink 將來的目標是批處理和流處理一體化,由於批處理的數據集你能夠理解爲是一個有限的數據流。Flink 在批出理方面,尤爲是在今年 Flink 1.9 Release 以後,合入大量在 Hive 方面的功能,你可使用 Flink SQL 來讀取 Hive 中的元數據和數據集,而且使用 Flink SQL 對其進行邏輯加工,不過目前 Flink 在批處理方面的性能,仍是幹不過 Spark的。
目前看來,Flink 在批處理方面還有不少內容要作,固然,若是是實時計算引擎的引入,Flink 固然是首選。
可使用布隆過濾器。
還有kafka數據順序消費的處理。
咱們以前設置的水位線是6s
Flink任務提交後,Client向HDFS上傳Flink的jar包和配置,以後向Yarn ResourceManager提交任務,ResourceManager分配Container資源並通知對應的NodeManager啓動
ApplicationMaster,ApplicationMaster啓動後加載Flink的jar包和配置構建環境,而後啓動JobManager;以後Application Master向ResourceManager申請資源啓動TaskManager
,ResourceManager分配Container資源後,由ApplicationMaster通知資源所在的節點的NodeManager啓動TaskManager,NodeManager加載Flink的Jar包和配置構建環境並啓動TaskManager,TaskManager啓動向JobManager發送心跳,並等待JobManager向其分配任務。
通常join是發生在window上面的:
一、window join,即按照指定的字段和滾動滑動窗口和會話窗口進行 inner join
二、是coGoup 其實就是left join 和 right join,
三、interval join 也就是 在窗口中進行join 有一些問題,由於有些數據是真的會後到的,時間還很長,那麼這個時候就有了interval join可是必需要是事件時間,而且還要指定watermark和水位以及獲取事件時間戳。而且要設置 偏移區間,由於join 也不能一直等的。
內存管理及配置優化
Flink 目前的 TaskExecutor 內存模型存在着一些缺陷,致使優化資源利用率比較困難,例如:
爲了讓內存配置變的對於用戶更加清晰、直觀,Flink 1.10 對 TaskExecutor 的內存模型和配置邏輯進行了較大的改動 (FLIP-49 [7])。這些改動使得 Flink 可以更好地適配全部部署環境(例如 Kubernetes, Yarn, Mesos),讓用戶可以更加嚴格的控制其內存開銷。
Managed 內存擴展
Managed 內存的範圍有所擴展,還涵蓋了 RocksDB state backend 使用的內存。儘管批處理做業既可使用堆內內存也可使用堆外內存,使用 RocksDB state backend 的流處理做業卻只能利用堆外內存。所以爲了讓用戶執行流和批處理做業時無需更改集羣的配置,咱們規定從如今起 managed 內存只能在堆外。
簡化 RocksDB 配置
此前,配置像 RocksDB 這樣的堆外 state backend 須要進行大量的手動調試,例如減少 JVM 堆空間、設置 Flink 使用堆外內存等。如今,Flink 的開箱配置便可支持這一切,且只須要簡單地改變 managed 內存的大小便可調整 RocksDB state backend 的內存預算。
另外一個重要的優化是,Flink 如今能夠限制 RocksDB 的 native 內存佔用,以免超過總的內存預算—這對於 Kubernetes 等容器化部署環境尤其重要。
統一的做業提交邏輯
在此以前,提交做業是由執行環境負責的,且與不一樣的部署目標(例如 Yarn, Kubernetes, Mesos)緊密相關。這致使用戶須要針對不一樣環境保留多套配置,增長了管理的成本。
在 Flink 1.10 中,做業提交邏輯被抽象到了通用的 Executor 接口。新增長的 ExecutorCLI (引入了爲任意執行目標指定配置參數的統一方法。此外,隨着引入 JobClient負責獲取 JobExecutionResult,獲取做業執行結果的邏輯也得以與做業提交解耦。
原生 Kubernetes 集成(Beta)
對於想要在容器化環境中嘗試 Flink 的用戶來講,想要在 Kubernetes 上部署和管理一個 Flink standalone 集羣,首先須要對容器、算子及像 kubectl 這樣的環境工具備所瞭解。
在 Flink 1.10 中,咱們推出了初步的支持 session 模式的主動 Kubernetes 集成(FLINK-9953)。其中,「主動」指 Flink ResourceManager (K8sResMngr) 原生地與 Kubernetes 通訊,像 Flink 在 Yarn 和 Mesos 上同樣按需申請 pod。用戶能夠利用 namespace,在多租戶環境中以較少的資源開銷啓動 Flink。這須要用戶提早配置好 RBAC 角色和有足夠權限的服務帳號。
Table API/SQL: 生產可用的 Hive 集成
Flink 1.9 推出了預覽版的 Hive 集成。該版本容許用戶使用 SQL DDL 將 Flink 特有的元數據持久化到 Hive Metastore、調用 Hive 中定義的 UDF 以及讀、寫 Hive 中的表。Flink 1.10 進一步開發和完善了這一特性,帶來了全面兼容 Hive 主要版本的生產可用的 Hive 集成。
Batch SQL 原生分區支持
此前,Flink 只支持寫入未分區的 Hive 表。在 Flink 1.10 中,Flink SQL 擴展支持了 INSERT OVERWRITE 和 PARTITION 的語法(FLIP-63 ),容許用戶寫入 Hive 中的靜態和動態分區。
INSERT { INTO | OVERWRITE } TABLE tablename1 [PARTITION (partcol1=val1, partcol2=val2 ...)] select_statement1 FROM from_statement;
INSERT { INTO | OVERWRITE } TABLE tablename1 select_statement1 FROM from_statement;
對分區表的全面支持,使得用戶在讀取數據時可以受益於分區剪枝,減小了須要掃描的數據量,從而大幅提高了這些操做的性能。
另外,除了分區剪枝,Flink 1.10 的 Hive 集成還引入了許多數據讀取方面的優化,例如:
固定延遲重啓策略
固定延遲重啓策略是嘗試給定次數從新啓動做業。若是超過最大嘗試次數,則做業失敗。在兩次連續重啓嘗試之間,會有一個固定的延遲等待時間。
故障率重啓策略
故障率重啓策略在故障後從新做業,當設置的故障率(failure rate)超過每一個時間間隔的故障時,做業最終失敗。在兩次連續重啓嘗試之間,重啓策略延遲等待一段時間。
無重啓策略
做業直接失敗,不嘗試重啓。
後備重啓策略
使用羣集定義的從新啓動策略。這對於啓用檢查點的流式傳輸程序頗有幫助。默認狀況下,若是沒有定義其餘重啓策略,則選擇固定延遲重啓策略。
aggregate: 增量聚合
process: 全量聚合
當計算累加操做時候可使用aggregate操做。
當計算窗口內全量數據的時候使用process,例如排序等操做。
歡迎關注,《大數據成神之路》系列文章
歡迎關注,《大數據成神之路》系列文章
歡迎關注,《大數據成神之路》系列文章