Flink 調優:Checkpoint 配置

Flink 原理與實現:Checkpoint 這篇文章中介紹了 Flink Checkpoint 的原理以及作用,Flink 原理與實現:Savepoint
這篇文章講述了 Flink Checkpoint 和 Savepoint 的異同。有了這些基礎,你就可以在流式計算中對 Flink Checkpoint 進行配置了,下文會詳細介紹各種配置方式,以及配置原則。

1. Checkpoint 的配置

在 Flink 應用程序中配置 Checkpoint,首先需要開啓 Checkpoint,同時指定 Checkpoint 的時間間隔。

val env = StreamExecutionEnvironment.getExecutionEnvironment

// enable Checkpoint and set 10min Checkpoint Interval
env.enableCheckpointing(10 * 1000)

爲了對 Checkpoint 進行更多的配置,你需要拿到 CheckpointConfig:

val chkpConf = env.getCheckpointConfig

Flink 默認提供 Extractly-Once 保證 State 的一致性。這可以通過 CheckpointConfig 進行設置,Flink 提供了 Extractly-Once,At-Least-Once 兩種模式。

chkpConf.setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE)

如果只是設置 State 的一致性保障機制,那麼可以簡單配置成:

env.enableCheckpointing(10 * 1000, CheckpointingMode.EXACTLY_ONCE)

由於每個 Flink 應用程序的 State 大小不同,StateBackend 也可能有所不同,所以,Checkpoint 需要根據實際情況配置。Flink 默認同一時間只允許執行一個 Checkpoint,以避免佔用太多正常數據處理資源。如果在配置的 Checkpoint 時間間隔之內,一個 Checkpoint 正在生產,另一個 Checkpoint 也需要開始生產,那麼,第二個 Checkpoint 將會等到第一個 Checkpoint 生產完成纔會開始。

那麼,如果很多 Checkpoint 生產時間過長,比 Checkpoint 時間間隔還要長,會有什麼影響呢?在這種情況下,Checkpoint 的配置是不理想的,原因有二:

  1. 這種現象意味着應用程序的正常數據處理過程和 Checkpoint 的生產是併發的,資源是被二者共享的。所以,它將會拖慢正常數據的處理速度,無法全力消費數據,甚至導致數據的處理速度慢於數據的輸入速度。
  2. 因爲需要等待前一個 Checkpoint 生產完成,會使下一個 Checkpoint 延遲生產,從而導致在失敗恢復時需要更長的追趕時間。

爲了保證應用程序可以全力處理數據,你可以配置 Checkpoint 彼此之間的停頓時間。比如,你配置最小停頓時間是一分鐘,那麼在一個 Checkpoint 生產完成之後的頭一分鐘,不會有新的 Checkpoint 被拉起,這僅限於同時最多隻有一個 Checkpoint 生產的情況。

chkpConf.setMinPauseBetweenCheckpoints(60 * 1000)

如果某個應用程序的 Checkpoint 生產需要比較長的時間,但由於不用消耗很多資源,那麼這時候是可以配置 Checkpoint 更高的併發量的:

chkpConf.setMaxConcurrentCheckpoints(3)

值得注意的一點是:Savepoint 是可以和 Checkpoint 併發生產的。即使有多個 Checkpoint 正在生產的過程中,Savepoint 也會併發生產

爲了避免有 Checkpoint 生產時間過長,導致資源一直被佔用,你可以給 Checkpoint 設置一個超時時間,Flink 默認的 Checkpoint 超時時間是 10 分鐘。

chkpConf.setCheckpointTimeout(5 * 1000)

衆所周知,Checkpoint 失敗之後,會觸發 Flink 的失敗恢復機制進行重啓。如果你想禁用這個功能,讓應用程序在 Checkpoint 失敗後繼續執行,可以用下面的方式配置(這個配置的 API 在 Flink 1.9 已經被標記成廢棄了)。

chkpConf.setFailOnCheckpointingErrors(false)

