Flink DataStream 狀態和容錯 二:Checkpoint 和 StateBackends

Checkpoint

Flink 中的 State 在上一篇中介紹過,為了使 State 容錯,需要有 State checkpoint(狀態檢查點)。Checkpoint 允許 Flink 恢復流的 State 和處理位置,從而為程序提供與無故障執行相同的語義。Checkpoint 機制在 Flink 容錯機制 中有更詳細介紹。

Checkpoint 使用的先決條件:

  1. 一個持久化的,能夠在一定時間范圍內重放記錄的數據源。例如,持久化消息隊列:Apache Kafka,RabbitMQ,Amazon Kinesis,Google PubSub 或文件系統:HDFS,S3,GFS,NFS,Ceph...
  2. State 持久化存儲系統,通常是分布式文件系統:HDFS,S3,GFS,NFS,Ceph...

啟用和配置

Checkpoint 默認情況下是不啟用的。StreamExecutionEnvironment 對象調用 enableCheckpointing(n) 啟用 Checkpoint,其中n是以毫秒為單位的 Checkpoint 間隔。

Checkpoint 的配置項包括:

  • 恰好一次(exactly-once)或至少一次(at-least-once):Checkpoint 支持這兩種模式。對于大多數應用來說,恰好一次是優選的。至少一次可能在某些要求超低延遲(幾毫秒)的應用程序使用。

  • Checkpoint 超時時間:在超時時間內 checkpoint 未完成,則中止正在進行的 checkpoint。

  • Checkpoint 最小間隔時間(毫秒):如果設置為5000,表示在上一個 checkpoint 完成后的至少5秒后才會啟動下一個 checkpoint,不論 checkpoint 的持續時間和間隔是多少。即使 checkpoint 間隔永遠不會小于此參數。是為了保證 checkpoint 之間能夠完成一定量的數據處理工作。

    配置 time between checkpoint 相比配置 checkpoint interval 通常更容易。因為 checkpoint 耗時有時會明顯比平時更長,time between checkpoint 更不容易收到影響(例如,目標存儲系統臨時性的響應緩慢)

    這個值還意味著并發 checkpoint 的數量是一個

  • Checkpoint 并發數:默認情況下,當一個 checkpoint 處于運行狀態時,系統不會觸發另一個 checkpoint。確保整個拓撲結構不會花費太多時間用于 checkpoint。該設置可以設置多個重疊的 checkpoint,特點的場景可能會需要。

    當設置 time between checkpoint 時,不能使用此配置。

  • 外部 checkpoint:可以配置在系統外部持久化 checkpoint。Checkpoint 信息寫入外部持久存儲,在作業失敗時不會自動清除,因此作業失敗時可以用來恢復。

  • Checkpoint 出錯時,任務狀態:決定了如果在 checkpoint 過程中發生錯誤,當前任務是否將失敗或繼續執行。默認會任務失敗。

val env = StreamExecutionEnvironment.getExecutionEnvironment()

// 啟用 checkpoint 間隔 1000 ms
env.enableCheckpointing(1000)

// 高級選項:

// 設置 exactly-once 模式
env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)

// 設置 checkpoint 最小間隔 500 ms 
env.getCheckpointConfig.setMinPauseBetweenCheckpoints(500)

// 設置 checkpoint 必須在1分鐘內完成,否則會被丟棄
env.getCheckpointConfig.setCheckpointTimeout(60000)

// 設置 checkpoint 失敗時,任務不會 fail,該 checkpoint 會被丟棄
env.getCheckpointConfig.setFailTasksOnCheckpointingErrors(false)

// 設置 checkpoint 的并發度為 1
env.getCheckpointConfig.setMaxConcurrentCheckpoints(1)

相關配置

更多相關參數可以通過 conf/flink-conf.yaml 全局配置

配置項 默認值 描述
state.backend (none) 選擇 state backend 實現
state.backend.async true state backend 使用異步方法。有些不支持異步,或者僅支持異步的可并忽略此選項
state.backend.fs.memory-threshold 1024 存儲 state 數據文件的最小規模,如果小于該值則會存儲在 root checkpoint metadata file
state.backend.incremental false 是否采用增量 checkpoint,有些不支持增量的可并忽略此選項
state.backend.local-recovery false
state.checkpoints.dir (none) 用于指定 checkpoint 數據存儲目錄,目錄必須對所有參與的 TaskManagers 和 JobManagers 可見
state.checkpoints.num-retained 1 指定保留已完成的 checkpoint 數量
state.savepoints.dir (none) 用于指定 savepoint 數據存儲目錄
taskmanager.state.local.root-dirs (none)

選擇 State backend

Checkpoint 的存儲的位置取決于配置的 State backend(JobManager 內存,文件系統,數據庫...)。

默認情況下,State 存儲在 TaskManager 內存中,Checkpoint 存儲在 JobManager 內存中。Flink 支持在其他 state backend 中存儲 State 和 Checkpoint。可以通過如下方法配置:StreamExecutionEnvironment.setStateBackend(…),下面有更詳細的介紹。

迭代任務中使用

Flink 目前僅為沒有迭代的作業提供處理保證。在迭代作業上啟用 checkpoint 會導致異常。為了強制對迭代程序執行 checkpoing,需要設置一個特殊標志:env.enableCheckpointing(interval, force = true)

