Flink 應用的一致性保障


應用一致性保障

在Flink中,會自動做檢查點,用於故障時恢復一個應用。在恢復時,application的state信息可以根據最近完成的檢查點進行重建,並繼續運行。不過,僅將一個application的state進行重置並不足以滿足exactly-once的保證。

為了給一個應用提供exactly-once保證,在應用根據檢查點重置state時,它的每個source connector都應該有能力將它的read position重置到做檢查點時的read position。在做一個檢查點時,source operator將它的read position也持久化,並在恢復時根據此位置進行重置。對於這類可以重置read position的source connector,比較有代表性的有:

  1. 基於文件的源:可以存儲讀文件字節流時的偏移量
  2. Kakfa:可以存儲讀入topic partition的偏移量

如果一個application從一個無法重置read position的source connector讀數據,則在故障發生並恢復時,只能提供at-most-once 的保證。

Flink的檢查點與恢復機制、結合可重置reading position的source connector,可以確保一個應用不會丟失任何數據。但是,此應用仍可能輸出同一數據兩次。因為若是應用故障發生在兩次檢查點之間,則必定會導致已經成功輸出的數據再次輸出一次。所以僅通過Flink與source connector的行為,並不足以提供端到端的exactly-once保證,即使application的state具有exactly-once的保證。

一個application若是需要提供端到端exactly-once 的保證,則需要特殊的sink connectors。對於sink connectors來說,有兩種技術可以應用於不同的場景,用於達到exactly-once的保證,分別為:idempotent writes、以transactional writes。

 

Idempotent Writes

一個idempotent 操作可被執行多次,但是僅會產生一個變化。例如向一個hashmap中插入同樣的key-value pair,這即為一個idempotent操作。因為僅有第一次操作會在hashmap中增加此條目,而之后的插入不會改變hashmap中的內容。一個非 idempotent 操作的例子如追加操作,即使是同樣的數據,每次追加都會增加一條數據。在流應用中,idempotent write是一個很有特點的操作,它們可以多次執行,但並不改變最終的結果。所以在Flink根據檢查點機制進行恢復時,可以在一定程度上緩解replay對結果造成的影響(或是沒有影響)。

需要注意的是,若是一個應用依賴於idempotent sinks,以達到exactly-once 的結果,則必須保證的是:在replay時覆蓋之前寫的結果。一般來說,只要流應用在replay時正常執行並輸出,在新的輸出覆蓋掉之前寫的結果后,即可以正常到達一致狀態。

 

Transactional Writes

第二種實現端到端exactly-once 一致性的方法是基於transactional writes。這個方法基於的想法是:僅在最近一個檢查點成功完成后,才將所有結果寫入到一個外部的sink系統。這個行為可以實現端到端exactly-once的原因是因為:在故障發生時,應用會被重置到最近的檢查點,並且在此檢查點之后,沒有任何結果被寫入到外部sink系統。但是此方法會增加延時,因為結果僅能在一個檢查點完成后才能看到。

Flink提供了兩種方式分別實現transactional sink connectors – 一個通用的 write-ahead-log(WAL
以及一個two-phase-commit(2PC)sink。WAL sink將所有result records寫入應用的state,並在它收到了一個“檢查點完成”的通知后,將結果輸出到sink 系統。因為WAL sink會將result records緩存到state backend,所以它可以用於任何sink 系統中。然而,使用此方法實現的exactly-once仍會有些代價:增加了應用的state大小,並且sink 系統需要處理突增寫入的模式。

與WAL不同的是,2PC sink需要sink system提供事務支持,或者提供模擬事務的支持。對於每個檢查點,sink首先啟動一個事務,將所有接收到的記錄添加到事務中,並將它們寫入sink系統,但是不提交(commit)。當它收到一個“檢查點完成”的通知后,它提交事務,並將結果落盤。

2PC協議集成在Flink的檢查點機制中。Checkpoint barriers便是啟動一個新事務的通知,所有operators中對於它“自身檢查點完成”的通知,即是它們的commit 投票。JobManager的對於“整個檢查點完成”的消息,即為提交事務的指示。

相對於WAL sinks,2PC sinks是基於sink 系統以及sink的實現方式,達到exactly-once的輸出保障。而 相對於WAL sink的突增寫入模式,2PC sink為持續向sink 系統寫入記錄。

下表展示的是對於不同類型的source與sink connectors,在最優的情況下是否可以達到端到端exactly-once保障的對比(根據sink的實現不同,真正的一致性可能會更差):

 

 

References

Vasiliki Kalavri, Fabian Hueske. Stream Processing With Apache Flink. 2019


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM