1. 程式人生 > 其它 >Flink入門-第一篇:Flink基礎概念以及競品對比

Flink入門-第一篇:Flink基礎概念以及競品對比

Flink入門-第一篇:Flink基礎概念以及競品對比

Flink介紹

截止2021年10月Flink最新的穩定版本已經發展到1.14.0

Flink起源於一個名為Stratosphere的研究專案主要是為了構建下一代大資料分析平臺,在2014年成為Apache孵化器專案。2019 年 1 月,阿里巴巴實時計算團隊宣佈將經過雙十一歷練和集團內部業務打 磨的 Blink 引擎進行開源並向 Apache Flink 貢獻程式碼,為Flink迎來了一次高速發展,此後的一年中,阿里巴巴實時計算團隊與 Apache Flink 社群密切合作,持續推進 Flink 對 Blink 的整合。 2 月 12 日Apache Flink 1.10.0 正式釋出,在 Flink 的第一個雙位數版本中正 式完成了 Blink 向 Flink 的合併。在此基礎之上,Flink 1.10 版本在生產可用性、 功能、效能上都有大幅提升。 Flink 1.10 是迄今為止規模最大的一次版本升級,除標誌著 Blink 的合併完成 外,還實現了 Flink 作業的整體效能及穩定性的顯著優化、還包括對原生 Kubernetes 的初步整合以及對 Python 支援(PyFlink)的重大優化等。

Apache Flink 是一個計算框架和分散式處理引擎,用於在無邊界資料流和有邊界的資料流上進行有狀態的計算。Flink 能在所有常見叢集環境中執行,並能以記憶體速度和任意規模進行計算。目前Flink 也是 Apache 軟體基金會和 GitHub 社群最為活躍的專案之一也是公認的新一代開源大資料計算引擎,可以支援流處理、 批處理和機器學習等多種計算形態。

任何型別的資料都可以形成一種事件流。信用卡交易、感測器測量、機器日誌、網站或移動應用程式上的使用者互動記錄,所有這些資料都形成一種資料流。在Flink上資料可以被作為 無界 或者 有界 流來處理。

  1. 無界資料流 有定義流的開始,但沒有定義流的結束。它們會無休止地產生資料。無界流的資料必須持續處理,即資料被攝取後需要立刻處理。我們不能等到所有資料都到達再處理,因為輸入是無限的,在任何時候輸入都不會完成。處理無界資料通常要求以特定順序攝取事件,例如事件發生的順序,以便能夠推斷結果的完整性。
  2. 有界資料流 有定義流的開始,也有定義流的結束。有界流可以在攝取所有資料後再進行計算。有界流所有資料可以被排序,所以並不需要有序攝取。有界流的處理通常被稱為批處理。

我們知道大資料起源於批處理,隨著發展大資料的計算模式隨後主要分為批量計算(batch computing)、流式計算(stream computing)、互動計算(interactive computing)、圖計算(graph computing)等。其中,流式計算和批量計算是兩種主要的大資料計算模式,分別適用於不同的大資料應用場景。在批處理上,Spark有很深的積累。為了應對全球大量業務的實時需求,Spark也推出了流計算解決方案——SparkStreaming。但Spark畢竟不是一款純流式計算引擎,所以在時效性等問題上,始終無法提供極致的流批一體體驗。另外一個流計算方案是Storm,Storm和Flink這兩者在概念上更相近。這也是目前主流的三種流式計算框架。

Apache Spark

Spark Streaming,即核心Spark API的擴充套件,不像Storm那樣一次處理一個數據流。相反,它在處理資料流之前,會按照時間間隔對資料流進行分段切分。Spark針對連續資料流的抽象,我們稱為DStream(Discretized Stream)。 DStream是小批處理的RDD(彈性分散式資料集), RDD則是分散式資料集,可以通過任意函式和滑動資料視窗(視窗計算)進行轉換,實現並行操作。

Apache Storm

