實時處理中的 exactly once 方案具體的應用場景或者使用方法是什麼?

時間 2021-05-31 10:17:49

1樓:

Strom和JStrom提供不是exactly once,而是At-Least-Once;從字面上就可以看出來至少一次有可能會有重複的資料,這樣就違背了資料的準確性、一致性的原則。所以Strom會用在計算準確性要求不高的場景裡,比如日誌分析、人物畫像等這樣的場景,Strom的時效性還是比較認可的!

而flink,spark才是真正exactly once,正是恰好一次的處理模型可以應用各種場景來處理,例如風控處理、實時監控、電商行業的實時統計等。flink會比Spark會更好一點,他是支援了複雜的函式如視窗函式、CEP函式等等來滿足使用者的各種需求!

一般就是會出現線上作業出現Failover的時候,checkpoint儲存增量計算的啟動位點;等你處理完異常故障的時候,線上作業會從儲存的啟動位點開始恢復作業。從而保證你的增量計算不會丟、不會重複。

關於實時計算的各種業務場景架構可以私聊聯絡我!

2樓:

保證exactly-once是需要源端,streaming系統和輸出共同協作,主要的要求是

1.源端要支援重放, 比如Kafka,Amazon Kinesis

2. 中間streaming系統的容錯處理保證task只會產生exactly-once的輸出

3. 輸出端要有transactional update

下游輸出冪等的情況比較好處理,streaming系統輸出結果可以直接update

下游輸出不冪等,需要引入版本控制機制

可以參考:

High-throughput, low-latency, and exactly-once stream processing with Apache Flink - data Artisans

Mastering Apache Spark 2.0

3樓:張云聰

exactly once是指的運算元對下游產出的結果有且僅有乙份會被下游獲取

也就是說,某級運算元可能會被重複排程多次,但無論被重複執行多少遍,都保證乙份輸入有且僅有一次產出可以被下游獲取到。

不過,exactly once有乙個前提,即運算元不能自己直接與外部系統互動。

如果確實需要與外部系統互動,就需要自己做一些額外的操作才能確保exactly once。

如果做不到了exactly once,僅僅做到at least once的話,而使用者又有上述exactly once需求時,則使用者需要在資料中加上編號,需要每級運算元都自己去完成去重操作,使用上會極度複雜低效。

而做到了exactly once的系統,則除與外部系統互動的模組外,使用者都不再需要關注去重的工作。

與外部系統互動的模組,一般與外部系統的互動無非是輸入、輸出、狀態儲存三種需求。

一般而言,現代的流式計算系統,都會提供一些機制,用以給使用者提供一種與計算保證原子性的內部狀態儲存機制(我這裡把它稱為Status),它會把資料處理切割成許多輪(最小可以把一條輸入資料當做是一輪),然後每輪處理中,使用者對Status的操作,會與資料的處理保證原子性。

使用者在每輪處理前讀取Status,處理後,會更新Status,然後本輪處理返回。

某輪處理返回後,系統會去嘗試

1. 本輪內給下游產生輸出真正成功提交,以便可被下游讀取

2. 並同時持久化更新Status

3. 標記輸入資料已經處理過了,未來不會再嘗試重試

這三個操作會是乙個原子的過程,即,如果乙個操作失敗,則另外兩個也會同時失敗。這樣,就保證了無論何時,使用者收到的Status與資料一定是匹配的。

有了這樣的機制之後,輸入、輸出、狀態儲存,只要上下游系統滿足一些特性,就可以實現輸入、輸出以及外部狀態的不丟不重了。

先來考慮輸入資料:假設輸入系統是一種帶訂閱id的訂閱系統,即,訂閱系統可以提供讀取某個id起的資料這樣的介面,則每輪讀取完成後,在Status中儲存已讀取的id,下輪讀取時從該id下一位讀取就可以了。

這樣,由於id被更新與資料可被下游獲取是同乙個原子的過程,這就保證了乙份資料輸入,下游只會獲取到乙份。

再來考慮輸出資料:一般的流式計算系統中,輸出的有序性需要下游系統支援冪等的操作,然後在流式計算系統中去使用這些冪等的操作。乙個典型的場景是如果某流式系統支援Status並且流式系統保證順序的話,可以用Status為每條資料維護乙個id,下游系統就可以使用該id去重,以保證最終結果不重複。

而與外部狀態儲存的需求則更為複雜一些,一般需要進行多版本號控制,即在外部儲存中維護多個版本的狀態,然後在Status中維護版本號,如果發生故障,則從Status中獲取版本號,以便知曉自己該去讀取哪個版本的狀態。

雖然,聽起來這些很複雜,但實際上,目前的各種流式系統中,基本上都會把一些常見的輸入、輸出、外部狀態儲存需求都包裝起來,使得使用者不再需要關注前邊這些細節就可以與這些常見外部系統不丟不重的打交道(當然,你得用專用的介面而不是裸用外部系統原始介面)。

所以,總結一下就是,做到不丟不重(exactly once)也不能保證運算元不被重算,但可以保證下游收到的資料一定是不丟不重的。

4樓:劉人傑

流式計算框架的exactly once指的是最終的處理結果是exactly once的,不是說對輸入的資料只恰好處理一次。這裡以計數為例,我們說的exactly once指的是寫出的最終的結果(這裡我們假設是DB)與輸入的資料一致,一條不多一條不少。這個聽起來很容易,但是實現起來卻並不容易,因為流式計算框架通常是分布式的,而且通常有著比較複雜的topology。

