1. 程式人生 > 實用技巧 >大資料面試題之葵花寶典------Flink初級

大資料面試題之葵花寶典------Flink初級

葵花寶典------Flink初級

1、簡單介紹一下 Flink

Flink 是一個框架和分散式處理引擎,用於對無界和有界資料流進行有狀態計算。並且 Flink 提供了資料分佈、容錯機制以及資源管理等核心功能。Flink提供了諸多高抽象層的API以便使用者編寫分散式任務:


DataSet API, 對靜態資料進行批處理操作,將靜態資料抽象成分散式的資料集,使用者可以方便地使用Flink提供的各種操作符對分散式資料集進行處理,支援Java、Scala和Python。
DataStream API,對資料流進行流處理操作,將流式的資料抽象成分散式的資料流,使用者可以方便地對分散式資料流進行各種操作,支援Java和Scala。
Table API,對結構化資料進行查詢操作,將結構化資料抽象成關係表,並通過類SQL的DSL對關係表進行各種查詢操作,支援Java和Scala。
此外,Flink 還針對特定的應用領域提供了領域庫,例如: Flink ML,Flink 的機器學習庫,提供了機器學習Pipelines API並實現了多種機器學習演算法。 Gelly,Flink 的圖計算庫,提供了圖計算的相關API及多種圖計算演算法實現。

2、Flink相比傳統的Spark Streaming區別?

這個問題是一個非常巨集觀的問題,因為兩個框架的不同點非常之多。但是在面試時有非常重要的一點一定要回答出來:Flink 是標準的實時處理引擎,基於事件驅動。而 Spark Streaming 是微批(Micro-Batch)的模型。
下面我們就分幾個方面介紹兩個框架的主要區別:

  1. 架構模型Spark Streaming 在執行時的主要角色包括:Master、Worker、Driver、Executor,Flink 在執行時主要包含:Jobmanager、Taskmanager和Slot。
  2. 任務排程Spark Streaming 連續不斷的生成微小的資料批次,構建有向無環圖DAG,Spark Streaming 會依次建立 DStreamGraph、JobGenerator、JobScheduler。Flink 根據使用者提交的程式碼生成 StreamGraph,經過優化生成 JobGraph,然後提交給 JobManager進行處理,JobManager 會根據 JobGraph 生成 ExecutionGraph,ExecutionGraph 是 Flink 排程最核心的資料結構,JobManager 根據 ExecutionGraph 對 Job 進行排程。
  3. 時間機制Spark Streaming 支援的時間機制有限,只支援處理時間。 Flink 支援了流處理程式在時間上的三個定義:處理時間、事件時間、注入時間。同時也支援 watermark 機制來處理滯後資料。
  4. 容錯機制對於 Spark Streaming 任務,我們可以設定 checkpoint,然後假如發生故障並重啟,我們可以從上次 checkpoint 之處恢復,但是這個行為只能使得資料不丟失,可能會重複處理,不能做到恰好一次處理語義。Flink 則使用兩階段提交協議來解決這個問題。

3、Flink的元件棧有哪些?

根據 Flink 官網描述,Flink 是一個分層架構的系統,每一層所包含的元件都提供了特定的抽象,用來服務於上層元件。

自下而上,每一層分別代表:Deploy 層:該層主要涉及了Flink的部署模式,在上圖中我們可以看出,Flink 支援包括local、Standalone、Cluster、Cloud等多種部署模式。Runtime 層:Runtime層提供了支援 Flink 計算的核心實現,比如:支援分散式 Stream 處理、JobGraph到ExecutionGraph的對映、排程等等,為上層API層提供基礎服務。API層:API 層主要實現了面向流(Stream)處理和批(Batch)處理API,其中面向流處理對應DataStream API,面向批處理對應DataSet API,後續版本,Flink有計劃將DataStream和DataSet API進行統一。Libraries層:該層稱為Flink應用框架層,根據API層的劃分,在API層之上構建的滿足特定應用的實現計算框架,也分別對應於面向流處理和麵向批處理兩類。面向流處理支援:CEP(複雜事件處理)、基於SQL-like的操作(基於Table的關係操作);面向批處理支援:FlinkML(機器學習庫)、Gelly(圖處理)。

