帶你玩轉Flink流批一體分佈式實時處理引擎

摘要:Apache Flink是爲分佈式、高性能的流處理應用程序打造的開源流處理框架。

本文分享自華爲雲社區《【雲駐共創】手把手教你玩轉Flink流批一體分佈式實時處理引擎》,作者: 萌兔之約。

Apache Flink是爲分佈式、高性能的流處理應用程序打造的開源流處理框架。Flink不僅能提供同時支持高吞吐和exactly-once語義的實時計算,還能提供批量數據處理。相較於市面上的其他數據處理引擎,它採用的是基於流計算來模擬批處理。

一、Flink原理及架構

Flink簡介

Apache Flink是爲分佈式、高性能的流處理應用程序打造的開源流處理框架。Flink不僅能提供同時支持高吞吐和exactly-once語義的實時計算,還能提供批量數據處理。主要由Java代碼實現,支持實時流處理和批處理,批數據只是流數據的一個極限案例。支持了迭代計算,內存管理和程序優化。

相較於市面上的其他數據處理引擎,Flink和Spark都可以同時支持流處理和批處理。但是,Spark的技術理念是基於批處理來模擬流的計算;而Flink則完全相反,它採用的是基於流計算來模擬批處理。

Flink關鍵機制

四個機制:狀態、時間、檢查點、窗口

Flink中有四種最重要的關鍵機制,這些關鍵機制在後面我們也會來進行詳細的介紹,這裏我們主要介紹它的基本概念以及主要用途。首先Flink中最重要的一個機制是狀態機制(State),Flink是一種有狀態的流計算引擎。狀態的作用主要是我們Flink是一種流計算,它需要存儲節點的中間計算結果。另外狀態的保存還有利於Flink進行容錯恢復。狀態有密切關係的是Flink的Checkpoint,也就是檢查點的機制,Checkpoint能夠去把Flink的狀態進行存儲,相當於是做一次快照,方便Flink進行容錯恢復。另外因爲Flink它是一種流計算引擎,它的數據是不間斷產生的,是沒有界限的,因此我們需要有一種機制能夠對數據進行切分,我們會採用的時間(Time)作爲切分點,另外Flink進行容錯性的恢復,它也需要知道從哪個時間點來進行恢復。所以說時間也是Flink中一種很重要的機制。最後是窗口window,在Flink中需要使用的窗口對數據進行切分,也方便對數據進行聚合計算。

Flink核心理念

Flink與其他流計算引擎的最大區別,就是狀態管理。

Flink提供了內置的狀態管理,可以把工作時狀態存儲在Flink內部,而不需要把它存儲在外部系統。這樣做的好處:

  • 降低了計算引擎對外部系統的依賴,使得部署、運維更加簡單;
  • 對性能帶來了極大的提升。

Flink Runtime整體架構

Flink運行時架構從下至上可以分爲了三層,在最下層是Flink的一些配置方式,Flink可以採用單機的方式安裝,也可以採用的集羣的方式安裝,另外也可以採用雲的方式部署。在大多數情況下,Flink都是採用的集羣的方式進行配置和安裝的。其中呢它支持了兩種集羣模式,一種是Standalon,這種方式是採用了Flink自身提供的資源調度管理器。另外一種方式是基於YARN的方式進行了配置安裝。

YARN提供了專用的資源管理器。在中間層次是Flink的計算引擎,這個計算引擎它同時能夠支持流處理和批處理,可以接收了上層的api提交給它做作業 。Runtime這個引擎上面可以分爲了兩個模塊,一個模塊是DataStream api,一個是DataSet api。Flink向dataset和datastream,也就是批數據集以及流數據集是分開處理的,但是都是公用下面的計算引擎。基於兩種類型的api,Flink又提供了更多的上層的抽象的api,API越抽象,它的表達能力越弱,但是它對數據的處理能力、抽象性也越強。在針對於上層Table api和SQL,它是主要是針對關係運算的,那針對關係數據的查詢,Flink提供了統一的接口,基於流數據api,同時提供了複雜事件處理api。複雜事件指的就是說對不能夠用時間去表示事件的開始、次序以及結束這樣的事件進行處理的api接口。另外針對於數據及api,它提供了機器學習api以及圖計算的api。

