一、簡介
Apache Flink是一個框架和分散式處理引擎,用於對無界和有界資料流進行有狀態計算。Flink被設計在所有常見的叢集環境中執行,以記憶體執行速度和任意規模來執行計算。
1,事件驅動型(Event-driven)
事件驅動型應用是一類具有狀態的應用,它從一個或多個事件流提取資料,並根據到來的事件觸發計算、狀態更新或其他外部動作。
2,分層api
3,有狀態計算
Flink在1.4版本中實現了狀態管理,所謂狀態管理就是在流失計算過程中將運算元的中間結果儲存在記憶體或者檔案系統中,等下一個事件進入運算元後可以讓當前事件的值與歷史值進行彙總累計。
4,exactly-once語義:
https://mp.weixin.qq.com/s/SteNgNSe_0-ex49vBpAGNw
5,支援事件時間:
二、Flink部署
1,standalone模式
a)安裝
解壓縮 flink-1.7.0-bin-hadoop27-scala_2.11.tgz
修改 flink/conf/flink-conf.yaml 檔案
# jobManager 的IP地址 jobmanager.rpc.address: localhost # jobManager 的埠號 jobmanager.rpc.port: 6123 # jobManager JVM heap 記憶體大小 jobmanager.heap.size: 1024m # taskManager JVM heap 記憶體大小 taskmanager.heap.size: 1024m # 每個taskManager提供任務的slots數量大小 taskmanager.numberOfTaskSlots: 1 #程式預設的平行計算的個數 parallelism.default: 1
修改 conf/slave檔案
linux02
linux03
分發給linux02和linux03
xrsync flink-1.7.0
啟動
./bin/start-clusster.sh
b)提交任務
//-c class的全路徑 jar包路徑 class類中輸入的引數 --input 輸入文字路徑 --output 輸出文字路徑 ./bin/flink run -c com.xcc.FlinkDataStreamWCDemo /flink-demo-1.0-SNAPSHOT-jar-with-dependencies.jar linux02 8888
2,yarn模式
a)啟動hadoop叢集
b)啟動yarn-session
./yarn-session.sh -n 2 -s 2 -jm 1024 -tm 1024 -nm test -d -n(--container):TaskManager的數量。 -s(--slots): 每個TaskManager的slot數量,預設一個slot一個core,預設每個taskmanager的slot的個數為1,有時可以多一些taskmanager,做冗餘。 -jm:JobManager的記憶體(單位MB)。 -tm:每個taskmanager的記憶體(單位MB)。 -nm:yarn 的appName(現在yarn的ui上的名字)。 -d:後臺執行。
c)執行任務
./bin/flink run -m yarn-cluster -c com.xcc.FlinkDataStreamWCDemo /flink-demo-1.0-SNAPSHOT-jar-with-dependencies.jar linux02 8888
三、Flink執行框架
1,任務提交流程(yarn模式)
Flink任務提交後,Client向HDFS上傳Flink的Jar包和配置,之後向Yarn ResourceManager提交任務,ResourceManager分配Container資源並通知對應的NodeManager啟動ApplicationMaster,ApplicationMaster啟動後載入Flink的Jar包和配置構建環境,然後啟動JobManager,之後ApplicationMaster向ResourceManager申請資源啟動TaskManager,ResourceManager分配Container資源後,由ApplicationMaster通知資源所在節點的NodeManager啟動TaskManager,NodeManager載入Flink的Jar包和配置構建環境並啟動TaskManager,TaskManager啟動後向JobManager傳送心跳包,並等待JobManager向其分配任務。
2,任務排程原理
Client 為提交 Job 的客戶端,可以是執行在任何機器上(與 JobManager 環境連通即可)。提交 Job 後,Client 可以結束程式(Streaming的任務),也可以不結束並等待結果返回。
JobManager 主要負責排程 Job 並協調 Task 做 checkpoint,職責上很像 Storm 的 Nimbus。從 Client 處接收到 Job 和 JAR 包等資源後,會生成優化後的執行計劃,並以 Task 的單元排程到各個 TaskManager 去執行。
TaskManager 在啟動的時候就設定好了槽位數(Slot),每個 slot 能啟動一個 Task,Task 為執行緒。從 JobManager 處接收需要部署的 Task,部署啟動後,與自己的上游建立 Netty 連線,接收資料並處理。
3,Worker與Slots
每個task slot表示TaskManager擁有資源的一個固定大小的子集。假如一個TaskManager有三個slot,那麼它會將其管理的記憶體分成三份給各個slot。資源slot化意味著一個subtask將不需要跟來自其他job的subtask競爭被管理的記憶體,取而代之的是它將擁有一定數量的記憶體儲備。需要注意的是,這裡不會涉及到CPU的隔離,slot目前僅僅用來隔離task的受管理的記憶體。
通過調整task slot的數量,允許使用者定義subtask之間如何互相隔離。如果一個TaskManager一個slot,那將意味著每個task group執行在獨立的JVM中(該JVM可能是通過一個特定的容器啟動的),而一個TaskManager多個slot意味著更多的subtask可以共享同一個JVM。而在同一個JVM程式中的task將共享TCP連線(基於多路複用)和心跳訊息。
Task Slot是靜態的概念,是指TaskManager具有的併發執行能力,可以通過引數taskmanager.numberOfTaskSlots進行配置,而並行度parallelism是動態概念,即TaskManager執行程式時實際使用的併發能力,可以通過引數parallelism.default進行配置。
也就是說,假設一共有3個TaskManager,每一個TaskManager中的分配3個TaskSlot,也就是每個TaskManager可以接收3個task,一共9個TaskSlot,如果我們設定parallelism.default=1,即執行程式預設的並行度為1,9個TaskSlot只用了1個,有8個空閒,因此,設定合適的並行度才能提高效率。
4,並行資料流
Stream在operator之間傳輸資料的形式可以是one-to-one(forwarding)的模式也可以是redistributing的模式,具體是哪一種形式,取決於operator的種類。
One-to-one:stream(比如在source和map operator之間)維護著分割槽以及元素的順序。那意味著map operator的subtask看到的元素的個數以及順序跟source operator的subtask生產的元素的個數、順序相同,map、fliter、flatMap等運算元都是one-to-one的對應關係。類似於spark中的窄依賴。
Redistributing:stream(map()跟keyBy/window之間或者keyBy/window跟sink之間)的分割槽會發生改變。每一個operator subtask依據所選擇的transformation傳送資料到不同的目標subtask。例如,keyBy() 基於hashCode重分割槽、broadcast和rebalance會隨機重新分割槽,這些運算元都會引起redistribute過程,而redistribute過程就類似於Spark中的shuffle過程。類似於spark中的寬依賴。