Flink VS Spark

        前幾周我出於好奇花了一些時間研究了下flink。當我一看到標準示例就馬上發現他和Spark其中一個例子很像。因而我認爲這只是模仿實現了spark功能的另外一個框架。可是隨着我研究的深刻,愈來愈清晰地發覺,有些藏匿在這個看起來很類似的API後的一些新穎的想法使得flink區別於spark。我被這些想法吸引了,而且花愈來愈多的時間搞懂和探索。java

        許多flink的想法像自定義內存管理,dataset API都已經在Spark中實現了,而且被證實是很不錯的。因此搞明白flink能夠幫助咱們搞清楚將來分佈式數據處理方面的趨勢信息。算法

        在這篇博客中我嘗試做爲一名spark開發者來闡述我對於Apche flink的第一印象。這個審視是我做爲一名從事Spark開發2年而僅花了2-3周的時間玩了玩Apache flink的人的一些我的看法。因此帶着批判的思惟看待我如今作的事吧~sql

        什麼是Apache Flink?數據庫

        Apache Flink是新一代的大數據處理引擎,他致力於統一不一樣數據載入。他聽起來像是Apache Spark嗎?確實是。Flink嘗試去定位Spark嘗試去解決的課題。這兩個系統都是向着創建單一平臺,在這個平臺上能夠運行諸如批處理,流式,交互計算,圖計算,機器學習等。因此flink和Spark的思想體系是很接近的。可是他們在實現的細節方面有着很大的區別。                api

        Apache Spark VS Apache Flink緩存

        1  抽象概念app

        在Spark裏,咱們使用RDD抽象模型來運行批處理,使用DStream來建立流計算任務,這些都是RDD自己帶有的。因此咱們在Spark中展現的全部的數據都使用了RDD。框架

        在flink中,咱們使用Dataset抽象模型來運行批處理,使用DataStreams建立流應用。他們聽起來比較像RDD和DStreams但其實不一樣。不一樣點表如今:機器學習

  • Dataset做爲運行時的計劃體現

        在spark中RDD在運行時階段被看成java對象。經過Tungsten的介紹,他的變化是微乎其微的。而Apache flink的Dataset是做爲邏輯計劃執行的。聽着熟悉嗎?是的,他們就像是Spark中的dataframes。因此在flink中你能夠將Dataframe像API同樣使用,做爲使用優化器優化過的一等類公民。可是在Spark RDD中沒有任何這樣的優化存在。分佈式

        flink裏的Dataset就像是在執行前優化了的Spark Dataframe API。

        在spark 1.6中,dataset API才加入spark,這也將會最終取代RDD。

  • Dataset和DataStream是獨立的API

        在Spark中像DStream和Dataframe都是創建在RDD抽象基礎之上的。可是在flink中,Dataset和DataStream是創建在

        咱們不能將DataSet和DataStreams結合起來,像RDD和DStreams同樣。

        故即便flink和spark擁有差很少的抽象組件,他們的實現仍是有很大差別的。

        2  內存管理

        直到spark1.5,Spark纔開始使用Java堆來緩存數據。儘管對於一個項目來講很容易開始,但結果不是報OOM錯誤就是gc中止了。因此自從1.5以來,spark步入自定義內存管理階段,這個項目叫作tangsten。

        Flink總有一天也會自定義內存管理。實際上他仍是Spark往這個方向邁進的一個靈感。不只flink將他的數據存儲在自定義的二進制格式中,他直接操做二進制數據。在spark中,自從1.5開始,全部的dataframe操做都是直接在tungsten二進制數據中執行的。

        在JVM上的自定義內存管理有更好的表現和更好的資源利用率。

        3  實現語言

        Spark是用Scala實現的。他也提供其餘語言的APIs,這些語言有Java,Python和R。而Flink是用Java實現的。他有提供Scala的API。

        因此語言方面的選擇Spark要優於flink。雖然在一些flink的scala API裏,是用java實現的抽象。我認爲當有更多用戶的時候這一點將會獲得改善。我對於Spark和Flink中的java API沒有太多想法,由於我早已經轉向了Scala。

        4  API

        Spark和Flink有着類似的scala集合API。因此從表面上看兩個API都差很少。下面是用RDD和Dataset API編寫的word count程序。

// Spark wordcount
object WordCount {

  def main(args: Array[String]) {

    val env = new SparkContext("local","wordCount")

    val data = List("hi","how are you","hi")

    val dataSet = env.parallelize(data)

    val words = dataSet.flatMap(value => value.split("\\s+"))

    val mappedWords = words.map(value => (value,1))

    val sum = mappedWords.reduceByKey(_+_)

    println(sum.collect())

  }

}
​// Flink wordcount
object WordCount {

  def main(args: Array[String]) {

    val env = ExecutionEnvironment.getExecutionEnvironment

    val data = List("hi","how are you","hi")

    val dataSet = env.fromCollection(data)

    val words = dataSet.flatMap(value => value.split("\\s+"))

    val mappedWords = words.map(value => (value,1))

    val grouped = mappedWords.groupBy(0)

    val sum = grouped.sum(1)

    println(sum.collect())
  }

}

我不是很肯定,這究竟是巧合仍是故意的,有着這麼類似的API有助於在兩個框架中輕易地切換。好像在不久的未來集合API將會成爲建立數據通道的標準API。甚至是Scala的發明人,Martin Odersky都認同了這個事實。

        5  流

        Apache Spark將流視爲快速的批處理工具。而Apache flink將批處理視爲流處理的特殊情形。 這兩種都有着優雅的實現方式。不過兩種接近的實現的不一樣點在於

  • 實時VS準實時

        Apache flink提供基於事件的處理,也叫作實時流處理。這很像Storm模型。

        而在Spark中咱們提供的最小批量處理不支持切分到事件級別粒度。這種成爲準實時。

        Spark Streaming是更快的批處理,Flink批處理綁定在流處理中。

        儘管準實時系統沒什麼毛病,仍是有些系統須要基於事件的實時處理的。這些系統更適合用storm而不是Spark Streaming。這二者之間flink有很是有趣的選擇。

  • 結合歷史數據和流的能力

        將流處理看成更快的批處理的一點好處在於,咱們能夠在兩種情形之間作相同的抽象。Spark在結合批和流數據上有着極佳的支持由於RDD抽象模型。

        在flink中,批和流不共享一樣的api抽象層。因此即便有途徑結合基於數據流的歷史文件,但他沒有Spark來的那麼簡潔。

        在許多應用中這種能力仍是很重要的。在這些應用中Spark代替了Flink流的地位。

  • 多樣的窗口函數

        因爲最小批的特性,Spark中對窗口函數的支持比較侷限,直到如今。你只能在基於處理時間中將批進行窗口化。

        相比於其餘系統Flink提供了豐富的窗口系統。窗口函數也是flink流API的重中之重。他提供基於處理時間,數據時間,空記錄等的窗口函數。這個多樣性使得flink流API相比於spark要強大的多。

        我不肯定將這樣的API帶給Spark會不會很容易,不過直到如今flink有着相比Spark streaming更加有優點的窗口API。

        SQL interface

        目前來看Spark庫中最熱門的當屬spark-sql了。Spark不只提供了像查詢語言同樣的Hive,還有用來查詢結構數據的DSL同樣的Dataframe。這是成熟的API而且在批處理和流世界中普遍地應用。

        如今Flink的Table API只支持像DSL的dataframe,它仍然在beta階段。據稱有計劃將sql接口加進去,可是不肯定何時可以落地到框架中。

        因此如今Spark相比於flink有着不錯的sql支持。我認爲flink會後來居上的。

        Data source Integration

        Spark數據源API是這個框架中最好的API了。數據源API使得像NoSQL數據庫,parquet,ORC這些不錯的數據源做爲spark中的第一等公民。固然這個API提供了像在源碼級別中預測的操做的能力。

        Flink仍是很依賴於map/reduce inputFormat去作數據源的集成。儘管他是足夠好的推送數據的API,可是它不能充分利用好源的能力。因此flink在數據源集成方面落後了一些。

        Iterative processing

        Spark的一個最常常被談論到的特徵就是高效處理機器學習的能力。因爲能夠進行內存計算,和其餘的一些實現細節,以致於它確實是實現ML算法的強大平臺。

        儘管ML算法在spark中是表現爲直接非週期圖的循環數據流。正常的沒有分佈式處理系統鼓勵去作複雜的循環數據流運算。

        不過flink和其餘框架比起來也沒有多大差異。他支持在運行時控制循環依賴的圖計算。相比於DAG他用了很是搞笑的方式去表現ML算法。因此Flink支持在本地平臺的迭代。結果是相比於DAG的方法他更具有可擴展性和高性能。

        我但願spark也能開始在框架中支持這個,這將會大大促進ML協會的發展。

        Stream as platform vs Batch as Platform

 

        結論

        最後總結下,Spark是更加成熟和完善的框架相比於Flink來講。可是flink帶來了譬如自定義的內存管理,像表同樣的data set API這些奇妙的想法。Spark協會認識到這點,而且把他應用到spark中。這麼看來flink是推進了大數據處理向下一個層次的發展。因此瞭解flink API和內在的機制能夠幫助你瞭解在技術落地到Spark以前的這個新的流計算範例。

相關文章
相關標籤/搜索