4、Flink 的執行必須依賴 Hadoop元件嗎?

Flink可以完全獨立於Hadoop,在不依賴Hadoop元件下執行。但是做為大資料的基礎設施,Hadoop體系是任何大資料框架都繞不過去的。Flink可以整合眾多Hadooop 元件,例如Yarn、Hbase、HDFS等等。例如,Flink可以和Yarn整合做資源排程,也可以讀寫HDFS,或者利用HDFS做檢查點。

5、你們的Flink叢集規模多大?

大家注意,這個問題看起來是問你實際應用中的Flink叢集規模,其實還隱藏著另一個問題:Flink可以支援多少節點的叢集規模?在回答這個問題時候,可以將自己生產環節中的叢集規模、節點、記憶體情況說明,同時說明部署模式(一般是Flink on Yarn),除此之外,使用者也可以同時在小叢集(少於5個節點)和擁有 TB 級別狀態的上千個節點上執行 Flink 任務。

6、Flink的基礎程式設計模型瞭解嗎?

上圖是來自Flink官網的執行流程圖。通過上圖我們可以得知,Flink 程式的基本構建是資料輸入來自一個 Source,Source 代表資料的輸入端,經過 Transformation 進行轉換,然後在一個或者多個Sink接收器中結束。資料流(stream)就是一組永遠不會停止的資料記錄流,而轉換(transformation)是將一個或多個流作為輸入,並生成一個或多個輸出流的操作。執行時,Flink程式對映到 streaming dataflows,由流(streams)和轉換操作(transformation operators)組成。

7、Flink叢集有哪些角色?各自有什麼作用?

Flink 程式在執行時主要有 TaskManager,JobManager,Client三種角色。其中JobManager扮演著叢集中的管理者Master的角色,它是整個叢集的協調者,負責接收Flink Job,協調檢查點,Failover 故障恢復等,同時管理Flink叢集中從節點TaskManager。TaskManager是實際負責執行計算的Worker,在其上執行Flink Job的一組Task,每個TaskManager負責管理其所在節點上的資源資訊,如記憶體、磁碟、網路,在啟動的時候將資源的狀態向JobManager彙報。Client是Flink程式提交的客戶端,當用戶提交一個Flink程式時,會首先建立一個Client,該Client首先會對使用者提交的Flink程式進行預處理,並提交到Flink叢集中處理,所以Client需要從使用者提交的Flink程式配置中獲取JobManager的地址,並建立到JobManager的連線,將Flink Job提交給JobManager。

8、說說 Flink 資源管理中 Task Slot 的概念

在Flink架構角色中我們提到,TaskManager是實際負責執行計算的Worker,TaskManager 是一個 JVM 程序,並會以獨立的執行緒來執行一個task或多個subtask。為了控制一個 TaskManager 能接受多少個 task,Flink 提出了 Task Slot 的概念。簡單的說,TaskManager會將自己節點上管理的資源分為不同的Slot:固定大小的資源子集。這樣就避免了不同Job的Task互相競爭記憶體資源,但是需要主要的是,Slot只會做記憶體的隔離。沒有做CPU的隔離。

9、說說 Flink 的常用運算元?

Flink 最常用的常用運算元包括:Map:DataStream → DataStream,輸入一個引數產生一個引數,map的功能是對輸入的引數進行轉換操作。Filter:過濾掉指定條件的資料。KeyBy:按照指定的key進行分組。Reduce:用來進行結果彙總合併。Window:視窗函式,根據某些特性將每個key的資料進行分組(例如:在5s內到達的資料)

10、說說你知道的Flink分割槽策略?

