天天看點

Flink最佳實踐(一)流式計算系統概述

前言

傳統的批處理擁有巨大 吞吐量 的優勢,但是随之而來的是極其 高延遲 的缺陷。

随着大資料系統的不斷發展,傳統的批處理已然無法全部滿足對 時效性 要求愈加嚴苛的業務需求。

為了适應逐漸變得 「實時」 的年代,大資料系統架構也由簡單的批處理轉向批流混合的Lambda架構,最後可能會逐漸演變成隻有流計算的 高精準高時效 的Kappa架構。

無論是看起來像是過渡期産物的批流混合,還是感覺像是 「終結者」 的純流式計算,都離不開最核心的計算元件:流式計算系統。

做為當今最火熱的流式計算引擎,Flink以其卓越的性能、高度可信的正确性等種種特性收獲了大量粉絲。

本文作為學習Flink的前置知識,将從 時域、視窗、時間推理工具、強正确性方案 等方面讨論流式計算系統的核心概念,為初學者揭開其神秘面紗。

從本文中你将了解到:

  • 流式計算系統是如何做到批處理的 準确性,進而達到可以和批處理平起平坐、互相代替的地步。
  • 流式計算系統是如何做到遊刃有餘地 處理現實世界中雜亂的事件流,做到批處理無法完成的事情,進而實作對批處理的反超。

值得注意的是,本文并不涉及任何具體的流式計算引擎,這意味着本文中的所有概念在幾乎所有流式計算系統中都是通用的(Flink、SparkStreaming、StructuredStreaming等),因為大部分流式計算系統的抽象模型大體一緻。

一、術語與解釋

在進行正文描述之前,我們先規定流式計算系統中的基本術語,正文内容将會基于這些術語進行讨論。

1.1 無限資料

無限資料是一種不斷增長的,本質上 無限的資料集。

也常被稱為 流資料,但是我們這裡隻用 無限資料 這個概念來描述它。

因為流資料語義上 與流式計算強制綁定,但是實際上無限資料也經常使用批處理工具來計算,比如在一個源源不斷增長的資料集上進行 T+1天 的計算。

資料是一個無限增長的資料集,但是處理工具是批處理,每次隻處理前一天的資料。

如果這裡用流資料來描述可能經常會讓人誤以為其是一個流式計算系統處理的資料集。

1.2 資料亂序

資料亂序是指 服務端接收的資料順序并不是用戶端資料産生的順序 的現象。

網際網路中的資料流并 不會按照人們事先預想的順序進行傳輸,這是現實生活中的真實展現。

不同的用戶端按順序發出的資料包可能因為各種原因的影響,服務端接受到的時候有極大的可能順序是和用戶端發送順序不一緻的,這就是資料的亂序。

1.3 無限資料處理

批處理

批處理是一種通過将無限資料 劃分成最終一緻的有限批次資料 的處理方式。

如前文描述,T+1的批處理将一個無限資料集按天劃分成一批批的資料集,每個批次中的資料都是 不可變的、有限的。

現實中有很多用批處理系統來處理無限資料的場景,對于亂序的資料,批處理通過 拉長時間視窗 的做法來保持 結果的正确性。

比如T+1每天一個時間視窗,那麼除非資料延遲超過一天,否則人們認為這個批次處理的結果是正确的、沒有遺漏的:

  • 一天之内的所有資料隻會被處理一次,結果準确。
  • 一天之内的所有一起被處理,不存在資料亂序問題。

當然這種做法也并不是百分百正确,在劃分時間界限的附近仍然可能存在亂序的資料,時間視窗越長正确性越高。

流處理

流處理是一種 持續的資料處理模式、設計用于無限資料處理的執行引擎。

傳統的流處理器經常存在系統不可靠、資料易丢失、結果不準确等缺陷,導緻了曾經的一段時間内,流就代表了 「約等于」 的處理結果。

但是随着流處理器的不斷發展,現代化的流處理器依托 State、Checkpoint、WAL 等機制支援 準确一次,基本都具備了與批處理平起平坐 正确性:

一些先進的流處理器還會提供讓系統可以遊刃有餘地 應對真實世界中錯亂資料 的工具,這就是 超越批處理的時間推理能力:

  • 能夠處理亂序資料流,超越批處理的能力
  • 使得流計算可以獲得比批處理事實 更準确的結果

1.4 準确一次

準确一次 是事件在流處理器中 隻被準确地處理一次 的描述。

