在很多應用場景中,分布式系統的可靠性保障尤其重要。比如電商平台中,客戶的購買請求需要可靠處理,不能因為節點故障等原因丟失請求;比如告警系統中,產生的核心告警必須及時完整的知會監控人員,不能因為網路故障而丟失資料。
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()
public2、 boltvoid
ack(object msgid)
public
void
fail(object msgid)
這段**是bolt訊息處理傳送**,我們詳細看一下標紅**。
publicvoid
execute(tuple input)
collector.ack(input);}
outputcollector.emit(collectionanchors, listtuple) 中tuple表示傳送的子訊息,anchors表示子訊息的父節點。這段**既傳送了子訊息,又把子訊息錨定到了訊息樹上。上述例子中,相當於把訊息msg4 劉備,msg5關羽,msg6張飛錨定到訊息msg2 劉備 關羽 張飛上。
outputcollector.ack(tuple input)表示回答訊息處理完成。上述例子中,相當於確認msg2 劉備 關羽 張飛處理完成。
下面**會在訊息處理成功或失敗後呼叫。
public三、訊息重發機制可以看到,一條訊息從spout傳送後,會產生一棵訊息樹,只有當訊息樹中的所有訊息都被確認後(ack),storm才認為訊息處理完成。void
ack(object msgid)
public
void
fail(object msgid)
**上可以輕易看出,我們只需要指定根節點訊息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 族的一些函式,開始時總搞不明白訊息傳送到 去了,誰去處理,什麼時候處理。下面是問題解答。至於開始的幾個疑問,我是這樣理解的。訊息傳送出去,就相當於馬上要被處理了。就像進地鐵一樣,已經站到了進站的佇列中 假...