在Storm中,需要先設計一個實時計算結構,我們稱之為拓撲(topology)。之後,這個拓撲結構會被提交給叢集,其中主節點(master node)負責給工作節點(worker node)分配程式碼,工作節點負責執行程式碼。在一個拓撲結構中,包含spout和bolt兩種角色。資料在spouts之間傳遞,這些spouts將資料流以tuple元組的形式傳送;而bolt則負責轉換資料流。

後起新秀 Flink 的基本資料模型則是資料流,以及事件(Event)的序列。資料流作為資料的基本模型,可以是無邊界的無限“流”,即一般意義上的流處理;也可以是有邊界的有限“流”,也就同時兼顧了批處理。Flink在實現流式處理和批量處理時,與傳統方案完全不同,他從另一個視角看待流式處理和批量處理,將二者統一起來,把批量處理視作一種特殊的流式處理,只是輸入資料流被定義為有界的。

Apache Flink是一個統一流處理與批處理的框架。由於流水線資料在並行任務之間進行傳輸(包括資料的洗牌shuffles),flink在執行時支援流處理與批處理。資料被立刻的傳輸從生產資料的任務到接受資料的任務(在網路傳輸中被收集在一個快取中,然後傳送)之後,批處理的任務可以被選擇來處理這些阻塞的資料。以下為這三種流計算框架的對比:

Flink 的批處理api用法案列和Spark 非常相似,但是內部實現不一樣。對於處理流來說,兩種框架採用了不同的實現使得他們適合於不同場景的應用(Spark 微批處理 vs Flink 流計算),我可以說Spark與Flink的比較是有用有效的。然而Spark卻和Flink 不是最相似的流處理引擎。
Apache Storm 只能處理流資料,沒有批處理的能力。事實上,Flink的流式處理引擎和Storm很相似,比如 Flink的並行任務和Storm的bolt很相似。他倆都是通過流水線資料的傳輸來降低資料延時。然而Flink 提供了很多跟高階的api ,Flink的DataStream提供了Map、GroupBy、Window和Join等api來代替storm的bolt在一個或多個readers 和collectors的功能,而Storm在實現這些功能的時候都需要程式設計師自己實現。另外的不同在於處理語義。Storm提供了"at-least-once "而Flink提供了"exactly-once",兩個框架給與語義不同的保證在實現上也就相當的不同。Storm 採用 record-level ack,Flink採用Chandy-Lamport的輕微變種。簡言之,在資料來源中週期性的注入marker,然後放入資料流中,無論何時只要任務執行器接受到一個marker,執行器檢查他的內部狀態。當一個marker被所有的資料輸出sink給接收到,證明這個marker被提交(在這個marker之前的所有執行的資料,到上一個被提交的marker之後的所以資料)。萬一有一個sink沒有接受到marker,所有的源操作器將從置他們的處理資料到最近一次確認提交的marker然後繼續執行。這種檢查標記點的方法比record-level ack更加的輕量級。

Storm也提供了 exactly-once 以及高階api ,但是被稱為Trident ,然而Trident 是在微批處理的基礎上實現的,就很像Spark了而不是Flink,Flink比Storm的改進還有以下幾點:

  1. 背壓:Flink流計算當不同操作器在速度不同的時候表現的很好。因為低速流操作器背壓高速流操作器很好,雖然網路層管理控制快取池。
  2. 使用者定義狀態:Flink允許使用者在操作器中自定義狀態。這個自定義狀態可以參與在檢查點的容錯處理,也提供exactly-once語義支援。在一個操作器中使用者自定義機器狀態,該狀態始終與資料流一起參與checkpoint。
  3. 流視窗:流視窗和視窗聚合是資料流分析的重要組成部分。Flink配備了一個非常強大的視窗系統,支援多種型別的視窗。

Flink特性