本文中的 準确一次 ,與經常被提及的 精準一次、Exactly Once 等概念描述上有點差別,精準一次表示事件在流處理器中 隻被精确地處理了一次,不多不少正好一次。

但是現實生活中,能夠真正做到精準一次的效果是非常難的。

即使資料源、計算引擎、存儲系統都能夠支援精準一次的語義,但是在某些複合名額的計算過程中(如5分鐘内的PV),計算系統進行到一半因為特殊原因奔潰後重新開機,雖然其将自動将上次計算過程産生的副作用消除,并從資料源重新拉取資料進行計算并輸出,看起來就像什麼問題都沒發生過一樣。

但是對于上次到本次計算過程中的某些資料來說,它們确确實實 被計算了兩次,隻是第一次計算廢棄且始終保證最終結果是正确的,看起來就像隻被處理了一次一樣。

是以本文中用 準确一次 的概念來描述這個語義,對于資料結果來說,事件在流處理器中 隻被準确的處理了一次。

二、時域

時域是學習流處理系統的第一門課,大多數從事批處理系統相關工作的同學在第一次接觸流處理系統時經常會有疑惑或者概念混淆,其原因大部分是因為沒有 時域 的概念。

在批處理系統中,時域可能就隻是一個劃分處理資料集的工具,并沒有其他特殊之處。

但是在流處理系統中,時域是一個最基本的概念,流處理系統的所有計算過程都将圍繞着時域來建構。

2.1 時間類别

流處理與批處理最大的不同在于流進行中對時間類别劃分比批處理更豐富,且用不同時間類别計算出的資料,結果與意義可能全然不同。

事件時間

事件時間是 事件真實發生的時間。

由于資料亂序的原因,服務端收到資料時的時間和事件本身的時間可能是相差極大的。

正是因為這種差異,服務端做基于事件時間的計算是 最複雜的,需要對亂序的資料流做處理以 「還原」 真實世界的情況,需要依賴一定的資料緩存。

達到時間

達到時間是 系統接收到事件的時間,即服務端接收到事件的時間。

達到時間比較少被使用。

處理時間

處理時間是 系統開始處理到達事件的時間。

在某些場景下,處理時間等于達到時間。

因為處理時間 沒有亂序 的問題,是以服務端做基于處理時間的計算是比較簡單的,無遲到與亂序資料。

2.2 造成時間亂序的因素

從時間類别的劃分上來看,隻有事件時間會有亂序的困擾。

在最理想的狀态下,事件時間=達到時間=處理時間,在批處理系統中的簡單粗暴預設三者相等,是以批處理沒有亂序的煩惱。

但是在流處理系統中,要達到這種理想狀态 幾乎是不可能的,事件時間與處理時間總是會有誤差,如下圖所示。

Flink最佳實踐(一)流式計算系統概述

現實生活中造成時間亂序的原因有很多,基本都是不可避免的,比如以下幾種因素:

  • 共享資源限制,如網絡擁塞,網絡分區或在非專用環境中共享CPU
  • 軟體因素,如分布式系統的複雜邏輯、資源競争等
  • 資料本身的特性,包括 key 的分布、吞吐的差異、亂序
  • 軟體使用時的場景限制

等等。

舉一個簡單的場景,在聯網的遊戲程式中,遊戲結束時會将本地的資料上傳到伺服器進行排名、得分等結果統計。

某個比較倒黴的哥們,可能在地鐵或者隧道等信号不好的場所中,資料發送的過程可能因為外部環境因素而發生意外情況(信号不好、甚至無信号)導緻延遲發送甚至無法發送。

在這種情況下,可能原本應該于9點發送的資料包,服務端到10點多才收到,甚至永遠收不到。

那麼服務端在基于事件時間統計9-10點時間段内遊戲的排行時,因為該使用者資料遲遲未到,馬上計算的話結果将是不正确的(因為少了一個使用者的資料),而選擇等待的話沒人知道該使用者的資料何時到來。

這就是基于事件時間計算時,時間亂序帶來的困擾。

而如果基于處理時間計算,那麼事情将變得十分簡單,隻需要處理9-10點範圍内服務端收到的所有資料即可,但是輸出的結果并不是真正正确的結果。

2.3 基于時域的操作

流處理器定義完時域之後,接着需要定義在時域之上的操作,所有流處理器的操作都可以分為兩種類型:與時間無關的和與時間有關的。

與時間無關的操作

這種類型的操作往往是最簡單的,因為不管是什麼類别的時間,都對這類操作 沒有任何影響。