在這裡我簡單描述下三種流式計算框架(storm trident, spark streaming, flink)分別是如何實現exactly once的。

首先我們來說說storm trident。因為分布式系統中隨時都可能出現機器掛掉的情況,要保證實現exactly once最基本的一點就是在掛了之後需要重試。光重試是不夠的,重試的過程中還要保證順序。

打個比方我們處理2條kafka的訊息,訊息A表示為(offset: 1, key: cnn, count:

1),訊息B表示為(offset: 2, key: cnn, count:

2)。如果不保證順序,那麼處理的流程可能是這樣的:

將A的資料存入資料庫

將B的資料存入資料庫

通知系統B處理完成

系統掛了,只能重試,由於A尚未ack,所以系統從A開始拉取,但B已經處理完成,因此無法實現exactly once

但是如果我們保證處理的順序性,那麼處理的流程就是這樣的:

將A的資料存入資料庫,並記錄下最後的offset

通知系統A處理完成

將B的資料存入資料庫,並記錄下最後的offset

通知系統B處理完成

在這種情況下如果尚未通知系統A處理完成就掛了,有2種可能:A未寫入資料庫或者A已經寫入資料庫。而這兩種情況可以根據記錄下來的最後的offset來判斷。

乙個分布式系統中如果一條一條地處理,顯然吞吐太低,嚴重浪費資源,這裡可以將一條一條改成一批一批地處理。這樣雖然比一條一條地處理好,但是面對複雜的topology,依然會嚴重浪費資源。比如我的topology需要先解析kafka裡的日誌,並提取出相應的字段,然後根據key shuffle到不同的機器上聚合然後存入到資料庫裡去。

這裡顯然只有存入資料庫的這個動作是需要按照順序一批一批處理,而前面解析日誌的部分不需要嚴格按照順序處理,因此storm trident裡的operator分為兩種,一種是有狀態的,一種是無狀態的。有狀態的處理需要嚴格保序,而無狀態的operator則不需要等待上乙個批次處理完成。這個其實與tcp中的視窗的思想有點類似。

以上就是storm trident的基本思想。因此從上面的分析可以看出,要實現exactly once的處理,輸入流需要支援回退(kafka就是乙個常用的輸入流),輸出需要支援update(比如mysql, redis),比如使用kafka作為輸出是做不到exactly once的。

spark streaming通過將輸入切分成乙個乙個的batch,在遭遇失敗的時候需要重新回放最後乙個batch,因此它要求foreach rdd的操作是冪等。看了storm trident分析的同學可能有乙個困惑:spark streaming要實現exactly once,就要保證按順序處理,它是如何做到的呢?

我們知道spark streaming的每乙個batch都會生成乙個job來處理,在內部實現中spark streaming只允許同時執行乙個job,也就是只允許同時處理乙個batch。這種做法的問題在於會嚴重浪費資源。

flink所提出的使用checkpiont方法來實現exactly once是目前我了解到的最優雅的方式。trident和spark streaming的batch方式的乙個問題在於資源的利用率。batch切小了吞吐上不去,切大了需要預分配更多的資源,而且trident基於storm原生的ack機制,所以batch還與超時的設定相關。

flink的基本思路就是將狀態定時地checkpiont到hdfs中去,當發生failure的時候恢復上一次的狀態,然後將輸出update到外部。這裡需要注意的是輸入流的offset也是狀態的一部分,因此一旦發生failure就能從最後一次狀態恢復,從而保證輸出的結果是exactly once的。因此這裡注意exactly once的條件跟storm trident相同:

輸入流要能回退到某一點,輸出要能被update。

廣告行業中的實時競價 Real Time Bidding 是什麼? 與需求方平台 Demand Side Platform 有什麼不同?

秦浪 簡單說,RTB是一種交易方式,DSP是乙個廣告主平台。1 RTB RealTime Bidding 實時競價,是一種有別於傳統的CPM CPC CPD的購買方式的廣告交易方式 2 DSP 需求方平台,是專門為廣告主提供廣告採購與廣告管理發布的平台 可以看看Google官方對於RTB的介紹 什麼...

人腦在睡夢中會對現實中即將或實時發生的場景有一定的未卜先知功能嗎?

解夢雜貨鋪周公 個人理解是潛意識在夢中把即將發生的事進行了一遍預演,至於結果一般是根據發夢者的性格和抗壓能力決定的。樂觀的人,結果都是好的。悲觀的人,結果都是壞的。 獨樹一幟 不一定。但夢境多是現實生活的反映,同時也預知未來,夢境很神秘,目前還沒有科學家研究出夢境的規律和真實性。但夢境的確可以參考生...

如何處理交易中的假突破?

steven 你要先定義什麼是真突破什麼是假突破。你認為的假突破,可能別人看來是真突破。所以問這個問題的人還沒搞懂交易並不是是與非的遊戲 叢林鳥 它山之石可以攻玉!銀行培訓員工辨別假鈔,不會拿一堆各種假鈔來學習,只學習辨別真鈔的幾個特徵!真正的突破一去不回頭,那麼好了,你還要期待那種一波三折的突破嗎...