Flink核心概念- DataStream

DataStream: Flink用類DataStream來表示程序中的流式數據。用戶可以認爲它們是含有重複數據的不可修改的集合(collection),DataStream中元素的數量是無限的。

從圖中我們可以發現,對DataStream可以使用一些算子,例如KeyBy這樣的算子,對它進行處理轉換之後,它會轉換成另外一種數據流,也稱爲keyedstream。那麼基於keyedstream,我們進一步可以使用窗口算子,這主要是Flink程序設計中對數據流的一些處理方式。

Flink核心概念- DataSet

DataSet : Flink系統可對數據集進行轉換(例如,過濾,映射,聯接,分組),數據集可從讀取文件或從本地集合創建。結果通過接收器( Sink)返回,接收器可以將數據寫入(分佈式)文件或標準輸出(例如命令行終端)

Flink程序

Flink程序由Source、Transformation和Sink三部分組成,其中Source主要負責數據的讀取,支持HDFS、kafka和文本等;Transformation主要負責對數據的轉換操作; Sink負責最終數據的輸出,支持HDFS、kafka和文本輸出等。在各部分之間流轉的數據稱爲流( stream ) 。

Flink數據源

批處理:

Files:HDFS,Local file system,MapR file system;Text,CSV,Avro,Hadoop input formats

JDBC、HBase和 Collections

流處理:

Files、Socket streams、Kafka、RabbitMQ、Flume、Collections、 Implement your own和SourceFunction.collecto

Flink程序運行圖

Flink是一種master-Slave架構,它在啓動的時候就會產生了JobManger以及TaskManager。事實上在Flink程序中還包含兩個組件,這兩個組件一個叫resource manager,主要負責了資源的調度與管理,另外一個稱爲Dispatcher。主要是用來進行client,要把JobManager進行分發公佈。我們來看一看具體的運行流程。

首先是用戶提交Flink程序,這個Flink程序就會轉換成邏輯數據流圖。客戶端接收到邏輯數據流圖之後,然後連同jar包以及一些依賴包就會提交給了JobManger,JobManger接收到邏輯數據流圖之後會轉成物理數據流圖,這個物理數據流圖是真實的可執行的,能夠具體的將任務放置在TaskManager上,在TaskManager中會將它所擁有的資源劃分成一個一個的TaskSlot。每個TaskSlot實際上就相當於是jvm,它的一個具體的線程。每個TaskSlot佔用了TaskManager的一部分資源,這裏的資源主要是以內存進行劃分的,TaskSlot不對cpu的資源進行劃分,因此沒有對cpu的資源進行隔離。

Flink作業運行流程(一)

用戶首先提交Flink程序到JobClient,經過JobClient的處理、解析、優化提交到JobManager,最後由TaskManager運行task。

在Flink中它通過了JobClient提交了任務,做過JobClient提交的任務進一步的進行優化、解析以及處理,提交給了JobManager。JobManager會將jobClient提交了邏輯數據流圖轉換成物理數據流圖,然後將這些任務分配給taskmanager。taskmanager接受到任務之後就相應地進行處理,並且彙報了task的狀態給JobManager,JobManager最後就把結果反饋給jobClient。

JobClient是Flink程序和JobManager交互的橋樑。主要負責接收程序、解析程序的執行計劃、優化程序的執行計劃,然後提交執行計劃到JobManager。在Flink中主要有三類Operator。

Source Operator:數據源操作,比如文件、socket、Kafka等。

Transformation Operator:數據轉換操作,比如map,flatMap,reduce等算子。

Sink Operator:數據存儲操作。比如數據存儲到HDFS、Mysql、Kafka等等。

一個完整的Flink程序---java

Flink的數據處理

Apache Flink它同時支持批處理和流處理,也能用來做一些基於事件的應用。

首先Flink是一個純流式的計算引擎,它的基本數據模型是數據流。流可以是無邊界的無限流,即一般意義上的流處理。也可以是有邊界的有限流,就是批處理。因此Flink用一套架構同時支持了流處理和批處理。

其次,Flink的一個優勢是支持有狀態的計算。如果處理一個事件(或一條數據)的結果只跟事6件本身的內容有關,稱爲無狀態處理;反之結果還和之前處理過的事件有關,稱爲有狀態處理。

有界流與無界流

無界流:有定義流的開始,但沒有定義流的結束。數據源會無休止地產生數據。無界流的數據必須持續處理,即數據被讀取後需要立刻處理。不能等到所有數據都到達再處理,因爲輸入是無限的,在任何時候輸入都不會完成。處理無界數據通常要求以特定順序攝取事件,例如事件發生的順序,以便能夠推斷結果的完整性。

有界流:有定義流的開始,也有定義流的結束。有界流可以在讀取所有數據後再進行計算。有界流所有數據可以被排序,所以並不需要有序攝取。有界流處理通常被稱爲批處理。

批處理示例

批處理是流處理的一種非常特殊的情況。在流處理中,我們爲數據定義滑動窗口或滾動窗口,並且在每次窗口滑動或滾動時生成結果。批處理則不同,我們定義一個全局窗口,所有的記錄都屬於同一個窗口。舉例來說,以下代碼表示一個簡單的Flink程序,它負責每小時對某網站的訪問者計數,並按照地區分組。

如果知道輸入數據是有限的,則可以通過以下代碼實現批處理。

如果輸入數據是有限的,那麼下面代碼與上面代碼的運行結果相同。

Flink批處理模型

Flink通過一個底層引擎同時支持流處理和批處理。

在流處理引擎之上,Flink 有以下機制:

  • 檢查點機制和狀態機制:用於實現容錯、有狀態的處理;
  • 水印機制:用於實現事件時鐘;
  • 窗口和觸發器:用於限制計算範圍,並定義呈現結果的時間。

在同一個流處理引擎之上,Flink 還存在另一套機制,用於實現高效的批處理。

  • 用於調度和恢復的回溯法:由 Microsoft Dryad 引入,現在幾乎用於所有批處理器;
  • 用於散列和排序的特殊內存數據結構:可以在需要時,將一部分數據從內存溢出到硬盤上;
  • 優化器:儘可能地縮短生成結果的時間。

流與批處理機制

兩套機制分別對應各自的API(DataStream API 和 DataSet API);在創建 Flink 作業時,並不能通過將兩者混合在一起來同時 利用 Flink 的所有功能。

Flink支持兩種關係型的API,Table APl和sQL。這兩個API都是批處理和流處理統一的APl,這意味着在無邊界的實時數據流和有邊界的歷史記錄數據流上,關係型API會以相同的語義執行查詢,併產生相同的結果。

  • Table API / SQL 正在以流批統一的方式成爲分析型用例的主要 API。
  • DataStream API 是數據驅動應用程序和數據管道的主要API。

二、Flink的Time與Window

時間背景

在流處理器編程中,對於時間的處理是非常關鍵的。比如計數的例子,事件流數據(例如服務器日誌數據、網頁點擊數據和交易數據)不斷產生,我們需要用key將事件分組,並且每隔一段時間就針對每一個key對應的事件計數。這就是我們熟知的“大數據”應流處理中的時間分類

在數據流處理過程中,我們經常使用系統處理時間即: processing time作爲某個事件的時間,而實際上系統時間processing time是我們強加給事件的時間,由於網絡延遲等原因並不能較好的反應事件之間發生的先後順序。

在實際場景中,每個事件的時間可以分爲三種:

  • event time,即事件發生時的時間;
  • ingestion time,即事件到達流處理系統的時間;
  • processing time,即事件被系統處理的時間。

三種時間示例

例如,一條日誌進入Flink的時間爲2019-11-1210:00:00.123,到達window的系統時間爲2019-11-1210:00:01.234,日誌的內容如下:

2019-11-0218:37:15.624 INFO Fail over to rm2

2019-11-0218:37:15.624是Event Time;

2019-11-1210:00:00.123是Ingestion Time;

2019-11-1210:00:01.234是Processing Time;

三種時間的區別