比如 過濾、轉換 等簡單映射,來一條就可以處理一條,處理完一條就可以直接輸出,和時間沒有任何關系。

與時間有關的操作

基于各類時間的視窗處理 是流處理器中主要的與時間有關的操作。

三、視窗

3.1 視窗的本質

對擁有時域概念的資料流做操作,就必定會用到視窗這個工具,它的本質就是将無限資料集 沿着時間的邊界切分成有限資料集。

在批進行中,視窗就是定義的多久處理一次,每次處理的資料就是根據這個視窗時間(一般都是處理時間)劃分出來的有限資料集。

在流進行中,根據不同的時間類别,劃分出來的視窗性質也不同:

基于處理時間劃分

  • 優點
    • 簡單,不需要根據時間 shuffle 資料,每個時間視窗内的資料都是 完整的
    • 容易判斷完整性,不需要處理遲到的資料
  • 缺點
    • 資料不準确,無法反映真實世界的資料情況

基于事件時間劃分

    • 能夠反映出真實世界 最準确的資料
    • 需要 還原并處理遲到的資料
    • 遲到的資料到來前 需要緩存更多資料
      • 需要根據不同的時間視窗 shuffle 資料
      • 延遲更高
    • 系統的完整性問題無法保證

3.2 視窗的類别

不論是基于事件時間的視窗還是基于處理時間的視窗,都會有不同的視窗類型可以使用,常見的如:固定視窗、滑動視窗、會話視窗 等。

固定視窗

按照固定的時間片劃分資料流,将資料流 分割成具有固定大小的片段。

如圖所示:

Flink最佳實踐(一)流式計算系統概述

假設

window-size=1

那麼window1、window2、window3等各個視窗的大小永遠固定是1,且 各個視窗不會重疊也不會有間隙。

固定視窗是最簡單也是最常見的視窗類型。

滑動視窗

在固定視窗的基礎上,滑動視窗增加了 滑動步長 的定義。

滑動視窗由 固定視窗長度、視窗滑動步長 确定,如下圖所示:

Flink最佳實踐(一)流式計算系統概述

window-size=1 & window-slide=0.5

那麼表示 視窗長度為1機關且每0.5個機關就向前滑動一個新視窗。

滑動視窗經常被用來統計諸如 每5分鐘統計過去10分鐘的通路量 的需求,視窗長度為10分鐘,滑動步長為5分鐘。

滑動視窗的視窗長度和滑動步長的關系如下:

  • 視窗長度>滑動步長,則視窗重疊
  • 視窗長度=滑動步長,則等同于固定視窗,沒有視窗重疊
  • 視窗長度<滑動步長,有一些資料就無法配置設定到視窗中,視窗之間将出現空隙

會話視窗

和固定視窗、滑動視窗不一樣,會話視窗沒有固定的視窗大小定義。

會話視窗的大小由 使用者活動事件頻率 決定,長度不能被事先定義而取決于實際資料。

比如Web伺服器中Session的概念,使用者在一定時間内沒有後續活動的話Session将會過期,如果使用者一直保持活躍的操作,那麼Session将一直保留。

會話視窗的劃分也類似Session的定義,如下圖所示:

Flink最佳實踐(一)流式計算系統概述

每個使用者都可能産生多個會話視窗,每個會話視窗的大小取決于該使用者是否持續産生活動事件。

會話視窗是批處理引擎不擅長處理的類型,通常用于 分析一段時間内的使用者行為。

四、時間推理工具

有了時域和視窗的概念後,基本上我們就擁有了上手流處理程式開發的條件了。

但是此時我們仍然無法了解到,先進的流處理器核心思想到底先進在哪裡?它是如何做到和批處理器一樣的正确性甚至擁有超越批處理的能力?

本節先從 時間推理工具 的角度來讨論流處理器擁有的 能夠正确處理亂序資料的超能力,使其成為超越批處理的事實标準。

在本節中,我們會嘗試在這三個問題的回答上更好的了解流處理器的時間推理工具:

  1. 流處理器的計算結果是什麼?
  2. 流處理器會在事件時間的哪個位置計算?
  3. 流處理器會在處理時間的什麼時候觸發?

4.1 計算結果是什麼?

這個問題也是經典批處理需要回答的問題,即想得到什麼樣的資料運算結果,将會被定義在程式代碼中。

比如簡單的轉換操作、複雜的視窗操作,以及是否做聚合、join等,比較具有代表性的計算結果有 計算總和、建構直方圖、訓練模型 等。

比較簡單的問題,可以了解為使用者的業務需求。

