Categories
程式開發

快速起步Apache Flink,這遠比我們看到的更強大


2020 年初,Cloudera Hadoop 大神 Arun 在 Twitter 上宣布 Cloudera Data Platform 正式集成了 Flink 作為其流計算產品,意味著 Cloudera 的全球客戶都將能夠使用 Flink 進行流數據處理。那麼,被認為是 Storm 最佳替代的 Apache Flink,哪些出眾的能力受到了大數據獨角獸 Cloudera 的青睞? Cloudera 與 Apache Flink 的結合能給企業及開發者帶來哪些體驗提升?

什麼是 Apache Flink?

Flink 誕生於歐洲的一個大數據研究項目 StratoSphere。該項目是柏林工業大學的一個研究性項目。早期,Flink 是做Batch 計算的,但是在2014 年,StratoSphere 裡面的核心成員孵化出Flink,同年將Flink 捐贈Apache,並在後來成為Apache 的頂級大數據項目,同時Flink 計算的主流方向被定位為Streaming ,即用流式計算來做所有大數據的計算。

具體來說,Apache Flink 是一個解決實時數據處理的計算框架,但不是數據倉庫的服務,其可對有限數據流和無限數據流進行有狀態計算,並可部署在各種集群環境,對各種大小的數據規模進行快速計算。
快速起步Apache Flink,這遠比我們看到的更強大 1

如上圖所示 Flink 框架,大致可以分為三塊內容,從左到右依次為:數據輸入、Flink 數據處理、數據輸出。

Flink 支持消息隊列的Events(支持實時的事件)的輸入,上游源源不斷產生數據放入消息隊列,Flink 不斷消費、處理消息隊列中的數據,處理完成之後數據寫入下游系統,這個過程是不斷持續的進行。
快速起步Apache Flink,這遠比我們看到的更強大 2

在 API 層面,Flink 具備較好的層級組。但是不論是通過 SQL 的 API 還是 Table 的 API 還是 DataStream 的 API,其最終都會被轉換成 Stream Operator 然後放在 flink Runtime 的框架下去執行,即轉換成一個各種 Operator 串聯在一起的 Flink 應用程序。只是上層的 API 在嘗試做 Flink 程序時,會有各種不同的角度,從各方面寫出所想要達到效果的應用程序。

新一代分佈式流式數據處理框架

Flink 是一套集高吞吐、低延遲、有狀態三者於一身的分佈式流式數據處理框架。

眾所周知,非常成熟的計算框架Apache Spark 也只能兼顧高吞吐和高性能特性,在Spark Streaming 流式計算中無法做到低延遲保障;而Apache Storm 只能支持低延遲和高性能特性,但是無法滿足高吞吐的要求。而對於滿足高吞吐,低延遲,有狀態這三個目標對分佈式流式計算框架是非常重要的。

高吞吐

快速起步Apache Flink,這遠比我們看到的更強大 3

如上圖所示,相比於 Storm 或其他的框架,Flink 網絡模型還是相對來說比較高效的,每一個 Flink TaskManager 下會有很多個 Subtask。與其他方案設計不同的是,Subtask 會共享一個 TaskManager 的服務,通過一個 TCP Connection 與其它 TaskManager 通信,通信則是由 TaskManager 內設的 Netty 服務器完成。

需要注意的是,默認的情況下事件的數據並不是完成了一條就發送一條,而是從每一個Subtask 的Buffer Pool 中獲取一個緩衝塊,由RecordWriter 寫到緩衝塊中,等到這個緩衝塊寫滿了,再通知Netty 發送隊列到其他的TaskManager。這樣既可以很好保證了每一個 TCP 包被盡可能的利用,又減少了不必要網絡包的數量。

低延時

快速起步Apache Flink,這遠比我們看到的更強大 4

從技術本身的底層特性上說,Flink 引入了 Buffer Pool 和 Buffer 塊的概念。在大流量時,由於 Buffer 區很快就會被寫滿,緊接著會通知 Netty 盡可能地發送,因此不會看到太多的延遲。但在低流量時,可能幾秒鐘才會有一條數據,這就意味著Buffer pool 有很長時間沒有被強制寫滿,因此為了保證下游系統盡可能盡快得到上游的消息,就需要有一個強制的刷新或往下游推送的觸發器機制。

Flink 本身則具備這樣的一個機制,它可以盡可能地保證Buffer 還沒有寫滿時,就可提前去通知Netty 服務器,盡快把當前Buffer 塊裡面的數據發送下去,並可以通過BufferTimeout 的參數設置,控制Flink 在低流量時的系統最大延遲。