實際情況中事件真正發生的先後順序與系統處理時間存在一定的差異,這些差異主要由網絡延遲、處理時間的長短等造成。如圖所示:

橫座標代表Event time,縱座標代表processing time。理想情況下,eventtime和processing time構成的座標應該形成一條傾斜角爲45度的線。但實際應用過程中,processing time要落後與eventtime,造成事件到來的先後順序不一致。

Flink支持的時間語義

Processing Time是指事件數據被Operator處理時所在機器的系統時間,它提供了最好的性能和最低的延遲。

Event Time是指在數據產生時該設備上對應的時間,這個時間在進入Flink之前已經存在於數據記錄中了。

Ingestion Time指的是事件數據進入到Flink的時間。

Window概述

流式計算是一種被設計用於處理無限數據集的數據處理引擎,而無限數據集是指一種不斷增長的本質上無限的數據集,而Window是一種切割無限數據爲有限塊進行處理的手段。Window是無限數據流處理的核心,它將一個無限的stream拆分成有限大小的"buckets"桶,我們可以在這些桶上做計算操作。

Window類型

Window根據應用類型可以分成兩類:

  • CountWindow:數據驅動,按照指定的數據條數生成一個Window,與時間無關。
  • TimeWindow:時間驅動,按照時間生成Window。

Apache Flink是一個天然支持無限流數據處理的分佈式計算框架,在Flink中 Window可以將無限流切分成有限流。Flink中 Window可以是Time Window,也可以是Count Window。

TimeWindow分類

TimeWindow可以根據窗口實現原理的不同分成三類:滾動窗口(Tumbling Window ) .滑動窗口( Sliding Window)和會話窗口( Session Window)。

滾動窗口

將數據依據固定的窗口長度對數據進行切片。特點:時間對齊,窗口長度固定,沒有重疊。

適用場景:適合做Bl統計等(做每個時間段的聚合計算)。

舉一個例子,假設要對傳感器輸出的數值求和。一分鐘滾動窗口收集最近一分鐘的數值,並在一分鐘結束時輸出總和,如下圖所示。

滑動窗口

滑動窗口是固定窗口的更廣義的一種形式,滑動窗口由固定的窗口長度和滑動間隔組成。特點∶時間對齊,窗口長度固定,有重疊。

適用場景:對最近一個時間段內的統計(求某接口最近5min的失敗率來決定是否要報警)。

示例:一分鐘滑動窗口計算最近一分鐘的數值總和,但每半分鐘滑動一次並輸出結果,如下圖所示。

會話窗口

會話窗口由一系列事件組合一個指定時間長度的timeout間隙組成,類似於web應用的session,也就是一段時間沒有接收到新數據就會生成新的窗口。特點:時間無對齊。

代碼定義

在Flink中,一分鐘滾動窗口的定義如下:

stream.timeWindow(Time.minutes(1));

在Flink中,每半分鐘(即30秒)滑動一次的一分鐘滑動窗口,如下所示:

stream.timeWindow(Time.minutes(1),Time.seconds(30));

三、Flink的Watermark

亂序問題

流處理從事件產生,到流經source,再到operator,中間是有一個過程和時間的,雖然大部分情況下,流到operator的數據都是按照事件產生的時間順序來的,但是也不排除由於網絡、分佈式等原因,導致亂序的產生,所謂亂序,就是指Flink接收到的事件的先後順序不是嚴格按照事件的Event Time順序排列的。

此時出現一個問題,一旦出現亂序,如果只根據eventTime決定window的運行,我們不能明確數據是否全部到位,但又不能無限期的等下去,此時必須要有個機制來保證一個特定的時間後,必須觸發window去進行計算了,這個特別的機制,就是Watermark。

亂序示例

例子:某App會記錄用戶的所有點擊行爲,並回傳日誌(在網絡不好的情況下,先保存在本地,延後回傳)。A用戶在11:02對App進行操作,B用戶在11:03對App進行操作,但是A用戶的網絡不太穩定,回傳日誌延遲了,導致我們在服務端先接受到B用戶11:03的消息,然後再接受到A用戶11:02的消息,消息亂序了。

水位線(Watermark)

