checkpoint是啥
簡單點(diǎn)說,就是將正在運(yùn)行的任務(wù)的狀態(tài)保存下來。這個(gè)狀態(tài)包括任務(wù)中每個(gè)算子的state,緩存的數(shù)據(jù)(比如processFunction)等。可以保存在hdfs,磁盤等。
為什么需要checkpoint
當(dāng)flink的任務(wù)或者機(jī)器掛掉了,重新啟動(dòng)任務(wù)時(shí)需要將任務(wù)恢復(fù)到原來的狀態(tài)。當(dāng)然這個(gè)恢復(fù)程度可以由你自己定,比如excatly-once,at-least-once等。
checkpoint 如何做到excatly-once?
以下場景選至《Flink基礎(chǔ)教程》

上圖中的場景表示:
數(shù)據(jù)流:<word,time> ,根據(jù)word分區(qū),統(tǒng)計(jì)word的總次數(shù)。

當(dāng)flink的數(shù)據(jù)源處理到ckpt時(shí),他會(huì)將當(dāng)前數(shù)據(jù)源的offset落盤。

當(dāng)map算子接受到ckpt時(shí),會(huì)將該算子的狀態(tài)(中間結(jié)果)落盤,此時(shí)的中間結(jié)果為 b 的總數(shù)為5,c 的總數(shù)為1。

次數(shù)處理c的算子實(shí)例掛掉了,任務(wù)需要重新啟動(dòng)?;謴?fù)過程如下

ckpt之前的數(shù)據(jù)不會(huì)被重放,數(shù)據(jù)源會(huì)從位置1,2,3重放,也就是說ckpt后面三個(gè)元素會(huì)被重放,此時(shí)算子的中間狀態(tài)(<b,5>,<cm1>)也會(huì)被恢復(fù)。
聰明的同學(xué)可能會(huì)想到,這樣做map算子雖然可能多次接收到同一個(gè)數(shù)據(jù),但是其邏輯是正確的,所以flink內(nèi)部確實(shí)實(shí)現(xiàn)的excatly-once。 但是,試想一個(gè)場景,如果map中每次的中間結(jié)果都會(huì)落盤,那拓?fù)渲貑r(shí),map會(huì)接收到重復(fù)數(shù)據(jù),也就意味著數(shù)據(jù)庫會(huì)出現(xiàn)相同的操作。這是不行的,所以說光靠flink內(nèi)部的exactly-once是不行滴。也需要端到端的保證,那么如何保證flink到存儲(chǔ)介質(zhì)的excatly-once語義呢,大體有兩種方案:
- sink緩存數(shù)據(jù),也等到接受到ckpt時(shí)一次性輸出。
- 每次都輸出,提供類似事務(wù)回滾的機(jī)制。
熟悉數(shù)據(jù)庫事務(wù)的同學(xué),應(yīng)該會(huì)聯(lián)想到兩種事務(wù)隔離級(jí)別和上面一一對(duì)應(yīng):
- read-commit
- read-uncommit
本篇沒有涉及到具體的細(xì)節(jié),以下是我學(xué)習(xí)時(shí)遇到的問題:
- 每一個(gè)算子的實(shí)例都會(huì)接受到ckpt,那當(dāng)前算子應(yīng)該是等到所有實(shí)例都接受到了才會(huì)觸發(fā)ckpt。
- 上游算子的ckpt已經(jīng)觸發(fā)了,如果下游還沒接受到就任務(wù)重啟了,那豈不是這部分?jǐn)?shù)據(jù)下次就不會(huì)重現(xiàn)了。(應(yīng)該是等最后一個(gè)算子接收到了ckpt,本次ckpt才算數(shù))