開發與維運

走進 Apache Flink

作者:李鈺

內容簡介

  1. 什麼是 Apache Flink
  2. 為什麼要學習 Apache Flink
  3. Apache Flink典型應用場景
  4. Apache Flink基本概念

一、什麼是 Apache Flink

image.png

Apache Flink是一個開源的基於流的有狀態計算框架。它是分佈式地執行的,具備低延遲、高吞吐的優秀性能,並且非常擅長處理有狀態的複雜計算邏輯場景。

(一)Flink 的起源

Apache Flink是Apache開源軟件基金會的一個頂級項目,和許多Apache頂級項目一樣,如Spark起源於 UC伯克利的實驗室, Flink也是起源於非常有名的大學的實驗室——柏林工業大學實驗室。

image.png

項目最初的名稱為Stratosphere,目標是要讓大數據的處理看起來更加地簡潔。項目初始的代碼貢獻者中,有很多今天仍活躍在Apache的項目管理委員會裡,在社區裡持續做出貢獻。

image.png

Stratosphere項目於2010年發起,從它的 Git commit日誌裡面可以看到,它的第一行代碼是在2010年的12月15日編寫的。

image.png

2014年5月,Stratosphere項目被貢獻到Apache軟件基金會,作為孵化器項目進行孵化,並更名為Flink。

(二)Flink的發展

image.png

Flink項目非常活躍,2014年的8月27號發佈了孵化器裡的第一個版本v0.6-incubating。

image.png

由於Flink項目吸引了非常多貢獻者參與,活躍度等方面也都非常優秀,它在2014年12月成為了Apache的頂級項目。
成為頂級項目之後,它在一個月之後發佈了第一個Release版本Flink 0.8.0。在此之後,Flink基本保持4個月1個版本的節奏,發展到今天。

(三)Flink 的現狀–Apache社區最活躍的項目

image.png

發展至今,Flink已成為Apache社區最活躍的大數據項目。它的用戶與開發者郵件列表在2020年的Apache年度報告中排名第一。

如上方右圖所示,與非常活躍的Spark項目相比,可以看到用戶郵件列表的活躍度,Flink比Spark更高一籌。此外,在開發者代碼提交次數與Github的用戶訪問量中, Flink在Apache所有項目中排名第二,在大數據項目中Flink都是排名第一。

image.png

從2019年4月至今,Flink社區發佈了5個版本,每一個版本都有更多的 Commit與貢獻者。

二、為什麼要學習 Apache Flink

(一)大數據處理的實時化趨勢

image.png

隨著網絡迅速發展,大數據的處理呈現非常明顯的實時化趨勢。

如上圖所示,我們列舉了一些現實生活中常見的場景。如春晚的直播有一個實時大屏,雙11購物節也有實時成交額的統計和媒體彙報。

城市大腦可以實時監測交通,銀行可以實時進行風控監測。當我們打開淘寶、天貓等應用軟件時,它都會根據用戶不同的習慣進行實時個性化推薦。從以上例子我們可以看到,大數據處理呈現明顯的實時化趨勢。

(二)Flink已成為國內外實時計算事實標準

image.png

在實時化的大趨勢底下,Flink已成為國內外實時計算事實標準。

如上圖所示,目前國內外許多公司都在使用Flink,國際公司有NETFLIX,Ebay,Linked in等,國內有阿里巴巴、騰訊、美團、小米、快手等大型互聯網公司。

(三)流計算引擎的演進

image.png

流計算引擎進行了很多代的演進,第一代流計算引擎Apache Storm是一個純流的設計,延遲非常的低,但是它的問題也比較明顯,即沒有辦法避免消息的重複處理,從而導致數據正確性有一定的問題。

Spark Streaming是第二代流計算引擎,解決了流計算語義正確性的問題,但是它的設計理念是以批為核心,最大的問題是延遲比較高,只能做到10秒級別的延遲,端到端無法實現秒以內的延遲。

Flink是第三代流計算引擎,也是最新一代的流計算引擎。它既可以保證低延遲,同時它又可以保證消息的一致性語義,對於內置狀態的管理,也極大降低了應用程序的複雜度。

三、Apache Flink 典型應用場景

(一)事件驅動型應用

image.png

第一類應用場景是事件驅動型應用。

事件驅動表示一個事件會觸發另一個或者是很多個後續的事件,然後這一系列事件會形成一些信息,基於這些信息需要做一定的處理。

在社交場景下,以微博為例,當我們點擊了一個關注之後,被關注人的粉絲數就會發生變化。之後如果被關注的人發了一條微博,關注他的粉絲也會收到消息通知,這是一個典型的事件驅動。

另外,在網購的場景底下,如用戶給商品做評價,這些評價一方面會影響店鋪的星級,另外一方面有惡意差評的檢測。此外,用戶通過點擊信息流,也可以看到商品派送或其他狀態,這些都可能觸發後續的一系列事件。