4.2 在事件時間的哪個位置計算?

從事件時間的次元上看,流處理器執行代碼擷取計算結果時,必定需要 取某個事件時間範圍内的資料進行計算。

假設用一坐标軸表示無限資料,坐标軸上 以事件時間為x軸、以處理時間為y軸 畫圖,我們可以得到:

Flink最佳實踐(一)流式計算系統概述

以x軸上的事件時間點做切分,将會把坐标圖(無限資料) 劃分成一片片有界限的資料集。

是不是很眼熟?這就是視窗的作用,将無限資料集 沿着時間的邊界切分成有限資料集。

我們在事件時間的次元上定義視窗,就是定義了各個資料片的 資料區域與位置,流資料将會 按照自身攜帶的事件時間被劃分到指定的時間視窗中,流處理器将會取其中某個位置的資料進行計算。

如果是與時間無關的操作則在事件時間的任意位置都能計算。

在事件時間的哪個位置計算 由視窗決定,視窗定義了事件時間的計算位置(區域)。

用視窗在事件時間的次元上定義好計算位置後,流處理器還需要在處理時間的次元上知道,什麼時候觸發計算。

4.3 在處理時間的什麼時候觸發?

有些同學到這裡會出現一些概念上的混淆,我們不是已經定義過事件時間了嗎,為什麼還要定義處理時間?

事件時間和處理時間兩個管的次元不一樣,事件時間是定義 切分資料集的時間邊界,而 程式真正要觸發計算 需要在處理時間上定義。

可以了解為 到達某個處理時間後,程式取指定事件時間範圍内的資料進行計算。

在事件時間的次元上定義了一個個的資料視窗,流資料将會按照自身攜帶的事件時間被劃分到指定的時間視窗中。

我們還需要定義在處理時間的什麼時候觸發計算,也就是說,什麼時候我們才能說某個視窗的資料已經都到了,是個完整的資料集,可以進行計算了。

隻有事件時間的流進行中 缺乏對視窗資料完整性的判斷。

是以在處理時間的次元上,流處理器需要額外借助一些工具輔助程式 判斷某個事件時間視窗是否已經完整,以及是否觸發計算。

4.3.1 Watermark

Watermark 是描述 「事件時間」的輸入完整性 的概念,是系統根據目前處理資料的 「事件時間」 判斷 「處理進度和完整性」 的工具。

在事件時間次元上劃分的各個視窗原本都是 未封閉的,表示 資料還沒全部達到。

Watermark 的作用就是給各個視窗 「蓋上蓋子」,使其成為一個封閉的視窗,表示資料已經全部達到。

如下圖所示:

Flink最佳實踐(一)流式計算系統概述

在圖中,Watermark 出現表示目前事件時間視窗已完整。

那麼使用者如何去定義 Watermark ,程式又是怎麼判斷 Watermark 到了需要關閉視窗進行計算呢?

我們通過一個例子來說明 Watermark 的作用。

設事件時間視窗大小 size=5s,在事件時間的次元上可以劃分以下視窗:

視窗序号 事件時間範圍
0-5 20:10:00 - 20:10:05
6-10 20:10:06 - 20:10:10

定義資料攜帶的Watermark為 目前事件時間-2s,(Flink中通過SourceFunction的emitWatermark設定,每條資料都會攜帶一個Watermark)。

資料接收情況如下:

資料序号 所屬的視窗 攜帶的Watermark 目前的Watermark 備注
第1條 20:10:00 20:09:58 第一條直接取攜帶的WK為系統的WK
第2條 20:10:01 20:09:59 攜帶的WK比目前WK大,取攜帶的WK為目前的WK
第3條 20:10:02 同上
第4條 攜帶的WK比目前WK小,故繼續使用目前WK
第5條 20:10:05 20:10:03 同第3條
第6條 20:10:06 20:10:04
第7條 20:10:08 此時 WK已經>=事件時間視窗(0-5),表示第1個視窗已經完整,WK為20:10:06,在目前處理時間次元上「畫上」水位線,表示在這之前的資料已經都達到了,可以觸發計算
第8條 這是一條延遲「很久」的資料,0-5的視窗已經關閉

可以看到,每條資料過來,都會更新程式中最新的 Watermark。

在第7條資料到達時,其攜帶的 Watermark 已經 超過了 0-5 這個視窗的邊界,那麼此時我們可以認為 0-5 這個視窗的所有資料已經達到,可以進行計算。