對於無窮數據集,我們缺乏一種有效的方式來判斷數據完整性,因此就有了Watermark,它是建立在事件時間上的一個概念,用來刻畫數據流的完整性。如果按照處理時間來衡量事件,一切都是有序的、完美的,自然而然也就不需要Watermark了。換句話說事件時間帶來了亂序的問題,而Watermark就是用來解決亂序問題。所謂的亂序,其實就是有事件延遲了,對於延遲的元素,我們不可能無限期的等下去,必須要有一種機制來保證一個特定的時間後,必須觸發Window進行計算。這個特別的機制,就是Watermark,它告訴了算子延遲到達的消息不應該再被接收。

  • Watermark是一種衡量Event Time進展的機制。
  • Watermark是用於處理亂序事件的,而正確的處理亂序事件,通常用Watermark機制結合window來實現。
  • 數據流中的Watermark用於表示timestamp小於Watermark的數據,都已經到達了,因此,window的執行也是由Watermark觸發的。
  • Watermark可以理解成一個延遲觸發機制,我們可以設置Watermark的延時時長t,每次系統會校驗已經到達的數據中最大的maxEventTime,然後認定eventTime小於maxEventTime - t的所有數據都已經到達,如果有窗口的停止時間等於maxEventTime – t,那麼這個窗口被觸發執行。
  • watermark 用來讓程序自己平衡延遲和結果正確性

Watermark的原理

Flink怎麼保證基於event-time的窗口在銷燬的時候,已經處理完了所有的數據呢?

這就是watermark的功能所在。watermark會攜帶一個單調遞增的時間戳t,Watermark(t)表示所有時間戳不大於t的數據都已經到來了,未來小於等於t的數據不會再來,因此可以放心地觸發和銷燬窗口了。

當Flink,接收到數據時,會按照一定的規則去生成Watermark,這條Watermark就等於當前所有到達數據中的maExertT me"-延N時長,也就定說,Watermark是基於數據攜帶的時間戳生成的,一旦Watermark比當前未觸發的窗口的停止時間要晚,那麼就會觸發相應窗口的執行。由於eventtime是由數據攜帶的,因此,如果運行過程中無法獲取新的數據,那麼沒有被觸發的窗口將永遠都不被觸發。

上圖中,我們設置的允許最大延遲到達時間爲2s,所以時間戳爲7s的事件對應的Watermark 是 5s,時間戳爲12s的事件的Watermark是10s,如果我們的窗口是1s-5s,窗口2是6s~-10s,那麼時間戳爲7s的事件到達時的Matermarker.恰好觸發窗口1,時間戳爲 12s的事件到達時的Watermark恰好觸發窗口2。

Watermark就是觸發前一窗口的“關窗時間”,一旦觸發關門那麼以當前時刻爲準在窗口範圍內的所有所有數據都會收入窗中。只要沒有達到水位那麼不管現實中的時間推進了多久都不會觸發關窗。

延遲的數據

Watermark能夠應對亂序的數據,但是真實世界中沒法得到一個完美的 Watermark數值。要麼沒法獲取到,要麼耗費太大,因此實際工作中會近似 Watermark(t)之後,還有較小的概率接受到時間戳t之前的數據,在Flink中將這些數據定義爲“late elements”,同樣可以在Window中指定允許延遲的最大時間(默認爲О),可以使用下面的代碼進行設置:

延遲數據處理機制

延遲事件是亂序事件的特例,和一般亂序事件不同的是它們的亂序程度超出了水位線( Watermark)的預計,導致窗口在它們到達之前已經關閉。

延遲事件出現時窗口已經關閉併產出了計算結果,對於此種情況處理的方法有3種:

  • 重新激活已經關閉的窗口並重新計算以修正結果。
  • 將延遲事件收集起來另外處理。
  • 將延遲事件視爲錯誤消息並丟棄。

Flink默認的處理方式是第3種直接丟棄,其他兩種方式分別使用Side Output和AllowedLateness。

Side Output機制

Side Output機制可以將延遲事件單獨放入一個數據流分支,這會作爲Window計算結果的副產品,以便用戶獲取並對其進行特殊處理。