還有金融反欺詐的場景,詐騙者通過短信詐騙,然後在取款機竊取別人的錢財。在這種場景底下,我們通過攝像頭拍攝後,迅速反應識別出來,然後對犯罪的行為進行相應的處理。這也是一個典型的事件驅動型應用。

image.png

總結一下,事件驅動型應用是一類具有狀態的應用,會根據事件流中的事件觸發計算、更新狀態或進行外部系統操作。事件驅動型應用常見於實時計算業務中,比如:實時推薦,金融反欺詐,實時規則預警等。

(二)數據分析型應用

image.png

第二類典型應用場景是數據分析型應用,如雙11成交額實時彙總,包括PV、UV的統計。

包括上方圖中所示,是Apache開源軟件在全世界不同地區的一個下載量,其實也是一個信息的彙總。

還包括一些營銷大屏,銷量的升降,營銷策略的結果進行環比、同比的比較,這些背後都涉及到大量信息實時的分析和聚合,這些都是Flink非常典型的使用場景。

image.png

如上圖所示,以雙11為例,在2020年天貓雙11購物節,阿里基於Flink的實時計算平臺每秒處理的消息數達到了40億條,數據體量達到7TB,訂單創建數達到58萬/秒,計算規模也超過了150萬核。

可以看到,這些應用的場景體量很大且對於實時性要求非常高,這也是Apache Flink非常擅長的場景。

(三)數據管道型應用 (ETL)

Apache Flink擅長的第三類場景為數據管道型應用,即ETL。

ETL(Extract-Transform-Load)是從數據源抽取/轉換/加載/數據至目的端的過程。

image.png

傳統的ETL使用離線處理,經常做的是小時級別或者天級別的ETL。

但是,隨著大數據處理呈現實時化趨勢,我們也會有實時數倉的需求,要求在分鐘級或者秒級就能夠對數據進行更新,從而進行及時的查詢,能夠看到實時的指標,然後做更實時的判斷和分析。

image.png

image.png

在以上場景底下,Flink能夠最大限度地滿足實時化的需求。

背後的原因主要有以下幾個,一方面Flink有非常豐富的Connector,支持多種數據源和數據Sink,囊括了所有主流的存儲系統。另外它也有一些非常通用的內置聚合函數來完成ETL程序的編寫,因此ETL類型的應用也是它非常適合的應用場景。

四、Apache Flink 基本概念

(一)Flink的核心概念

Flink的核心概念主要有四個:Event Streams、State、(Event)Time和Snapshots。

1.Event Streams

即事件流,事件流可以是實時的也可以是歷史的。Flink是基於流的,但它不止能處理流,也能處理批,而流和批的輸入都是事件流,差別在於實時與批量。

2.State

Flink擅長處理有狀態的計算。通常的複雜業務邏輯都是有狀態的,它不僅要處理單一的事件,而且需要記錄一系列歷史的信息,然後進行計算或者判斷。

3.(Event)Time

最主要處理的問題是數據亂序的時候,一致性如何保證。

4.Snapshots

實現了數據的快照、故障的恢復,保證數據一致性和作業的升級遷移等。

(二)Flink作業描述和邏輯拓撲

接下來我們來具體的去看一下Flink的作業描述和邏輯拓撲。

image.png

如上方所示,代碼是一個簡單的Flink作業描述。它首先定義了一個KafkaSource,說明數據源是來自於Kafka消息隊列,然後解析Kafka裡每一條數據。解析完成後,下發的數據我們會按照事件的ID進行KeyBy,每個分組每10秒鐘進行一次窗口的聚合。聚合處理完之後,消息會寫到自定義的Sink。以上是一個簡單的作業描述,這個作業描述會映射到一個直觀的邏輯拓撲。

可以看到邏輯拓撲裡面有4個稱為算子或者是運算的單元,分別是Source、Map、KeyBy/Window/Apply、Sink,我們把邏輯拓撲稱為Streaming Dataflow。

(三)Flink物理拓撲

image.png

邏輯拓撲對應物理拓撲,它的每一個算子都可以併發進行處理,進行負載均衡與處理加速等。

大數據的處理基本上都是分佈式的,每一個算子都可以有不同的併發度。有 KeyBy關鍵字的時候,會按照key來對數據進行分組,所以在KeyBy前面的算子處理完之後,數據會進行一個Shuffle併發送到下一個算子裡面。上圖代表了示例對應的物理拓撲。

(四)Flink狀態管理和快照

接下來我們看一下Flink裡面的狀態管理和快照。

image.png

在進行Window的聚合邏輯時,每隔10秒會對數據進行聚合函數的處理。這10秒內的數據需要先存儲起來,待時間窗口觸發時進行處理。這些狀態數據會以嵌入式存儲的形式存儲在本地。這裡的嵌入式存儲既可以是進程的內存裡,也可以是類似RocksDB的持久化KV存儲,兩者最主要的差別是處理速度與容量。

