Flink例項(三十):狀態管理(一)概述
參考連結;
https://www.cnblogs.com/qiu-hua/p/13432337.html
https://www.cnblogs.com/shengyang17/p/12549199.html
1. 狀態管理
Flink中的狀態
- A. 運算元狀態(Operatior State)
- B. 鍵控狀態(Keyed State)
- 狀態後端(State Backends) --用作狀態管理
流式處理(A. 可以是無狀態(基於某個獨立的事件計算出來後直接輸出了,來一個處理一個不涉及到其他東西,如map、flatmap、filter;超過一定溫度就報警 - 側輸出流;)、
B. 可以是有轉態的(求和、wordcount計算))
- 狀態是針對一個任務而言的,由一個任務維護,並且用來計算某個結果的所有資料,都屬於這個任務的轉態;
- 可以認為狀態就是一個本地變數,可以被任務的業務邏輯直接訪問;
- Flink會進行狀態管理(狀態做序列化以二進位制的形式全部儲存起來),包括狀態一致性、故障處理以及高效儲存和訪問,以便開發人員可以專注於應用程式的邏輯。
在Flink中,狀態始終與特定運算元相關聯;為了執行時的Flink瞭解運算元的狀態,運算元需要預先註冊其狀態;
有兩種狀態:
運算元狀態(Operator State),運算元狀態的作用範圍限定為運算元任務,一個任務一個狀態;
鍵控(分割槽)狀態(Keyed State)
A. 運算元狀態:
運算元狀態的作用範圍限定為運算元任務,由同一並行子任務所處理的所有資料都可以訪問到相同的狀態;
狀態對於同一個任務而言是共享的(每一個並行的子任務共享一個狀態);
運算元狀態不能由相同或不同運算元的另一個任務訪問(相同運算元的不同任務之間也不能訪問);
運算元狀態資料結構:
列表狀態(List state),將狀態表示為一組資料的列表;(會根據並行度的調整把之前的狀態重新分組重新分配
聯合列表狀態(Union list state),也將狀態表示為資料的列表,它常規列表狀態的區別在於,在發生故障時,或者從儲存點(savepoint)啟動應用程式時如何恢復(把之前的每一個狀態廣播到對應的每個運算元中)。
廣播狀態(Broadcast state),如果一個運算元有多項任務,而它的每項任務狀態又都相同,那麼這種特殊情況最適合應用廣播狀態(把同一個狀態廣播給所有運算元子任務);
B. 鍵控狀態(Keyed State)-- 更常用
鍵控狀態是根據輸入資料流中定義的鍵(key)來維度和訪問狀態的;
Flink為每個key維護一個狀態例項,並將具有相同鍵的所有資料,都分割槽到同一個運算元任務中,這個任務會維護和處理這個key對應的狀態;
當任務處理一條資料時,它會自動將狀態的訪問範圍限定為當前資料的key;
鍵控狀態資料結構:
值狀態(Value state),將狀態表示為單個值;(直接.value獲取,Set操作是.update)
列表狀態(List state),將狀態表示為一組資料的列表(存多個狀態);(.get,.update,.add)
對映狀態(Map state),將狀態表示為一組Key-Value對;(.get,.put ,類似HashMap)
聚合狀態(Reducing state & Aggregating State),將狀態表示為一個用於聚合操作的列表;(.add不像之前新增到列表,它是直接聚合到之前的結果中)
Reduce輸入輸出型別是不能變的,Aggregate可得到資料型別完全不一樣的結果;
鍵控狀態的使用:
宣告一個鍵控狀態: lazy val lastTemp: ValueState[Double] = getRuntimeContext.getState( new ValueStateDescriptor[Double]("lastTemp", classOf[Double]) ) 讀取狀態: val prevTemp = lastTemp.value() 對狀態賦值: lastTemp.update(value.temperature)
C. 狀態後端(State Backends) -- 狀態管理(儲存、訪問、維護和檢查點)
每傳入一條資料,有狀態的運算元任務都會讀取和更新狀態;
由於有效的狀態訪問對於處理資料的低效遲至關重要,因此每個並行任務都會在本地維度其狀態,以確保快速的狀態訪問;
狀態的儲存、訪問以及維度,由一個可插入的元件決定,這個元件就叫做狀態後端(State Backends);
狀態後端主要負責兩件事:本地的狀態管理,以及將檢查點(checkpoint)狀態寫入遠端儲存;
狀態後端的分類:
MemoryStateBackend: 一般用於開發和測試
- 記憶體級的狀態後端,會將鍵控狀態作為記憶體中的物件進行管理,將它們儲存在TaskManager的JVM堆上,而將checkpoint儲存在JobManager的記憶體中;
- 特點快速、低延遲,但不穩定;
FsStateBackend(檔案系統狀態後端):生產環境
- 將checkpoint存到遠端的持久化檔案系統(FileSystem)上,而對於本地狀態,跟MemoryStateBackend一樣,也會存到TaskManager的JVM堆上。
- 同時擁有記憶體級的本地訪問速度,和更好的容錯保證;(如果是超大規模的需要儲存還是無法解決,存到本地狀態就可能OOM)
RocksDBStateBackend:
- 將所有狀態序列化後,存入本地的RocksDB(本地資料庫硬碟空間)中儲存,全部序列化儲存到本地。