使用者可以根據業務與資料情況自定義每條資料應該攜帶怎樣的 Watermark,而系統接收到資料時,根據目前 Watermark 是否超出某事件時間的視窗邊界來判斷該事件時間視窗是否完整。

那麼使用者該 如何定義具體的 Watermark 的值 呢。

下面我們來介紹兩種定義 Watermark 的方式,來幫助使用者設定 Watermark 的值。

完美式

完美式的 Watermark 是在使用者 完全了解輸入資料的前提下,建構出完美的水位線,不會有資料超過水位線。

也就是說,在完美式的 Watermark 中,不會有任何資料被遺漏,所有資料在完美式的 Watermark 下都能夠準時達到。

這是最完美的一種情況,但是真實業務場景中使用完美式的 Watermark 往往要付出比較大的代價。

因為其要兼顧所有資料,注定了 Watermark 會在比較晚的時間後才能到來。

比如 目前事件時間-10m,在視窗大小為10s的程式中,這意味着第一個視窗要 等到10分鐘之後的資料出現 才可能會被關閉。

但是正因為較大的 Watermark 值,隻要某視窗中遲到的資料在其視窗邊界10m之内達到,都是不會被遺漏的。

  • 缺點:延遲太高、需要緩存的資料量太大。
  • 優點:資料完整性高。

啟發式

在實際應用中,完全了解輸入資料是不切實際的,且資料的亂序延遲現象總比使用者想象的要糟糕。

因而,完美式的 Watermark 往往是一個比較大的值,但在某些高時效性要求的系統中,完美式的 Watermark 帶來的高延遲往往是不能被接受的。

是以我們需要另外一種啟發式的 Watermark,其 能夠在保持低延遲的同時,最大可能的保持視窗的完整性。

啟發式的 Watermark 一般都是使用者根據資料情況,比如 分區、分區内排序、檔案增長率等 提供盡可能準确的進度估計,設定一個較為理想的值。

  • 缺點:會存在小部分資料是延遲到達的,會損失部分資料。
  • 優點:低延遲。

4.3.2 Trigger

有了 Watermark 之後,雖然使用者可以以此來判定 視窗是否完整,但視窗完整并不意味着要觸發計算,隻能說滿足了觸發計算的條件。

真正決定在處理時間的什麼時候觸發計算的是 Trigger,其是描述 何時「計算視窗」的機制 。

Trigger 的觸發計算信号可以從以下幾個次元來定義:

  • 事件時間次元:按照事件時間視窗完整觸發計算,即 Watermark 出現。
  • 處理時間次元:按照固定的處理時間觸發計算,是固定的、不延遲的,定期輸出結果。
  • 元素計數次元:視窗累計固定數量後觸發計算
  • 帶标記信号或其他依賴其他觸發器:接受到EOF等事件時觸發計算

觸發器可以是簡單的觸發器,即以上任意一種,也可是是複合的觸發器,即以上 多種觸發條件的組合。

  • 重複觸發器:适用于處理時間以提供固定更新。
  • AND觸發器:多觸發器「與」組合。
  • OR觸發器:多觸發器「或」組合。
  • 序列觸發器:自觸發器按照預定義的順序依次觸發。

有了 Trigger 的定義之後,我們再來看看 完美式Watermark 和 啟發式Watermark 中的缺點如何通過 Trigger 的組合來避免。

對于完美式的Watermark,可以通過 視窗+固定處理時間 多重觸發器組合的方式,在 Watermark 到來之前,提前或周期觸發計算并輸出,達到低延遲的效果,Watermark 到來後也會觸發一次計算。

對于啟發式的Watermark,通過 視窗+LastestDelay 多重觸發器組合的方式,定義 LastestDelay 的大小,可以延遲計算處理遲到資料。LastestDelay 為最大允許的延遲時間,可以在視窗關閉之後将遲到的資料劃入特定空間中等待補充計算。但是 LastestDelay 本身也有大小限制,仍然可能遺漏極端延遲的資料。

由于 Watermark 本身存在嚴重的缺陷,資料完整性與低延遲不可兼得,且在極端情況下仍然 不可保證所有資料都被處理到。是以,隻根據 Watermark 來決定是否開始處理資料是比較不精準的。

通過 Trigger 的定義可以做到讓事件時間視窗盡可能的完整,且延遲盡可能的低。

現在,我們來總結一下關于流處理器的時間推理工具的三個問題:

    • 由業務邏輯決定
    • 由視窗來劃分時間邊界與定義資料位置
    • 由 Watermark 定義事件時間視窗的完整性
    • 由 Trigger 決定處理時間上觸發的條件