什麼要搞懂什麼是分割槽策略。分割槽策略是用來決定資料如何傳送至下游。目前 Flink 支援了8中分割槽策略的實現。

上圖是整個Flink實現的分割槽策略繼承圖:GlobalPartitioner 資料會被分發到下游運算元的第一個例項中進行處理。ShufflePartitioner 資料會被隨機分發到下游運算元的每一個例項中進行處理。RebalancePartitioner 資料會被迴圈傳送到下游的每一個例項中進行處理。RescalePartitioner 這種分割槽器會根據上下游運算元的並行度,迴圈的方式輸出到下游運算元的每個例項。這裡有點難以理解,假設上游並行度為2,編號為A和B。下游並行度為4,編號為1,2,3,4。那麼A則把資料迴圈傳送給1和2,B則把資料迴圈傳送給3和4。假設上游並行度為4,編號為A,B,C,D。下游並行度為2,編號為1,2。那麼A和B則把資料傳送給1,C和D則把資料傳送給2。BroadcastPartitioner 廣播分割槽會將上游資料輸出到下游運算元的每個例項中。適合於大資料集和小資料集做Jion的場景。ForwardPartitioner ForwardPartitioner 用於將記錄輸出到下游本地的運算元例項。它要求上下游運算元並行度一樣。簡單的說,ForwardPartitioner用來做資料的控制檯列印。KeyGroupStreamPartitioner Hash分割槽器。會將資料按 Key 的 Hash 值輸出到下游運算元例項中。CustomPartitionerWrapper 使用者自定義分割槽器。需要使用者自己實現Partitioner介面,來定義自己的分割槽邏輯。例如:

static classCustomPartitionerimplementsPartitioner<String> {
      @Override
      publicintpartition(String key, int numPartitions) {
          switch (key){
              case "1":
                  return 1;
              case "2":
                  return 2;
              case "3":
                  return 3;
              default:
                  return 4;
          }
      }
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

11、Flink的並行度瞭解嗎?Flink的並行度設定是怎樣的?

Flink中的任務被分為多個並行任務來執行,其中每個並行的例項處理一部分資料。這些並行例項的數量被稱為並行度。我們在實際生產環境中可以從四個不同層面設定並行度:
操作運算元層面(Operator Level)
執行環境層面(Execution Environment Level)
客戶端層面(Client Level)
系統層面(System Level)
需要注意的優先順序:運算元層面>環境層面>客戶端層面>系統層面。

12、Flink的Slot和parallelism有什麼區別?

官網上十分經典的圖:

slot是指taskmanager的併發執行能力,假設我們將 taskmanager.numberOfTaskSlots 配置為3 那麼每一個 taskmanager 中分配3個 TaskSlot, 3個 taskmanager 一共有9個TaskSlot。

parallelism是指taskmanager實際使用的併發能力。假設我們把 parallelism.default 設定為1,那麼9個 TaskSlot 只能用1個,有8個空閒。

13、Flink有沒有重啟策略?說說有哪幾種?

Flink 實現了多種重啟策略。
固定延遲重啟策略(Fixed Delay Restart Strategy)
故障率重啟策略(Failure Rate Restart Strategy)
沒有重啟策略(No Restart Strategy)
Fallback重啟策略(Fallback Restart Strategy)

14、用過Flink中的分散式快取嗎?如何使用?

Flink實現的分散式快取和Hadoop有異曲同工之妙。目的是在本地讀取檔案,並把他放在 taskmanager 節點中,防止task重複拉取。

val env = ExecutionEnvironment.getExecutionEnvironment

// register a file from HDFS
env.registerCachedFile("hdfs:///path/to/your/file", "hdfsFile")

// register a local executable file (script, executable, ...)
env.registerCachedFile("file:///path/to/exec/file", "localExecFile", true)

// define your program and execute
...
val input: DataSet[String] = ...
val result: DataSet[Integer] = input.map(new MyMapper())
...
env.execute()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

15、Flink的Slot和parallelism有什麼區別?

我們知道Flink是並行的,計算過程可能不在一個 Slot 中進行,那麼有一種情況即:當我們需要訪問同一份資料。那麼Flink中的廣播變數就是為了解決這種情況。我們可以把廣播變數理解為是一個公共的共享變數,我們可以把一個dataset 資料集廣播出去,然後不同的task在節點上都能夠獲取到,這個資料在每個節點上只會存在一份。

16、說說Flink中的視窗?

來一張官網經典的圖:

Flink 支援兩種劃分視窗的方式,按照time和count。如果根據時間劃分視窗,那麼它就是一個time-window 如果根據資料劃分視窗,那麼它就是一個count-window。flink支援視窗的兩個重要屬性(size和interval)如果size=interval,那麼就會形成tumbling-window(無重疊資料) 如果size>interval,那麼就會形成sliding-window(有重疊資料) 如果size< interval, 那麼這種視窗將會丟失資料。比如每5秒鐘,統計過去3秒的通過路口汽車的資料,將會漏掉2秒鐘的資料。通過組合可以得出四種基本視窗:
time-tumbling-window 無重疊資料的時間視窗,設定方式舉例:timeWindow(Time.seconds(5))
time-sliding-window 有重疊資料的時間視窗,設定方式舉例:timeWindow(Time.seconds(5), Time.seconds(3))
count-tumbling-window無重疊資料的數量視窗,設定方式舉例:countWindow(5)
count-sliding-window 有重疊資料的數量視窗,設定方式舉例:countWindow(5,3)

17、Flink的Slot和parallelism有什麼區別?

Flink在做計算的過程中經常需要儲存中間狀態,來避免資料丟失和狀態恢復。選擇的狀態儲存策略不同,會影響狀態持久化如何和 checkpoint 互動。Flink提供了三種狀態儲存方式:MemoryStateBackend、FsStateBackend、RocksDBStateBackend。

18、Flink中的時間有哪幾類

Flink 中的時間和其他流式計算系統的時間一樣分為三類:事件時間,攝入時間,處理時間三種。如果以 EventTime 為基準來定義時間視窗將形成EventTimeWindow,要求訊息本身就應該攜帶EventTime。如果以 IngesingtTime 為基準來定義時間視窗將形成 IngestingTimeWindow,以 source 的systemTime為準。如果以 ProcessingTime 基準來定義時間視窗將形成 ProcessingTimeWindow,以 operator 的systemTime 為準。

19、Flink 中水印是什麼概念,起到什麼作用?

Watermark 是 Apache Flink 為了處理 EventTime 視窗計算提出的一種機制, 本質上是一種時間戳。 一般來講Watermark經常和Window一起被用來處理亂序事件。

20、Flink Table & SQL 熟悉嗎?TableEnvironment這個類有什麼作用

TableEnvironment是Table API和SQL整合的核心概念。這個類主要用來:
在內部catalog中登錄檔
註冊外部catalog
執行SQL查詢
註冊使用者定義(標量,表或聚合)函式
將DataStream或DataSet轉換為表
持有對ExecutionEnvironment或StreamExecutionEnvironment的引用

21、Flink SQL的實現原理是什麼?是如何實現 SQL 解析的呢?

首先大家要知道 Flink 的SQL解析是基於Apache Calcite這個開源框架。

基於此,一次完整的SQL解析過程如下:
使用者使用對外提供Stream SQL的語法開發業務應用
用calcite對StreamSQL進行語法檢驗,語法檢驗通過後,轉換成calcite的邏輯樹節點;最終形成calcite的邏輯計劃
採用Flink自定義的優化規則和calcite火山模型、啟發式模型共同對邏輯樹進行優化,生成最優的Flink物理計劃
對物理計劃採用janino codegen生成程式碼,生成用低階API DataStream 描述的流應用,提交到Flink平臺執行