訊息中介軟體(二)之 kafka簡述

2021-09-18 08:07:57 字數 2950 閱讀 5412

kafka的高可用性

kafka乙個最基本的架構認識:多個broker組成,每個broker是乙個節點;你建立乙個topic,這個topic可以劃分為多個partition,每個partition可以存在於不同的broker上,每個partition就放一部分資料。

這就是天然的分布式訊息佇列,就是說乙個topic的資料,是分散放在多個機器上的,每個機器就放一部分資料。

實際上rabbitmq之類的,並不是分布式訊息佇列,他就是傳統的訊息佇列,只不過提供了一些集群、ha的機制而已,因為無論怎麼玩兒,rabbitmq乙個queue的資料都是放在乙個節點裡的,映象集群下,也是每個節點都放這個queue的完整資料。

kafka 0.8以前,是沒有ha機制的,就是任何乙個broker宕機了,那個broker上的partition就廢了,沒法寫也沒法讀,沒有什麼高可用性可言。

kafka 0.8以後,提供了ha機制,就是replica副本機制。每個partition的資料都會同步到結他機器上,形成自己的多個replica副本。然後所有replica會選舉乙個leader出來,那麼生產和消費都跟這個leader打交道,然後其他replica就是follower。寫的時候,leader會負責把資料同步到所有follower上去,讀的時候就直接讀leader上資料即可。只能讀寫leader?很簡單,要是你可以隨意讀寫每個follower,那麼就要care資料一致性的問題,系統複雜度太高,很容易出問題。kafka會均勻的將乙個partition的所有replica分布在不同的機器上,這樣才可以提高容錯性。

這麼搞,就有所謂的高可用性了,因為如果某個broker宕機了,沒事兒,那個broker上面的partition在其他機器上都有副本的,如果這上面有某個partition的leader,那麼此時會重新選舉乙個新的leader出來,大家繼續讀寫那個新的leader即可。這就有所謂的高可用性了。

寫資料的時候,生產者就寫leader,然後leader將資料落地寫本地磁碟,接著其他follower自己主動從leader來pull資料。一旦所有follower同步好資料了,就會傳送ack給leader,leader收到所有follower的ack之後,就會返回寫成功的訊息給生產者。(當然,這只是其中一種模式,還可以適當調整這個行為)消費的時候,只會從leader去讀,但是只有乙個訊息已經被所有follower都同步成功返回ack的時候,這個訊息才會被消費者讀到。

如何保證訊息不被重複消費啊(如何保證訊息消費時的冪等性)?

(1)比如你拿個資料要寫庫,你先根據主鍵查一下,如果這資料都有了,你就別插入了,update一下好吧

(2)比如你是寫redis,那沒問題了,反正每次都是set,天然冪等性

(3)比如你不是上面兩個場景,那做的稍微複雜一點,你需要讓生產者傳送每條資料的時候,裡面加乙個全域性唯一的id,類似訂單id之類的東西,然後你這裡消費到了之後,先根據這個id去比如redis里查一下,之前消費過嗎?如果沒有消費過,你就處理,然後這個id寫redis。如果消費過了,那你就別處理了,保證別重複處理相同的訊息即可。

如何保證訊息的可靠性傳輸(如何處理訊息丟失的問題)?

這個丟資料,mq一般分為兩種,要麼是mq自己弄丟了,要麼是我們消費的時候弄丟了。

kafka

1)消費端弄丟了資料

唯一可能導致消費者弄丟資料的情況,就是說,你那個消費到了這個訊息,然後消費者那邊自動提交了offset,讓kafka以為你已經消費好了這個訊息,其實你剛準備處理這個訊息,你還沒處理,你自己就掛了,此時這條訊息就丟咯。

這不是一樣麼,大家都知道kafka會自動提交offset,那麼只要關閉自動提交offset,在處理完之後自己手動提交offset,就可以保證資料不會丟。但是此時確實還是會重複消費,比如你剛處理完,還沒提交offset,結果自己掛了,此時肯定會重複消費一次,自己保證冪等性就好了。

生產環境碰到的乙個問題,就是說我們的kafka消費者消費到了資料之後是寫到乙個記憶體的queue裡先緩衝一下,結果有的時候,你剛把訊息寫入記憶體queue,然後消費者會自動提交offset。然後此時我們重啟了系統,就會導致記憶體queue裡還沒來得及處理的資料就丟失了。

2)kafka弄丟了資料

這塊比較常見的乙個場景,就是kafka某個broker宕機,然後重新選舉partiton的leader時。大家想想,要是此時其他的follower剛好還有些資料沒有同步,結果此時leader掛了,然後選舉某個follower成leader之後,他不就少了一些資料?這就丟了一些資料啊。

生產環境也遇到過,我們也是,之前kafka的leader機器宕機了,將follower切換為leader之後,就會發現說這個資料就丟了,所以此時一般是要求起碼設定如下4個引數:

給這個topic設定replication.factor引數:這個值必須大於1,要求每個partition必須有至少2個副本。

在kafka服務端設定min.insync.replicas引數:這個值必須大於1,這個是要求乙個leader至少感知到有至少乙個follower還跟自己保持聯絡,沒掉隊,這樣才能確保leader掛了還有乙個follower吧。

在producer端設定acks=all:這個是要求每條資料,必須是寫入所有replica之後,才能認為是寫成功了。

在producer端設定retries=max(很大很大很大的乙個值,無限次重試的意思):這個是要求一旦寫入失敗,就無限重試,卡在這裡了。

我們生產環境就是按照上述要求配置的,這樣配置之後,至少在kafka broker端就可以保證在leader所在broker發生故障,進行leader切換時,資料不會丟失。

3)生產者會不會弄丟資料

如果按照上述的思路設定了ack=all,一定不會丟,要求是,你的leader接收到訊息,所有的follower都同步到了訊息之後,才認為本次寫成功了。如果沒滿足這個條件,生產者會自動不斷的重試,重試無限次。

訊息中介軟體 kafka入門

訊息中介軟體有 activemq,rabbitmq,rocketmq,kafka,一般在 rabbitmq 和 kafka 間進行選擇 activemq 在別處看的,說沒有經過大規模吞吐的測試,社群不活躍 rocketmq 社群有黃掉的風險,碰到問題容易找不到技術資料 kafka 社群活躍度很高 在...

kafka與rabbitmq訊息中介軟體

kafka與rabbitmq xmind 思維導圖 axure 原型設計 一 rabbitmq集群 1.1普通集群 rabbitmq 每個節點上有乙個broker,每個broker負責本機上佇列的維護,並且borker之間可以互相通訊。集群中有兩個佇列a和b,每個佇列都分為master queue和...

訊息中介軟體

1.訊息的優先順序 2.訊息排序 3.訊息過濾 4.訊息持久化 5.訊息重試 6.事務的支援 7.broker滿 生產者,佇列,消費者 訊息佇列的優點 1 解耦2 非同步訊息,系統響應 在jms中,有兩種訊息模型 點對點模式和發布訂閱模式。1.在點對點模式中 有三種角色 1 訊息佇列,傳送者,接受者...