此外,這些有狀態算子的每一個併發都會有一個本地的存儲,因此它的狀態數據本身可以跟隨算子的併發度進行動態的擴縮容,從而可以通過增加併發處理很大的數據量。

image.png

另一方面,作業在很多情況下有可能會失敗。失敗之後重新去運行時,我們如何保證數據的一致性?

Flink基於Chandy-Lamport算法,會把分佈式的每一個節點的狀態保存到分佈式文件系統裡面作為Checkpoint(檢查點),過程大致如下。首先,從數據源端開始注入Checkpoint Barrier,它是一種比較特殊的消息。

image.png

然後它會跟普通的事件一樣隨著數據流去流動,當Barrier到達算子之後,這個算子會把它當前的本地狀態進行快照保存,當Barrier流動到Sink,所有的狀態都保存完整了之後,它就形成一個全局的快照。

image.png

image.png

這樣當作業失敗之後,就可以通過遠程文件系統裡面保存的Checkpoint來進行回滾:先把Source回滾到Checkpoint記錄的offset,然後把有狀態節點當時的狀態回滾到對應的時間點,進行重新計算。這樣既可以不用從頭開始計算,又能保證數據語義的一致性。

(五)Flink中的時間定義

image.png

Flink裡另一個很重要的定義是Event Time。

在Flink裡有三種不同的時間,Event Time指事件發生的時間,Ingestion Time指事件到達Flink數據源的時間,或者說進入到Flink處理框架的時間,Processing Time指處理時間,即到達算子當前的時間,這三個之間有什麼區別呢?

在現實世界中,這個事件從發生到寫入到系統裡面,期間的間隔可能比較久。例如在地鐵裡面信號較弱時,如果我們在微博進行轉發、評論、點贊等操作,由於網絡的原因,這些操作可能要等我們出了地鐵後才能完成,因此可能有些先發生的事件會後到達系統。而Event Time能夠更真實地反映事件發生的時間點,因此在很多場景下,我們用Event Time作為事件發生的時間。

但是在這種情況底下,由於存在的延遲,所以在窗口需要花費較長的時間等待它的到來,端到端的延遲可能較大。
我們還需要處理亂序的問題,如果用 Processing Time當做事件時間的話,處理較快,延遲較低,但是無法反映真實事件發生的情況。因此在真實的開發應用時,需要根據應用的特點做相應的取捨。

(六)Flink API

image.png

Flink可分成4個層次的API,最底層的API是可以自定義的Process Function,對一些最基本的元素,如時間、狀態等,進行細節的處理,實現自己的邏輯。

再往上一層是DataStream API,它可以做流和批的處理,另外一方面它是邏輯的表達,有很多Flink內置的函數,方便用戶編寫程序。

最上層的API是Table API和Stream SQL,這是一個非常上層的表達形式,非常簡潔,我們接下來分別舉例說明。

1. Process Function

可以看到,在processElement裡邊,能夠對這個事件、狀態進行自定義邏輯的處理。另外,我們可以註冊一個timer,並且自定義當timer被觸發或時間到達的時候,到底要進行哪些處理,是一個非常精細的底層控制。

2. DataStream API

DataStream API是作業的描述,可以看到它有很多內置的函數,如Map、keyBy、timeWindow、sum等。這裡也有一些我們剛才自定義的ProcessFunction,如MyAggregationFunction。

3. Table API & Stream SQL

同樣的邏輯,如果用Table API和Stream SQL描述的話,它就更加地直觀。數據分析人員不需要了解底層的細節,可以用一種描述式的語言去寫邏輯。有關Table API和Stream SQL方面的內容,會在第5課進行詳細的介紹。

(七)Flink運行時架構

Flink運行時的架構主要有三個角色。

第一個是客戶端,客戶端會提交它的應用程序,如果它是一個SQL程序,還會進行SQL優化器的優化,然後生成對應的JobGraph。客戶端會把obGraph提交到JobManager,可以認為這是整個作業的主控節點。

JobManager會拉起一系列的TaskManager作為工作節點,工作節點之間會按照作業拓撲進行串聯,還有相應計算邏輯的處理,JobManager主要是進行一些控制流的處理。

(八)Flink物理部署

最後我們來看一下Flink能部署哪些環境。

首先,它可以通過手動的方式作業提交到YARN, Mesos以及Standalone集群上。另外,它也可以通過鏡像的方式提交到 K8s雲原生的環境中。

目前,Flink在許多物理環境中均能進行部署。

最新活動推薦

僅需99元即可體驗阿里雲基於 Apache Flink 構建的企業級產品-實時計算 Flink 版!點擊下方鏈接瞭解活動詳情:https://www.aliyun.com/product/bigdata/sc?utm_content=g_1000250506

社區二維碼.jpg

Leave a Reply

Your email address will not be published. Required fields are marked *