side Output獲取延遲數據:

設置allowedLateness之後,遲來的數據同樣可以觸發窗口,進行輸出,利用Flink的sideoutput機制,可以獲取到這些延遲的數據,使用方式如下:

Allowed Lateness機制

Allowed Lateness機制允許用戶設置一個允許的最大延遲時長。Flink會在窗口關閉後一直保存窗口的狀態直至超過允許延遲時長,這期間的延遲事件不會被丟棄,而是默認會觸發窗口重新計算。因爲保存窗口狀態需要額外內存,並且如果窗口計算使用了ProcessWindowFunction APl還可能使得每個延遲事件觸發一次窗口的全量計算,代價比較大,所以允許延遲時長不宜設得太長,延遲事件也不宜過多。

四、Flink的容錯

Flink容錯機制

爲了保證程序的容錯恢復以及程序啓動時其狀態恢復,Flink任務都會開啓Checkpoint或者觸發Savepoint進行狀態保存。

  • Checkpoint機制。這種機制保證了實時程序運行時,即使突然遇到異常也能夠進行自我恢復。Checkpoint對於用戶層面,是透明的,用戶會感覺不到Checkpoint過程的存在。
  • Savepoint機制。是在某個時間點程序狀態全局鏡像,以後程序在進行升級,或者修改併發度等情況,還能從保存的狀態位繼續啓動恢復。Savepoint可以看做是Checkpoint在特定時期的一個狀態快照。

Checkpoint

Flink 如何保證exactly-once呢?它使用一種被稱爲“檢查點( Checkpoint )”的特性,在出現故障時將系統重置回正確狀態。Flink狀態保存主要依靠Checkpoint機制,Checkpoint會定時製作分佈式快照,對程序中的狀態進行備份。

Checkpoint檢查點機制

Flink中基於異步輕量級的分佈式快照技術提供了Checkpoints容錯機制,分佈式快照可以將同一時間點Task/Operator的狀態數據全局統一快照處理。Flink會在輸入的數據集上間隔性地生成checkpoint barrier,通過棚欄( barrier)將間隔時間段內的數據劃分到相應的checkpoint中。當應用出現異常時,Operator就能夠從上一次快照中恢復所有算子之前的狀態,從而保證數據的一致性。

對於狀態佔用空間比較小的應用,快照產生過程非常輕量,高頻率創建且對Flink任務性能影響相對較小。Checkpoint過程中狀態數據一般被保存在一個可配置的環境中,通常是在JobManager節點或HDFS上。

Checkpoint配置

默認情況下Flink不開啓檢查點,用戶需要在程序中通過調用enableCheckpointing(n)方法配置和開啓檢查點,其中n爲檢查點執行的時間間隔,單位爲毫秒。

exactly-once和at-least-once語義選擇

exactly-once:保證端到端數據一致性,數據要求高,不允許出現數據丟失和數據重複,Flink的性能也相對較弱;

at-least-once:時延和吞吐量要求非常高但對數據的一致性要求不高的場景。

Flink默認使用exactly-once模式,可以通過setCheckpointingMode()方法來設定語義模式。

env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)

Checkpoint超時時間

指定每次Checkpoint執行過程中的上限時間範圍,一旦Checkpoint執行時間超過該閾值,Flink將會中斷Checkpoint過程,並按照超時處理。

該指標可以通過setCheckpointTimeout方法設定,默認10分鐘。

env.getCheckpointConfig().setCheckpointingTimeout(60000)

檢查點之間最小時間間隔

設定兩個Checkpoint之間的最小時間間隔,防止出現狀態數據過大而導致Checkpoint執行時間過長,從而導致Checkpoint積壓過多,最終Flink應用密集地觸發Checkpoint操作,會佔用大量計算資源而影響到整個應用的性能。

env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500)

最大並行執行的檢查點數量

設定能夠同時執行的Checkpoint數量。在默認情況下只有一個檢查點可以運行,根據用戶指定的數量可以同時觸發多個Checkpoint,從而提升Checkpoint整體的效率。

env.getCheckpointConfig().setMaxConcurrentCheckpoints(500)