在失敗期間,處在循環邊界的記錄(以及與相關的 State 變化)將丟失。

State backend

Flink 提供了不同的 State backend,支持不通的 State 存儲方式和位置。默認會使用配置文件 flink-conf.yaml 指定的選項,也可以在每個作業中設置來覆蓋默認選項:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setStateBackend(...);

Flink 自帶了以下幾種開箱即用的 state backend:

  • MemoryStateBackend
  • FsStateBackend
  • RocksDBStateBackend

在沒有配置的情況下,系統默認使用 MemoryStateBackend

三種 State backend 介紹

MemoryStateBackend

使用 MemoryStateBackend,在 checkpoint 中對 State 做一次快照,并在向 JobManager 發送 checkpoint 確認完成的消息中帶上此快照數據,然后快照就會存儲在 JobManager 的內存堆中。

MemoryStateBackend 的限制:

  • 單個 State 的大小默認限制為5MB,可以在 MemoryStateBackend 的構造函數中增加。
  • 不論如何配置,State 大小都無法大于 akka.framesize(JobManager 和 TaskManager 之間發送的最大消息的大小)
  • JobManager 必須有足夠的內存大小

MemoryStateBackend 適用以下場景:

  • 本地開發和調試
  • 只持有很小的狀態,如方法:Map、FlatMap、Filter... 或 Kafka Consumer

FsStateBackend

FsStateBackend 需要配置一個文件系統的URL來,如 "hdfs://namenode:40010/flink/checkpoint" 或 "file:///data/flink/checkpoints"。

FsStateBackend 在 TaskManager 的內存中持有正在處理的數據。Checkpoint 時將 state snapshot 寫入文件系統目錄下的文件中,文件的路徑會傳遞給 JobManager,存在其內存中。

FsStateBackend 默認是異步操作,以避免在寫 state snapshot 時阻塞處理程序。如果要禁用異步,可以在 FsStateBackend 構造函數中設置:

new FsStateBackend(path, false);

FsStateBackend 適用以下場景:

  • State 較大,窗口時間較長和 key/value 較大的 State
  • 所有高可用性的情況

RocksDBStateBackend

RocksDBStateBackend 需要配置一個文件系統的URL來,如 "hdfs://namenode:40010/flink/checkpoint" 或 "file:///data/flink/checkpoints"。

RocksDBStateBackend 在 RocksDB 中持有正在處理的數據,RocksDB 在 TaskManager 的數據目錄下。Checkpoint 時將整個 RocksDB 寫入文件系統目錄下的文件中,文件的路徑會傳遞給 JobManager,存在其內存中。

RocksDBStateBackend 通常也是異步的。

RocksDBStateBackend 的限制:
RocksDB JNI API 是基于 byte[],因此 key 和 value 最大支持大小為2^31 個字節。RocksDB 自身在支持較大 value 時候有一些問題。

RocksDBStateBackendFsStateBackend 同樣適用以下場景:

  • State 較大,窗口時間較長和 key/value 較大的 State
  • 所有高可用性的情況
  • 目前唯一支持增量 checkpoint

與前兩者相比(處理狀態下的 State 還是保存在內存中),使用 RocksDB 可以保存的狀態量僅受可用磁盤空間量的限制。這也意味著可以實現的最大吞吐量更低,后臺的所有讀/寫都必須通過序列化和反序列化來檢索/存儲 State,這也比使用基于堆內存的方式代價更昂貴。

性能比較

Flink 支持 Standalone 和 on Yarn 的集群部署模式,以 Windowed Word Count 處理為例測試三種 State backends 在不通集群部署上的性能差異(來源:美團 Flink _Benchmark

Standalone 時的存儲路徑為 JobManager 上的一個文件目錄,on Yarn 時存儲路徑為 HDFS 上一個文件目錄。

不同 State backend 吞吐量對比

Throughput
  • 使用 FileSystem 和 Memory 的吞吐差異不大(都是使用堆內存管理處理中的數據),使用 RocksDB 的吞吐差距明顯。
  • Standalone 和 on Yarn 的總體差異不大,使用 FileSystem 和 Memory 時 on Yarn 模式下吞吐稍高,相反的使用 RocksDB 時 Standalone 模式下的吞吐稍高。

不同 State backend 延遲對比

Latency
  • 使用 FileSystem 和 Memory 時延遲基本一致且較低。
  • 使用 RocksDB 時延遲稍高,且由于吞吐較低,在達到吞吐瓶頸附近延遲陡增。其中 on Yarn 模式下吞吐更低,延遲變化更加明顯。

State backend 的選擇

StateBackend in-flight checkpoint 吞吐 推薦使用場景
MemoryStateBackend TM Memory JM Memory 調試、無狀態或對數據丟失或重復無要求
FsStateBackend TM Memory FS/HDFS 普通狀態、窗口、KV 結構
RocksDBStateBackend RocksDB on TM FS/HDFS 超大狀態、超長窗口、大型 KV 結構

Reference:
https://flink.xskoo.com/dev/stream/state/checkpointing.html
https://tech.meituan.com/Flink_Benchmark.html

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,546評論 6 533
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,570評論 3 418
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,505評論 0 376
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,017評論 1 313
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,786評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,219評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,287評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,438評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,971評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,796評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,995評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,540評論 5 359
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,230評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,662評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,918評論 1 286
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,697評論 3 392
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,991評論 2 374