現在,你知道流處理器的時間推理工具是什麼了嗎?

五、保持強正确性的工具

時間推理工具讓流處理器站在了批處理器的之上,使其能夠真正地處理現實世界中的亂序問題。

但是流處理器中還有一個問題未解決,那就是 正确性如何保證?

在批處理器中,同一批資料、同一個程式重複計算的結果應該是 始終一緻 的,這樣一來即使批處理器執行過程中挂了,使用者也可以通過一些補數的手段重跑,以 保證最後結果的正确性。

那麼對于流處理器來說,流處理器執行過程中當機重新開機之後 是否能夠保持結果資料的正确性與一緻性 是現代流處理器的基本素質。

抛開時間推理工具不說,能夠保持強正确性的流處理器可以直接取代系統中的批處理器,而不會出現結果不一緻的情況。

下面我們來讨論現代流處理器中,常見的保持強正确性的工具。

5.1 State

State 即為狀态,流處理器中常用來緩存視窗資料、程式運作時狀态、資料源偏移量等資訊。

可以簡單了解為流處理器中的一塊記憶體區域(或者使用了外部資料庫來存儲)。

為什麼流處理器需要 State?

  1. 計算需求
    • 流處理器要求資料實時産出,不延遲
    • 需要使用狀态緩存視窗資料
  2. 準确一次語義需求
    • 流處理器要求資料不丢失不重複,準确一次
    • 需要使用狀态記錄資料源、計算程式、輸出端等鍊路資訊,可以及時恢複
  3. 容錯需求
    • 流處理器要求7 * 24小時運作,高可靠
    • 需要狀态來提供故障恢複與容災的資料支援
    • 橫向擴容時根據狀态中的資料進行配置設定管理

使用者的計算需求中經常使用到狀态的場景:

  • 通路量統計
  • 去重
  • 視窗計算
  • 通路曆史資料
  • 機器學習與深度學習

狀态的存儲實作一般有以下幾種:

  • 基于記憶體
  • 基于嵌入式資料庫
  • 基于外部共享檔案系統

State不僅給使用者提供了高性能實作計算需求的方案,也是流處理器保持強正确性的工具之一。

5.2 Checkpoint

除了 State 之外,流處理器還需要一種 可以将 State 中的資料進行備份與恢複的機制 才能保證 任何時刻流處理器的當機重新開機都不會影響最後的正确結果。

這種機制就是 Checkpoint(分布式全域一緻快照),其包含流處理器全鍊路中的資訊:

  • Source的offset資訊
  • 各個節點上的State資訊
  • Sink的事務資訊

通過 Checkpoint,流處理器可以定時的備份系統中的狀态與資料,并在必要時刻提供幫助。

以 Flink 中 Checkpoint 為例,其一個生成周期如下:

  • 在資料源設定一系列的checkpoint barrier
    • ck barrier n 與 ck barrier n-1 之間的資料都屬于目前的checkpoint
    • ck barrier n經過第一個op時向ck後端 儲存source offset
  • 經過後續每個op時
    • ck barrier n到達之前,會用input buffer緩存之前的資料集
    • ck barrier n到達表示目前所屬的所有資料已經處理完成并更新狀态
    • 将目前op的狀态儲存至ck後端
  • ck barrier n經過sink op時向ck後端确認ck完整性

Checkpoint 生成之後,如果需要狀态恢複與故障容錯,則所有節點從hdfs中讀取 「上次的資料位置」 來重置消息隊列,并從 「上次的狀态」 開始重新計算。

Checkpoint 機制對資料源有一定要求,即資料源的必要條件為 支援重放。

通過 State 與 Checkpoint 的結合使用,流處理器可以保持結果資料的強一緻性。

  • 定時制作分布式快照,對程式狀态進行備份
  • 發生故障時将程式恢複到最近一次成功的checkpoint,從那個點開始處理

問題:如何保證端到端的準确一次?

從以上我們讨論 State、Checkpoint 等機制來看,它們隻能保證在 流處理器内部的準确一次。

Sink在使用了外部存儲的情況下,在本次 Checkpoint 和上次 Checkpoint 之間源源不斷寫資料到外部存儲中。

即使流處理器當機從恢複點重新開機了,那麼 之前處理的資料實際上已經寫到了外部存儲中,這種情況下就不能稱之為端到端的準确一次了。

借助可重放的資料源、State/Checkpoint的流處理器,我們可以保證資料源到計算引擎的準确一次,那麼使用外部存儲的情況下如何保證端到端的準确一次?