作為新一代大資料計算框架,其各種新特性讓開發者在處理實時計算技術選型上眼前一亮。

  1. 有狀態計算的exactly-once語義。狀態是指Flink能夠維護資料在時序上的聚類和聚合,同時它的檢查點(checkpoint)機制可以方便、快速地做出失敗重試;
  2. 支援帶有事件時間(event time)語義的流式處理和視窗 ( window)處理。事件時間的語義使流計算的結果更加精確,尤其是在事件無序或者延遲的情況下;
  3. 支援高度靈活的視窗可以方便、快速地做出失敗重試操作。包括基於time、count、session,以及 data-driven 的視窗操作,能很好地對現實環境中建立的資料進行建模;
  4. 輕量的容錯處理(fault tolerance)。它使得系統既能保持高吞吐率又能保證exactly-once的一致性,通過輕量的state snapshots實現;
  5. 支援高吞吐、低延遲、高效能的流式處理;
  6. 支援儲存點(savepoint)機制(一般為手動觸發)。即可以將應用的執行狀態儲存下來,在升級應用或者處理歷史資料時能夠做到無狀態丟失和停機時間最小;
  7. 支援大規模的叢集模式。支援YARN、Mesos,k8s可執行在成千上萬的節點上;
  8. 支援具有背壓( backpressure)功能的持續流模型;
  9. 支援迭代計算;
  10. JVM內部實現了自己的記憶體管理。它支援程式自動優化,例如能避免特定情況下的Shuffle、排序等昂貴操作,能對中間結果進行快取;
  11. 支援Java、Python、Scala;
  12. 支援複雜事件處理(CEP);
  13. 支援以SQL的方式開發流式應用;

Flink程式設計模型

Flink 為流式/批式處理應用程式的開發提供了不同級別的抽象。

  • Flink API 最底層的抽象為有狀態實時流處理。其抽象實現是 Process Function,並且 Process Function 被 Flink 框架整合到了 DataStream API 中來為我們使用。它允許使用者在應用程式中自由地處理來自單流或多流的事件(資料),並提供具有全域性一致性和容錯保障的狀態。此外,使用者可以在此層抽象中註冊事件時間(event time)和處理時間(processing time)回撥方法,從而允許程式可以實現複雜計算。

  • Flink API 第二層抽象是 Core APIs。實際上,許多應用程式不需要使用到上述最底層抽象的 API,而是可以使用 Core APIs 進行程式設計:其中包含 DataStream API(應用於有界/無界資料流場景)和 DataSet API(應用於有界資料集場景)兩部分。Core APIs 提供的流式 API(Fluent API)為資料處理提供了通用的模組元件,例如各種形式的使用者自定義轉換(transformations)、聯接(joins)、聚合(aggregations)、視窗(windows)和狀態(state)操作等。此層 API 中處理的資料型別在每種程式語言中都有其對應的類。

  • Process Function 這類底層抽象和 DataStream API 的相互整合使得使用者可以選擇使用更底層的抽象 API 來實現自己的需求。DataSet API 還額外提供了一些原語,比如迴圈/迭代(loop/iteration)操作。

  • Flink API 第三層抽象是 Table API。Table API 是以表(Table)為中心的宣告式程式設計(DSL)API,例如在流式資料場景下,它可以表示一張正在動態改變的表。Table API 遵循(擴充套件)關係模型:即表擁有 schema(類似於關係型資料庫中的 schema),並且 Table API 也提供了類似於關係模型中的操作,比如 select、project、join、group-by 和 aggregate 等。Table API 程式是以宣告的方式定義應執行的邏輯操作,而不是確切地指定程式應該執行的程式碼。儘管 Table API 使用起來很簡潔並且可以由各種型別的使用者自定義函式擴充套件功能,但還是比 Core API 的表達能力差。此外,Table API 程式在執行之前還會使用優化器中的優化規則對使用者編寫的表示式進行優化。

  • 表和 DataStream/DataSet 可以進行無縫切換,Flink 允許使用者在編寫應用程式時將 Table API 與 DataStream/DataSet API 混合使用。

  • Flink API 最頂層抽象是 SQL。這層抽象在語義和程式表示式上都類似於 Table API,但是其程式實現都是 SQL 查詢表示式。SQL 抽象與 Table API 抽象之間的關聯是非常緊密的,並且 SQL 查詢語句可以在 Table API 中定義的表上執行。

參考:

https://stackoverflow.com/questions/30699119/what-is-are-the-main-differences-between-flink-and-storm
https://www.javacodegeeks.com/2015/02/streaming-big-data-storm-spark-samza.html

福祿·研發中心 福小嗨