1. 程式人生 > >(二):Flink概述,Flink如何支援批流處理,程式流程

(二):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(流) 是同一個公用引擎之上的兩個獨立的抽象。所以,這兩者的行為目前無法合併在一起操作
    ,目前官方正在處理這種問題,詳見[FLINK-2320];但是Spark就不同,DStream以及DataSet(DataFrame[T])都是封裝在RDD之上的,所以可以互動。
  • 計算操作都是懶載入。

下圖的紅色框,現在看來,可能不太嚴謹了。(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