(二):Flink概述,Flink如何支援批流處理,程式流程
前言
以下都儘量對比Spark(或者大資料生態的其他技術)進行理解。
Flink簡介,Flink能做什麼
Flink簡介
Flink最初是一個名為Stratosphere的研究專案,目標是為柏林地區的一些大學建立下一代大資料分析平臺。 它於2014年4月16日成為Apache孵化器專案。Stratosphere的初始版本基於Nephele的研究論文http://stratosphere.eu/assets/papers/Nephele_09.pdf
Flink最重要的功能,即Flink的流API,是Flink 0.7才引入的。 最開始只有Java API,後來的版本也開始支援Scala API。
下圖為Stratosphere的演變:
當下1.x版本的架構為:
Flink能做什麼
- 支援批處理
- 互動式處理
- 實時流資料處理
- 支援用SQL分析
- 支援機器學習
- 資料處理後的託管狀態(managed state)
- 以及僅一次交付(exactly-once)保證
(下圖的特性是不完整的)
所以,這樣看來,Flink的目標,和Spark是差不多的。
一些異同舉例:
- 雖然目標差不多,都想“一統江湖”,但是Flink的生態,還不太完善,還在慢慢的建立
- Flink實時處理是其優勢,基於此的機器學習,也是優勢,雖然也不夠完善
- 託管狀態(managed state) 是Flink的優勢。【儘量將每個Task的歷史狀態儲存在記憶體中。】
【在流處理中,有些操作僅僅在某一時間針對單一事件(如事件轉換map),有些操作需要記住多個事件的資訊並進行處理(window operators),受到其他資訊的處理結果的影響。後者的這些操作稱為有狀態的操作。】 - 準實時處理(微處理)以及較為完善的生態,依然是Spark的大優勢。
- Flink 與 Spark Streaming都保證 僅一次交付(exactly-once)。【Flink通過定期的非同步checkpointing本地狀態儲存到持久層來保證在出現故障時的exactly-once】
Flink guarantees exactly-once state consistency in case of failures by periodically and asynchronously checkpointing the local state to durable storage.
- 在 Flink 中,DataSet APi(批) 和 DataStream API(流) 是同一個公用引擎之上的兩個獨立的抽象。所以,這兩者的行為目前無法合併在一起操作
- 計算操作都是懶載入。
下圖的紅色框,現在看來,可能不太嚴謹了。(TODO:Flink純自動化記憶體管理?連基本的額配置都不需要?就因為其是自己控制記憶體,而spark基於JVM控制記憶體,就把它們分為configured和automatic?)
- 1.6開始,spark推出UnifiedMemoryManager開始朝自動化記憶體管理髮展
- Spark 記憶體管理以及記憶體消耗估算 可參考該官方說明
Filink也支援三大部署模式:Local、Cluster(Standalone,Yarn,messos)以及Cloud
選擇微批處理還是實時處理
- 第一個用例是金融:信用卡欺詐檢測與欺詐預防有些不同。檢測是在微批或實時流上發生的事情,而欺詐預防必須實時發生。想象一下,使用者正在進行交易,您希望系統檢視是欺詐性交易還是有效交易。
- 比如有兩個廣告科技行業的場景:一個是聚合來自不同IP地址的不同IP請求,將IP歸入黑名單或白名單;另一個是設法阻止一個黑名單IP的特定請求。前者使用微批處理就可以,而後者就需要實時流處理。再比如,在電信行業,統計特定使用者使用的頻寬,微批處理可能是一個更高效的方案,而網路異常檢測就需要實時流處理了。也有一些場景,微批處理和實時流處理都適用,如在IoT行業檢視特定工業裝置的使用情況。
- 視訊中還對IOT以及電信行業進行了例舉。對應部落格
計算流程(元件)
這裡只是簡單的類比下:
- 在Spark中,我們知道,是RDD/dstream + transform運算元 + action運算元
- 而在Flume中,是source、channel、sink
- Kafka中,是produce 、儲存(或者不儲存)、consume
- Hadoop中,map、落磁碟(也可以不落磁碟)、reduce
- Storm中,是圖狀結構(拓撲):spout、bolt
- Hive:HiveSQL ->AST(抽象語法樹:完成SQL詞法,語法解析,將SQL轉化為抽象 語法樹AST Tree;) -> QB(查詢塊) ->OperatorTree(操作樹)->優化後的操作樹->mapreduce任務樹->優化後的mapreduce任務樹
- 這裡的Flink,是source、transformation、sink
Flink如何支援批流處理
理解Flink如何流式實時處理資料,如果不是深入細節去理解,還是很好理解,泛泛而談,就是來一條處理一條,但是具體是怎樣的,還需要以後深入學習才知道。
比如說:
- 哪條訊息傳送往哪臺機器去計算,是怎樣決定的?
- 處理某條訊息如果牽扯到之前的訊息處理的狀態,那麼之前的訊息相關的,是怎樣傳輸到其他節點的?
- 等等
這裡先理解下Flink如何進行批處理:
- 首先,Flink 把批處理看成 Stream 的特殊例子(也就是批處理建立在流式基礎之上,Spark Streaming可以理解為是相反的),具體到架構圖可知道:
面向流處理對應DataStream API,面向批處理對應DataSet API。 - 官網講解的Dataset都是從檔案獲取資料,我想知道的是:Flink是如何將流式資料批量對待的(因為Flink將批作為流的特例,有文章說——Flink中有一個時間引數,控制快取多少的資料之後再進行處理。但我遲遲沒有找到證據)。
- 先放著,TODO
程式開發步驟
DataStream和DataSet API是程式設計師呼叫的介面。編譯程式時,這些API會生成JobGraphs。編譯後,DataSet API允許優化器生成最佳執行計劃,而DataStream API使用流構建的方式來實現高效的執行計劃。然後根據部署模型將優化的JobGraph提交給執行程式。
與Spark“套路”差不多:
- 獲取上下文執行環境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
【Spark中是
SparkContext / SparkSession / StreamingContext 或者
JavaSparkContext / JavaSparkStreaming
】
- 載入資料,比如:
env.readTextFile
等
【spark:
spark.read.jdbc
spark.read.json
spark.read.orc
spark.read.parquet
spark.read.textFile
】
- Transformations 運算元,比如:
data.flatMap(new FlatMapFunction<String, String>() {
public void flatMap(String value, Collector<String> out) {
for (String s : value.split(" ")) {
out.collect(s);
}
}
});
- sinks,比如:
textData.writeAsText
- 執行
env.execute();
spark:spark-submit
參考
[7.] 《Learning Apache Flink》packt