Storm訊息可靠處理機制

2022-07-10 11:24:10 字數 2641 閱讀 1711

在很多應用場景中,分布式系統的可靠性保障尤其重要。比如電商平台中,客戶的購買請求需要可靠處理,不能因為節點故障等原因丟失請求;比如告警系統中,產生的核心告警必須及時完整的知會監控人員,不能因為網路故障而丟失資料。

storm訊息可靠性保障是storm核心特性之一,其中訊息樹的跟蹤管理機制是storm核心演算法之一,本文將詳細介紹storm訊息可靠處理機制。我們從storm初探中的例子入手。

一、訊息處理流程

1、 spout節點

(1) spout接收到乙個文字訊息;

msg1

劉備 關羽 張飛

曹操 郭嘉 荀彧

(2) spout把文字訊息拆分為2個行字串訊息,並把2個訊息傳送給namessplit bolt節點。

2、 namessplit bolt節點

(1) namessplit bolt接收到兩個行字串訊息;

msg2 劉備 關羽 張飛

msg3 曹操 郭嘉 荀彧

(2) namessplit bolt把2個行字串訊息拆分為6個名字訊息,傳送給helloworld bolt節點;

(3) namessplit bolt確認,msg2、msg3處理完成。

3、 helloworld bolt節點

(1) helloworld bolt接收到6個名字訊息;

msg4 劉備

msg5 關羽

msg6 張飛

msg7 曹操

msg8 郭嘉

msg9 荀彧

(2) helloworld bolt sayhello;

(3) helloworld bolt確認,msg4、msg5、msg6、msg7、msg8、msg9處理完成。

二、關鍵**

1、 spout

下面**表示spout節點傳送訊息,訊息繫結到messageid上,這裡的messageid可以看做上述例子中的msg1,tuple可以看做上述例子中的msg2或msg3。

public

void

nexttuple()

下面**會在訊息處理成功或失敗後呼叫。

public

void

ack(object msgid)

public

void

fail(object msgid)

2、 bolt

這段**是bolt訊息處理傳送**,我們詳細看一下標紅**。

public

void

execute(tuple input)

collector.ack(input);}

outputcollector.emit(collectionanchors, listtuple) 中tuple表示傳送的子訊息,anchors表示子訊息的父節點。

這段**既傳送了子訊息,又把子訊息錨定到了訊息樹上。上述例子中,相當於把訊息msg4 劉備,msg5關羽,msg6張飛錨定到訊息msg2 劉備 關羽 張飛上。

outputcollector.ack(tuple input)表示回答訊息處理完成。上述例子中,相當於確認msg2 劉備 關羽 張飛處理完成。

下面**會在訊息處理成功或失敗後呼叫。
public

void

ack(object msgid)

public

void

fail(object msgid)

三、訊息重發機制可以看到,一條訊息從spout傳送後,會產生一棵訊息樹,只有當訊息樹中的所有訊息都被確認後(ack),storm才認為訊息處理完成。

**上可以輕易看出,我們只需要指定根節點訊息id(即spout接收到的訊息id),其他訊息id系統會自動生成。同時,我們只需要確認非根節點訊息處理完成。

實際上,spout或者bolt每傳送一條訊息,訊息便會儲存到kestrel佇列中,bolt每接收到一條訊息,kestrel便會標記這條訊息在處理中(pengding),直到該條訊息被確認處理完成,kestrel才把它移除出佇列。

bolt訊息處理過程中,發生異常或者超時,kestrel會把該條訊息從處理中狀態重新置為待處理狀態,等待storm下一次排程處理。

四、訊息樹管理演算法

可以看到,spout每處理乙個訊息,就會生成一棵訊息樹,如果storm儲存每棵訊息樹每個節點的狀態,記憶體很快便會耗盡,顯然是不可取的。

實際上,storm僅僅採用20位元組管理一棵訊息樹,資料結構如下:

treeid|

treeid用於區分不同的訊息樹(和**中指定的根節點id一一對應),則用於訊息樹節非根點異或計算。

每生成乙個64位msgid,則與異或計算一次,直到該訊息確認處理完成後,再與異或計算一次。(異或計算結果為新的值)

==0時,表示訊息處理完畢。(一目了然,在此不再證明)

handler訊息處理機制

handler主要用來更新ui 因為涉及到執行緒安全,android必須在ui執行緒 即主線程 裡才能更新ui,在其他執行緒裡更新ui會報錯,而一些耗時的操作又必須通過開啟新的執行緒來執行,這就要用到handler來傳遞訊息了。在主線程中建立乙個handler的例項,並重寫handlermessag...

非同步訊息處理機制

借鑑 為什麼不能在子執行緒更新ui?1 ui是非執行緒安全的,主線程和子執行緒同時更新ui的話會導致錯誤,如ui錯亂之類的。2 ui更新是很耗效能的,更別說為了執行緒安全加鎖了,最簡單的方法就是更新ui的操作放到乙個執行緒中,即主線程 handler機制 looper 維持乙個thread物件以及m...

Handler訊息處理機制

剛開始接觸android,邊學習邊做筆記,希望大家多指正。經常在 中看到sendmessage 族的一些函式,開始時總搞不明白訊息傳送到 去了,誰去處理,什麼時候處理。下面是問題解答。至於開始的幾個疑問,我是這樣理解的。訊息傳送出去,就相當於馬上要被處理了。就像進地鐵一樣,已經站到了進站的佇列中 假...