storm是怎麼實現高效率的可靠性的?

2021-06-17 00:14:53 字數 2411 閱讀 2537

理解storm的可靠性的最好的方法是來看看tuple和tuple樹的生命週期,當乙個tuple被建立,不管是spout還是bolt建立的,它會被賦予乙個64位的id,而acker就是利用這個id去跟蹤所有的tuple 的。每乙個tuple知道它的祖宗的id(從spout發出來的那個tuple的id),每當你新發射乙個tuple,它的祖宗id都會傳給這個新的tuple。所以當乙個tuple 被ack的時候,它會發乙個訊息給acker,告訴它這個tuple樹發生了怎麼樣的變化。具體來說就是:它告訴acker:我呢已經完成了,我有這些兒子tuple,你跟蹤一下他它吧。下面這個圖演示了c被ack了之後,這個tuple樹所發生的變化。

關於storm怎麼跟蹤tuple還有一些細節,前面已經提到過了,你可以自己設定你的topology裡面有多少個acker。而這又給我們帶來乙個問題,當乙個tuple需要ack的時候,它到底選擇哪個acker來傳送這個資訊呢?

storm使用一致性雜湊來把乙個spout-tuple-id對應到acker,因為每乙個tuple知道它所有的祖宗tuple-id,所以它自然可以算出要通知哪個acker來ack。(這裡所有的祖宗是指這個tuple所對應的所有的根tuple。這裡注意因為乙個 tuple 可能存在於多個tuple樹,所以才有所有一說)

storm的另乙個細節是acker是怎麼知道每乙個spout tuple應該交給哪個task來處理。當乙個spout發射乙個新tuple,它會簡單的發乙個訊息給乙個合適的acker,並且告訴acker它自己的id(taskid),這樣storm就有了taskid-tupleid的對應關係。當acker發現乙個樹完成處理了,它知道哪個task傳送成功的訊息。

acker task並不是顯式的跟蹤tuple 樹。對於那些有成千上萬個節點的tuple樹,把這麼多的tuple資訊都跟蹤起來會耗費太多的記憶體。相反, acker用了一種不同的方式,使得對於每個spout tuple 所需要的記憶體量恆定的(20 bytes),這個跟蹤演算法是storm 如何工作的關鍵,並且也是它的主要突破。

既然你已經理解了storm的可靠性演算法,讓我們一起過一遍所有可能的失敗場景,並看看storm在每種情況下是怎麼避免資料丟失的。

1.對由於應的task掛掉了,乙個tuple沒有被ack:storm的超時機制在超時之後會把這個tuple標記為失敗,從而可以重新處理。

2.acker掛掉了:這種情況下由這個acker所跟蹤的所有spout tuple都會超時,也就會被重新處理 

3. spout掛掉了: 在這種情況下給spout傳送訊息的訊息源負責重新傳送這些訊息。比如kestrel和rabbitmq在乙個客戶端斷開之後會把所有」處理中「的訊息放回佇列。

就像你看到的那樣, storm的可靠性機制是完全分布式的, 可伸縮的並且是高度容錯的。

調整可靠性 (tuning reliability)

acker task是非常輕量級的, 所以乙個topology裡面不需要很多acker。你可以通過strom ui(id: -1)來跟蹤它的效能。 如果它的吞吐量看起來不正常,那麼你就需要多加點acker了。

如果可靠性對你來說不是那麼重要 — 你不太在意在一些失敗的情況下損失一些資料, 那麼你可以通過不跟蹤這些tuple樹來獲取更好的效能。不去跟蹤訊息的話會使得系統裡面的訊息數量減少一半, 因為對於每乙個tuple都要傳送乙個ack訊息。並且它需要更少的id來儲存下游的tuple, 減少頻寬占用。

有三種方法可以去掉可靠性。第一是把config.topology_ackers 設定成 0. 在這種情況下, storm會在spout發射乙個tuple之後馬上呼叫spout的ack方法。也就是說這個tuple樹不會被跟蹤。

第二個方法是在tuple層面去掉可靠性。 你可以在發射tuple的時候不指定messageid來達到不跟粽某個特定的spout tuple的目的。

最後乙個方法是如果你對於乙個tuple樹裡面的某一部分到底成不成功不是很關心,那麼可以在發射這些tuple的時候unanchor它們。 這樣這些tuple就不在tuple樹裡面, 也就不會被跟蹤了。

怎麼才能提高效率

最近一直迷上工作效率的這個問題了,遇到問題時,不能盲目的去想解決方法,而是先確認下使用場景,了解後,看下是不是自己理解錯誤 然後再提出自己的想法,而且自己首先必須要有清晰的思路,要不然,是一堆的問題。其實提高工作效率,就是為了更好的享受生活,你無法忍受,每天都在公司加班,而且 加班還是因為他人的緣故...

遮蔽字的實現(高效率)

select message replace message,shieldname,left len shieldname from tblshieldinfo nolock where shieldstatus t insert into remark info movieid,remarkid,...

LeetCode系列 高效率實現LFU

lfu least frequently used,最近最少使用演算法 一種常見的快取演算法。思想 如果乙個資料在最近一段時間很少被訪問到,那麼可以認為在將來它被訪問的可能性也很小。因此,當空間滿時,最小頻率訪問的資料最先被淘汰。lfu演算法描述 設計一種快取結構,該結構在構造時確定大小,假設大小為...