State Processor API:如何讀取,寫入和修改 Flink 應用程式的狀態

芊寶寶最可愛發表於2019-12-24

過去無論您是在生產中使用,還是調研Apache Flink,估計您總是會問這樣一個問題:我該如何訪問和更新Flink儲存點(savepoint)中儲存的state?不用再詢問了,Apache Flink 1.9.0引入了狀態處理器( State Processor)API,它是基於DataSet API的強大擴充套件,允許讀取,寫入和修改Flink的儲存點和檢查點(checkpoint)中的狀態。

在這篇文章中,我們將解釋為什麼此功能對Flink來說很重要,以及該功能的用途和用法。最後,我們將討論狀態處理器API的未來規劃,以保持與Flink批流統一的未來整體規劃一致。

截止到Apache Flink 1.9的狀態流處理現狀

幾乎所有複雜的流處理應用程式都是有狀態的,其中大多數都是設計為執行數月甚至數年。隨著時間的推移,這些作業積累了很多有價值的狀態,如果由於故障而丟失,這些狀態的重建將變得代價很高甚至是不可能的。為了保證應用程式狀態的一致性和永續性,Flink從一開始就設計了一套複雜巧妙的檢查點和恢復機制。在每一個版本中,Flink社群都新增了越來越多與狀態相關的特性,以提高檢查點執行和恢復的速度、改進應用程式的維護和管理。

然而,Flink使用者經常會提出能夠“從外部”訪問應用程式的狀態的需求。這個需求的動機可能是驗證或除錯應用程式的狀態,或者將應用程式的狀態遷移到另一個應用程式,或者從外部系統(例如關聯式資料庫)匯入應用程式的初始狀態。

儘管這些需求的出發點都是合理的,但到目前為止從外部訪問應用程式的狀態這一功能仍然相當有限。Flink的可查詢狀態( queryable state)功能只支援基於鍵的查詢(點查詢),且不保證返回值的一致性(在應用程式發生故障恢復前後,返回值可能不同),並且可查詢狀態只支援讀取並不支援修改和寫入。此外,狀態的一致性快照:儲存點,也是無法訪問的,因為這是使用自定義二進位制格式進行編碼的。

使用狀態處理器(State Processor)API對應用程式狀態進行讀寫

Flink1.9引入的狀態處理器API,真正改變了這一現狀,實現了對應用程式狀態的操作。該功能借助DataSet API,擴充套件了輸入和輸出格式以讀寫儲存點或檢查點資料。由於DataSet和Table API的互通性,使用者甚至可以使用關係表API或SQL查詢來分析和處理狀態資料。

例如,使用者可以建立正在執行的流處理應用程式的儲存點,並使用批處理程式對其進行分析,以驗證該應用程式的行為是否正確。 或者,使用者也可以任意讀取、處理、並寫入資料到儲存點中,將其用於流計算應用程式的初始狀態。 同時,現在也支援修復儲存點中狀態不一致的條目。最後,狀態處理器API開闢了許多方法來開發有狀態的應用程式,以繞過以前為了保證可以正常恢復而做的諸多限制:使用者現在可以任意修改狀態的資料型別,調整運算子的最大並行度,拆分或合併運算子狀態,重新分配運算子UID等等。

將應用程式與資料集進行對映

狀態處理器API將流應用程式的狀態對映到一個或多個可以分別處理的資料集。為了能夠使用API,您需要了解此對映的工作方式。

首先,讓我們看看有狀態的Flink作業是什麼樣的。Flink作業由運算元( operator)組成,通常是一個或多個source運算元,一些進行資料處理的運算元以及一個或多個sink運算元。每個運算元在一個或多個任務中並行執行,並且可以使用不同型別的狀態:可以具有零個,一個或多個列表形式的 operator states,他們的作用域範圍是當前運算元例項;如果這些運算元應用於鍵控流( keyed stream),它還可以具有零個,一個或多個 keyed states,它們的作用域範圍是從每個處理記錄中提取的鍵。您可以將keyed states視為分散式鍵-值對映。

下圖顯示的應用程式“MyApp”,由稱為“Src”,“Proc”和“Snk”的三個運算元組成。Src具有一個 operator state(os1),Proc具有一個 operator state(os2)和兩個 keyed state(ks1,ks2),而Snk則是無狀態的。


State Processor API:如何讀取,寫入和修改 Flink 應用程式的狀態


MyApp的儲存點或檢查點均由所有狀態的資料組成,這些資料的組織方式可以恢復每個任務的狀態。在使用批處理作業處理儲存點(或檢查點)的資料時,我們腦海中需要將每個任務狀態的資料對映到資料集或表中。因為實際上,我們可以將儲存點視為資料庫。每個運算元(由其UID標識)代表一個名稱空間。運算元的每個 operator state都射到名稱空間中的一個單列專用表,該列儲存所有任務的狀態資料。operator的所有 keyed state都對映到一個鍵值多列表,該表由一列key和與每個 key state對映的一列值組成。下圖顯示了MyApp的儲存點如何對映到資料庫


State Processor API:如何讀取,寫入和修改 Flink 應用程式的狀態


該圖顯示了"Src"的 operator state的值如何對映到具有一列和五行的表,一行資料代表對於Src的所有並行任務中的一個並行例項。類似地,"Proc"的 operator state os2,也對映到單個表。對於 keyed state,ks1和ks2則是被組合到具有三列的單個表中,一列代表主鍵,一列代表ks1,一列代表ks2。該表為兩個keyed state的每個不同key都保有一行。由於“Snk”沒有任何狀態,因此其對映表為空。

狀態處理器API提供了建立,載入和編寫儲存點的方法。使用者可以從已載入的儲存點讀取資料集,也可以將資料集轉換為狀態並將其新增到儲存點中。總之,可以使用DataSet API的全部功能集來處理這些資料集。使用這些方法,可以解決所有前面提到的用例(以及更多用例)。如果您想詳細瞭解如何使用狀態處理器API,請 檢視文件

為什麼使用DataSet API?

如果您熟悉Flink的未來規劃,可能會對狀態處理器API基於DataSet API而感到驚訝,因為目前Flink社群計劃使用 BoundedStreams的概念擴充套件DataStream API,並棄用DataSet API。但是在設計此狀態處理器功能時,我們還評估了DataStream API以及Table API,他們都不能提供相應的功能支援。由於不想此功能的開發因此受到阻礙,我們決定先在DataSet API上構建該功能,並將其對DataSet API的依賴性降到最低。基於此,將其遷移到另一個API應該是相當容易的。

總結

Flink使用者很長時間以來有從外部訪問和修改流應用程式的狀態的需求,藉助於狀態處理器API,Flink為使用者如何維護和管理流應用程式開啟了許多新可能性,包括流應用程式的任意演變以及應用程式狀態的匯出和引導。簡而言之,狀態處理器API得儲存點不再是一個黑匣子。

原文連結

本文為阿里雲原創內容,未經允許不得轉載。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69949601/viewspace-2670244/,如需轉載,請註明出處,否則將追究法律責任。

相關文章