一、什么是Flink?
Apache Flink是一個面向分布式數據流處理和批量數據處理的開源計算平台,提供支持流處理和批處理兩種類型應用的功能。
二、Flink特點
1、現有的開源計算方案,會把流處理和批處理作為兩種不同的應用類型:流處理一般需要支持低延遲、Exactly-Once保證,而批處理一般要支持高吞吐、高效處理
2、Flink是完全支持流處理,也就是說作為流處理看待時輸入數據流是無界的;而批處理被作為一種特殊的流處理,只是它的輸入數據流被定義為有界的。
技術特點:
1、流處理特性
支持高吞吐、低延遲、高性能的流處理
支持帶有事件時間的窗口操作
支持有狀態計算 的Exactly-Once語義
支持高度靈活的窗口操作,支持基於time、count、session,以及data-driver的窗口操作
支持具有Backpressure功能的持續六模型
支持基於輕量級分布式快照(Snapshot)實現的容錯
支持迭代計算
支持程序自動優化:避免特點情況下Shuffle、排序等操作,中間結果有必要進行緩存
Flink在JVM內部實現了自己的內存管理
2、API支持
對Streaming數據類應用,提供DataStream API
對批處理類應用,提供DataSet API
3、Libraries支持
支持機器學習(FlinkML)
支持圖分析(Gelly)
支持關系數據處理(Table)
支持復雜事件處理(CEP)
Flink系統的關鍵能力
1、低延時:提供ms級延時的處理能力
2、Exactly Once語義:提供異步快照機制,保證所有數據真正只處理一次
3、HA:JobManager支持主備模式,保證無單點故障
4、水平擴展能力:TaskManager支持手動水平擴展
三、Flink技術棧
1、從部署上講,Flink支持Local模式、集群模式(standalone模式或者Yarn模式)、雲端部署(GCE、EC2)
2、Runtime是主要的數據處理引擎,它以JobGraph形式的API接收程序。JobGraph是一個簡單的並行數據流,包含一些列的tasks,每個task包含了輸入和輸出(source和sink例外)。
3、DataStream API和DataSet API分別是流處理和批處理的應用程序接口,當程序編譯時,生成JobGraph。編譯完成后,根據API的不同,優化器(批或流)會生成不同的執行計划。根據不同的部署方式,優化后的JobGraph被提交給executors去執行。
四、Flink架構
Flink整個系統包含三個部分:
1、Client:
給用戶提供向Flink系統提交用戶任務(流式作業)的能力。用戶提交一個Flink程序時,會首先創建一個Client,該Client首先會對用戶提交的Flink程序進行預處理,並提交到Flink集群。
Client會將用戶提交的Flink程序組裝成一個JobGraph,並且是以JobGraph的形式提交的。
2、TaskManager:
業務執行節點,執行具體用戶任務。TaskManager可以有多個,各個TaskManager都平等。
實際負責執行計算的Worker,在其上執行Flink Job的一組Task。
負責管理其所在節點上的資源信息,如內存、磁盤、網絡等,在啟動的時候將資源狀態向JobManager匯報。
3、JobManager:
管理節點,管理所有的TaskManager,並決策用戶任務在哪些TaskManager上執行。
Master進程,Flink系統的協調者,它負責接收Flink Job及Job的管理和資源的協調,包括任務調度,檢查點管理,失敗恢復、調度組成Job的多個Task執行等。
對於集群為HA模式,可以同時多個master進程,其中一個作為leader,其他作為standby。當leader失敗時,會選出一個standby的master作為新的leader(通過zookeeper實現leader選舉)
分布式執行:
1、Flink程序提交給JobClient
2、JobClient再提交給JobManager
3、JobManager負責資源的協調和Job的執行
4、待資源分配完成,task就會分配到不同的TaskManager,TaskManager會初始化線程去執行task
5、根據程序的執行狀態向JobManager反饋,執行的狀態包括starting、in progress、finished以及canceled和failling等等
6、當Job執行完成,結果會返回給客戶端
五、其他常用概念
1、Source
Flink系統源數據輸入。
可以使用readTextFile(String path)來消費文件中的數據作為流數據的來源,默認情況下的格式是TextInputFormat。也可以通過readFile(FileInputFormat inputFormat,String path)來指定FileInputFormat的格式。
2、Transformation
Transformation允許將數據從一種形式轉換為另一種形式,輸入源可以是一個也可以是多個,輸出則可以是0個、1個或者多個。例如以下Transformations:
Map:輸入一個元素,輸出一個元素。
FlatMap:輸入一個元素,輸出0個、1個或多個元素。
Filter:條件過濾使用。
KeyBy:邏輯上按照Key分組,內部使用hash函數進行分組,返回KeyedDataStream。
Reduce:KeyedStream流上,將上一次reduce的結果和本次的進行操作。
Fold:在KeyedStream流上的記錄進行連接操作。
Aggregation:在keyedStream上應用類型min、max等聚合操作。
Window:消息流的分段即稱為窗口,最常見的就是時間窗口。
我們可以將流切分到有界的窗口中去處理,根據指定的key,切分為不同的窗口。我們可以使用Flink預定義的窗口分配器。當然你也可以通過繼承WindowAssginer自定義分配器。
下面看看有哪些預定義的分配器。
1. Global windows:Global window的范圍是無限的,你需要指定觸發器來觸發窗口。通常來講,每個數據按照指定的key分配到不同的窗口中,如果不指定觸發器,則窗口永遠不會觸發。
2. Tumbling Windows:基於特定時間創建,大小固定,窗口間不會發生重合。例如你想基於event timen每隔10分鍾計算一次,這個窗口就很適合。
3. Sliding Windows:大小也是固定的,但窗口之間會發生重合,例如你想基於event time每隔1分鍾,統一過去10分鍾的數據時,這個窗口就很適合。
4. Session Windows:允許我們設置一個gap時間,來決定在關閉一個session之前,我們要等待多長時間,是衡量用戶活躍與否的標志。
WindowAll:WindowAll操作不是基於keu的,是對全局數據進行的計算。由於不基於key,因此是非並行的,即並行度為1,在使用時性能會受到影響。
Union:Union功能就是在2個或多個DataStream上進行連接,成為一個新的DataStream。
Join:Join運行在2個DataStream上基於相同的key進行連接操作,計算的范圍也是要基於一個Window進行
Split:Split的功能是根據某些條件將一個流切分為2個或多個流
Select:DataStream根據選擇的字段,將流轉換為新的流
Project:project功能運行你選擇流中的一部分元素作為新的數據流中的字段,相當於做個映射。
3、Sink
數據結果輸出。將結果數據輸出到不同的地方,Flink提供了以下一些選擇:
1、writeAsText():將結果以字符串的形式一行一行寫到文本文件中
2、writeAsCsv():保存為csv格式
3、print() / printErr():標准輸出或錯誤輸出。輸出到Terminal或者out文件
4、writeUsingOutputFotmat():自定義輸出格式,需要考慮序列化與反序列化
5、writeUsingOutputFormat():也可以輸出到socket,但是你需要定義SerializationSchema。
4、DataStream
Flink中的DataStream程序是實現數據流轉換的常規程序(例如,過濾,更新狀態,定義窗口,聚合)。
最初從各種源(例如,消息隊列,套接字流,文件)創建數據流。結果通過接收器返回,接收器可以例如將數據寫入文件或標准輸出(例如命令行終端)
5、物理切片
Flink允許我們在流上執行物理分片,當然我們也可以選擇自定義partitionning
1、自定義partitioning:根據某個具體的key,將DataStream中的元素按照key重新進行分片,將相同的元素聚合到一個線程中執行。
2、隨機partitioning:不根據具體的key,而是隨機將數據打散。
3、Rebalancing partitioning:內部使用round robin方法將數據均勻打散。這對於數據傾斜時是很好的選擇。廣播用於將dataStream所有數據發到每一個partition.