外部檢查點

設定週期性的外部檢查點,然後將狀態數據持久化到外部系統中,使用這種方式不會在任務停止的過程中清理掉檢查點數據,而是一直保存在外部系統介質中,也可以通過從外部檢查點中對任務就行恢復。

env.getCheckpointConfig().enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION)

作業如何恢復數據?

Flink在Cancel時允許在外部介質保留Checkpoint;另一方面,Flink還有另外一個機制是SavePoint.

Savepoints是檢查點的一種特殊實現,底層其實是使用Checkpoints的機制。Savepoints是用戶以手工命令的方式觸發,並將結果持久化到指定的存儲路徑中,目的是幫助用戶在升級和維護集羣過程中保存系統中的狀態數據,避免因爲停機運維或者升級應用等正常終止應用的操作而導致系統無法恢復到原有的計算狀態的情況,從而無法實現端到端的Exactly-Once語義保證。

Savepoint與Checkpoint

checkpoint的側重點是“容錯”,即Flink作業意外失敗並重啓之後,能夠直接從早先打下的checkpoint恢復運行,且不影響作業邏輯的準確性。而savepoint的側重點是“維護”,即Flink作業需要在人工干預下手動重啓、升級、遷移或A/B測試時,先將狀態整體寫入可靠存儲,維護完畢之後再從savepoint恢復現場。

savepoint是“通過checkpoint機制”創建的,所以savepoint本質上是特殊的checkpoint。

checkpoint面向Flink Runtime本身,由Flink的各個TaskManager定時觸發快照並自動清理,一般不需要用戶干預;savepoint面向用戶,完全根據用戶的需要觸發與清理。

  • 觸發管理方式上,Checkpoint是由Flink自動觸發並管理;Savepoint由用戶手動觸發並管理
  • 主要用途上,Checkpoint在Task發生異常時快速恢復,例如網絡抖動導致的超時異常;Savepoint有計劃的進行備份,例如修改代碼,調整併發
  • 從特點上看,Checkpoint輕量,自動從故障中恢復,在作業停止後默認清除;Savepoint持久,以標準格式存儲,允許代碼或配置發生改變,手動觸發從Savepoint的恢復。

狀態的存儲方式-MemoryStateBackend

構造方式:

MemoryStateBackend(int maxStateSize, boolean asynchronousSnapshots)

存儲方式:

- State: TaskManager內存;Checkpoint: JobManager內存。

容量限制:

單個state maxStateSize默認5M; maxStateSize<=akka.framesize ,默認10 M。·總大小不超過JobManager的內存

推薦使用的場景:本地測試;幾乎無狀態的作業,比如ETL。

狀態的存儲方式- FsStateBackend

構造方式:

FsStateBackend(URI checkpointDataUri ,boolean asynchronousSnapshots)

存儲方式:

State: TaskManager內存;

CHeckpoint:外部文件存儲系統(本地或HDFS)。

容量限制:

·單TaskManager 上state總量不超過它的內存;

·總大小不超過配置的文件系統容量。

推薦使用的場景:常規使用狀態的作業,例如分鐘級別窗口聚合、Join;需要開啓HA的作業;可以在生產場景使用。

狀態的存儲方式- RocksDBStateBackend

構造方式:

RocksDBStateBackend(URI checkpointDataUri ,boolean enableIncrementalCheckpointing)

存儲方式:

State: TaskManager上的KV數據庫(實際使用內存+磁盤);

CHeckpoint:外部文件存儲系統(本地或HDFS)。

容量限制:

單TaskManager 上State總量不超過它的內存+磁盤;

單Key最大2G;

總大小不超過配置的文件系統容量。

推薦使用的場景:超大狀態的作業,例如天級別窗口聚合;需要開啓HA的作業;要求不高的作業;可以在生產場景使用。

總結

本章主要講述了Flink的架構及技術原理,以及Flink程序的運行過程。重點在於Flink流處理與批處理的不同方式,從長遠來看,DataStream API應該通過有界數據流完全包含DataSet APl。

 

點擊關注,第一時間瞭解華爲雲新鮮技術~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章