另外,在 Flink 1.9 引入了 Checkpoint 失敗次數容忍度的配置,默認是 0 次,即對 Checkpoint 的失敗是零容忍的,你可以通過 API 進行配置。

chkpConf.setTolerableCheckpointFailureNumber(3)

Checkpoint 的清除

Checkpoint 的初衷是進行失敗恢復,因此,當一個 Flink 應用程序停止時(比如,失敗終止、人爲取消等),它的 Checkpoint 就會被清除。但是,你可以通過開啓外化 Checkpoint 功能,在應用程序停止後,保存 Checkpoint。

chkpConf.enableExternalizedCheckpoints(ExternalizedCheckpointCleanup.RETAIN_ON_CANCELLATION)

Flink 支持兩種外化 Checkpoint:

  • DELETE_ON_CANCELLATION:當應用程序完全失敗或者明確地取消時,保存 Checkpoint。
  • RETAIN_ON_CANCELLATION:當應用程序完全失敗時,保存 Checkpoint。如果應用程序是明確地取消時,Checkpoint 被刪除。

切記:外化 Checkpoint 並不能代替 Savepoint。它們使用特定於 State Backend 的存儲格式,但是沒有伸縮性。因此,它們只能滿足應用程序失敗後的重啓,缺乏 Savepoint 的靈活性

2. Checkpoint 的配置原則

上一節介紹了 Checkpoint 的配置方法,以及 Checkpoint 時間間隔與 Checkpoint 生產時間的關係對 Flink 應用程序的影響。Checkpoint 的配置需要隨着 Flink 應用程序的不同而不同。這裏簡單介紹一下 Checkpoint 的配置原則:

  1. Checkpoint 時間間隔不易過大。一般來說,Checkpoint 時間間隔越長,需要生產的 State 就越大。如此一來,當失敗恢復時,需要更長的追趕時間。
  2. Checkpoint 時間間隔不易過小。如果 Checkpoint 時間間隔太小,那麼 Flink 應用程序就會頻繁 Checkpoint,導致部分資源被佔有,無法專注地進行數據處理。
  3. Checkpoint 時間間隔大於 Checkpoint 的生產時間。當 Checkpoint 時間間隔比 Checkpoint 生產時間長時,在上次 Checkpoint 完成時,不會立刻進行下一次 Checkpoint,而是會等待一段時間,之後再進行新的 Checkpoint。否則,每次 Checkpoint 完成時,就會立即開始下一次 Checkpoint,系統會有很多資源被 Checkpoint 佔用,而真正任務計算的資源就會變少。
  4. 開啓本地恢復。如果 Flink State 很大,在進行恢復時,需要從遠程存儲上讀取 State 進行恢復,如果 State 文件過大,此時可能導致任務恢復很慢,大量的時間浪費在網絡傳輸方面。此時可以設置 Flink 應用程序本地 State 恢復,應用程序 State 本地恢復默認沒有開啓,可以設置參數 state.backend.local-recovery 值爲 true 進行激活。
  5. 設置 Checkpoint 保存數。Checkpoint 保存數默認是 1,也就是隻保存最新的 Checkpoint 的 State 文件,當進行 State 恢復時,如果最新的 Checkpoint 文件不可用時 (比如文件損壞或者其他原因),那麼 State 恢復就會失敗,如果設置 Checkpoint 保存數 3,即使最新的 Checkpoint 恢復失敗,那麼 Flink 也會回滾到上一次 Checkpoint 的狀態文件進行恢復。考慮到這種情況,可以通過 state.checkpoints.num-retained 設置 Checkpoint 保存數。

3. 總結

Checkpoint 是 Flink 的失敗恢復機制,它的配置對於 Flink 應用程序的性能和穩定性有着至關重要的影響。Checkpoint 需要根據 Flink 應用程序的不同而進行不同的配置,根據相關配置原則,以求達到理想的配置,使 Flink 應用程序性能和穩定性最優化。

掃碼關注公衆號:冰山烈焰的黑板報
在這裏插入圖片描述

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