1. 程式人生 > >流處理系統中的“Exactly Once”語義保證

流處理系統中的“Exactly Once”語義保證

前言

最近在學習一些流處理相關的知識,對比與筆者接觸比較多的離線處理系統,實時流處理的有些地方還是比較有意思的。在這裡面,最常被人提到的詞應該是“Exactly Once”語義 ,在工作面試中,如果做過實時流系統,肯定免不了被問到“xx框架是如何做到Exactly Once的”?筆者最近在閱讀Spark Streaming的官方文件中,提到了這一點,於是來做個小小的總結歸納。如果感興趣的同學,請繼續往下閱讀。

語義定義

在流處理系統中,我們對應資料記錄的處理,有3種級別的語義定義,以此來衡量這個流處理系統的能力。

  • At most once(最多一次)。每條資料記錄最多被處理一次,潛臺詞也表明資料會有丟失(沒被處理掉)的可能。
  • At least once(最少一次)。每條資料記錄至少被處理一次。這個比上一點強的地方在於這裡至少保證資料不會丟,至少被處理過,唯一不足之處在於資料可能會被重複處理。
  • Exactly once(恰好一次)。每條資料記錄正好被處理一次。沒有資料丟失,也沒有重複的資料處理。這一點是3個語義裡要求最高的。

基本語義

上一節介紹的語義是比較寬泛意義上的語義,這裡我們再細分下里面的語義操作。比如說,我們可以把一個記錄處理操作再劃分為下面3個子操作:

  • 接收資料的操作。從資料來源接收資料的操作。
  • 轉換處理資料的操作。在這裡面數據會被事先定義好的各種操作語義所處理。
  • 輸出資料操作。將處理好後的結果資料輸出到外部系統檔案系統,或資料集等等。

為什麼這裡筆者要提到上面涉及到的更細粒度級別的操作呢?其實在流處理過程中,失敗現象就可能發生在上面3個步驟中的任何一步。如果要拿最高標準“Exactly Once”標準來看,我們要達到的理想效果應該是:

  • 資料只被處理過一次,這裡面可以包括曾經處理失敗,然後再讀取原始資料進行處理。
  • 對於一個原始資料,我們保證最後結果資料輸出是一致的,我們並不是說輸出操作只是一次執行的。

所以從這裡面我們可以看出,要想達到最高的“Exactly Once”標準,中間的處理操作是最最關鍵的。因為它會有各種意外情況發生。

“Exactly Once”的重要保證:輸入資料來源的可依賴性

因為資料在處理過程中有可能會有各種情況發生,所以這裡的一個必要前提保證是:原始資料的可依賴性,或者是可訪問性。簡單的用一句話來說,就是資料處理失敗了,我還能夠訪問到原始輸入數,然後再執行處理操作。所以歸結為一個本質問題:操作的“Exactly Once”語義問題實質上是輸入資料來源的可依賴程度。

這裡我們將焦點轉向輸入資料來源上,輸入資料來源可以分為以下2種。

基於檔案系統的資料來源

資料從檔案中讀取而來,因為檔案本身存在於已經本身具備容錯能力的檔案系統(比如HDFS),所以我們可以認為這樣的資料來源是可以支援“Exactly Once”語義的,因為任何的資料處理失敗恢復都可以從原始檔案系統中進行資料的再次讀取。

基於外部接收器的資料來源

基於外部接收器的資料來源指的是我們的資料從外部系統中(比如說Kafka)讀取過來的。像這類情況,同樣地,我們要分這些接收資料器是可信賴的還是不可信賴的。

  • 可信賴的接收器。接收器收到資料後並且在多個節點做了replica副本操作,然後確認回覆給資料來源,之後出現失敗情況時資料來源就不會重發資料給接收器物件。否則,接收資料來源在接收器重啟的時候,會重發資料給接收器物件。
  • 不可信賴的接收器。這種接收器不發任何確認回覆訊息給資料來源,這就有資料丟失的可能性了,當worker節點掛掉的時候。

以上就是筆者簡單學習總結的內容了,希望對對此感興趣的同學有幫助。

參考資料