Buffertimeout 包含-1、0、x ms 的配法。比較特殊的是-1 和 0,當把參數設為-1 時,Flink 的用戶會忽略 Flusher 的通知,往下的發送必須要由 RecordWriter 完成,也就是默認了這個緩衝寫滿了往下發。這樣的情況下雖然每一次通信的效率是高效的,但是在低流量時若接受就會出現大量的不可預測的系統延遲。

當把參數設為 0 時,意味著 Flink 每寫一條數據就會通知 Netty 盡可能的發送,即係統達到了技術理論上的最低延遲。因此,當你對延遲特別敏感流量又不是很高時,可以考慮將 Buffertimeout 設為 0。

正常情況下會將 Buffertimeout 設為某個正值,也就是多少個毫秒。這時 Flink 每間隔一段時間通知 Netty,Netty 不管這個數據有沒有寫完或者有沒有寫滿,都盡可能發送。

這樣通過這兩個參數,也就是緩衝區大小及多長時間強制發送,就可以在延遲和吞吐之間形成一種維度的控制,並可以在低延遲或者是高吞吐這兩個方向上做一些控制,既能保證高吞吐,又能保證低延遲。

有狀態

快速起步Apache Flink,這遠比我們看到的更強大 5

由於 Flink 是一個實時計算的框架,因此 Flink 的狀態實際上是最核心的技術資產,涉及到了頻繁的寫入與讀取,並需要用很快的存儲方案存儲該狀態。 Flink 提供了三種狀態的存儲模式,分別是內存模式、文件模式和 Rocks DB 的模式。

  • 內存模式:使用這種方式,Flink 會將狀態維護在 Java 堆上。眾所周知,內存的訪問讀寫速度最快;其缺點也顯而易見,單台機器的內存空間有限,不適合存儲大數據量的狀態信息。一般在本地開發調試時或者狀態非常小的應用場景下使用內存這種方式。

  • 文件模式:當選擇使用文件系統作為後端時,正在計算的數據會被暫存在 TaskManager 的內存中。 Checkpoint 時,此後端會將狀態快照寫入配置的文件系統中,同時會在 JobManager 的內存中或者在 Zookeeper 中(高可用情況)存儲極少的元數據。文件系統後端適用於處理大狀態,長窗口,或大鍵值狀態的任務。

  • RocksDB:RocksDB 是一種嵌入式鍵值數據庫。使用 RocksDB 作為後端時,Flink 會將實時處理中的數據使用 RocksDB 存儲在本地磁盤上。 Checkpoint 時,整個 RocksDB 數據庫會被存儲到配置的文件系統中,同時 Flink 會將極少的元數據存儲在 JobManager 的內存中,或者在 Zookeeper 中(高可用情況)。 RocksDB 支持增量 Checkpoint,即只對修改的數據做備份,因此非常適合超大狀態的場景。

三大場景,實時處理不在話下

Flink 的應用場景一般看到三大類,分別是流式的 ETL,實時的數據分析以及事件驅動型應用的改造。

流式 ETL

傳統的 ETL 的任務一般是定時出發完成讀取數據,把結果寫到某一個數據庫或者文件系統中,通過週期性地調用 ETL 腳本完成批處理的作業。但是當有流式 ETL 的能力時,就不再需要定時出發的方式完成 ETL 的任務,而是在數據到達之後馬上開始 ETL 的處理。遇到意外的情況也可通過畫面機制從上一個出發點恢復再繼續執行任務。

實時的數據分析

Apache Flink 同時支持流式及批量分析應用。

Flink 為持續流式分析和批量分析都提供了良好的支持。具體而言,它內置了一個符合 ANSI 標準的 SQL 接口,將批、流查詢的語義統一起來。無論是在記錄事件的靜態數據集上還是實時事件流上,相同 SQL 查詢都會得到一致的結果。

但是有一點不可避免的是,由於實時分析系統面對的是非閉合的區間,或者是半開放的數據處理區間,因此如果要用實時的數據分析系統,就不可能保證產品結果100%能運行,開發者只能通過一些手段來降低這種情況出現的概率,而不能完全避免像這樣的情況。

事件驅動型應用

事件驅動型應用是一類具有狀態的應用,它從一個或多個事件流提取數據,並根據到來的事件觸發計算、狀態更新或其他外部動作。
快速起步Apache Flink,這遠比我們看到的更強大 6

如上圖所示,左邊傳統的事務處理應用,右邊是事件驅動的處理應用。

傳統的事務處理應用的點擊流Events 可以通過Application 寫入Transaction DB(數據庫),同時也可以通過Application 從Transaction DB 將數據讀出,並進行處理,當處理結果達到一個預警值就會觸發一個Action 動作。

而事件驅動的應用處理採集的數據Events 可以不斷的放入消息隊列,Flink 應用會不斷ingest(消費)消息隊列中的數據,Flink 應用內部維護著一段時間的數據(state),隔一段時間會將數據持久化存儲(Persistent sstorage),防止Flink 應用死掉。 Flink 應用每接受一條數據,就會處理一條數據,處理之後就會觸發(trigger)一個動作(Action),同時也可以將處理結果寫入外部消息隊列中,其他 Flink 應用再消費。並且可以通過 checkpoint 機制保證一致性,避免意外情況。

CSA基於Flink ,實現IoT 級數據流和復雜事件的實時狀態處理

將Flink 添加到Cloudera DataFlow(CDF) 的意義十分重大,Cloudera 提供了流處理引擎的幾種選擇:Storm,Spark Structured Streaming 和Kafka Stream,其中,Storm 在市場和開源社區中逐漸失寵,用戶正在尋找更好的選擇,而Apache Flink 天然支持流計算(而不是批處理)可以大規模處理大量數據流,具有原生支持的容錯/恢復能力,以及先進的Window 語義,這使其成為更廣泛的流處理引擎的默認選擇。

由 Apache Flink 支持的 Cloudera Streaming Analytics(簡稱“CSA”) 是 CDF平台內的一項新產品,可提供 IoT 級數據流和復雜事件的實時狀態處理。作為 CDF 的關鍵支柱之一,流處理和分析對於處理來自各種數據源的數百萬個數據點和復雜事件非常重要。多年來已經支持了多個流引擎,Flink 的加入,使 CDF 成為了一個可以大規模處理大量流數據的平台。

Cloudera Streaming Analytics 涵蓋了 Apache Flink 的核心流功能:

  • 在 YARN 上支持 Flink 1.9.1
  • 支持在 Cloudera 託管集群上安裝 Flink
  • 支持完全安全(啟用 TLS 和 Kerberos)的 Flink 集群
  • 從 Kafka 或 HDFS 讀取數據源
  • 使用 Java DataStream 和 ProcessFunction API 的 pipeline 定義
  • 恰好一次的語義
  • 基於事件時間的語義
  • 數據接收器寫入 Kafka,HDFS 和 HBase
  • 與 Cloudera Schema Registry 集成以進行模式管理以及流事件的序列化/反序列化

如何使用Cloudera CSA?

Cloudera CSA 的下載與使用 Cloudera Manager 安裝服務沒有太大的區別,在簽署訂閱協議後會獲得下載鏈接,可以直接刷到 Parcels 包。 Parcels 裝好之後就可以裝 Flink 了,裝好之後可以看到 History Server 和 Gateway 的服務。打開 History Server 的 Web UI 就顯示出 Flink 業務運行的監控面板,代表了 CSA 安裝完畢。

接下來就是採用一些標準的開發包,開始第一個 Flink 工程。首先獲取運行環境,加載或者讀取數據,再編寫 Transformations,添加數據輸出目標系統,最後執行這個應用。

不止於此,Apache Flink 與 CSA 正在探索更多的可能性

目前 Flink 已經成為一個主流的流計算引擎,社區下一步很重要的工作是對 Flink 做一個大的整合,面向流和批去做一個統一的數據處理模型。在1.9 的版本上用一個技術預覽版Flink 的SQL Planner 來替代老的SQL Planner,支持原生SQL 關鍵字,這對SQL 的標準性以及SQL 語法解析的正確性和高效性都是有一個更好的保障。

同時,作為開源技術的或者叫Apache 社區的參與者,Cloudera 也會對Apache Flink 這個技術做出更多貢獻,其中會關注在安全層面上的集成,然後還有Atlas 組件的集成,同時也會在接口層面會做一個新的HBASE Con​​nector。

此外,當前的CSA 雖然支持Kerberos 的語義環境,但是沒有類似於像點擊就完成的這種自動化的Kerberos 配置,以及包括通過一些可視化的這種框架或者是統一的安全管理框架,比如說Ranger,去管理任務的權限。因此,未來的 CSA 也會在面向企業管理的方向做一些新的更好的管理,包括 A/B 測試的一個 Flink 程序的管理,以及任務和任務 JAR 的管理等等。

同時,Cloudera 將投入更多力量到開源 Flink 的發展和社區的建設當中,希望和廣大業界同仁一起助力 Flink 社區的發展。

點擊此處註冊登錄後,即可獲取更多視頻課程