訊息佇列的消費語義和投遞語義

2021-09-24 14:08:46 字數 2467 閱讀 9317

所謂的消費語義,指的就是如下三種情況

其實類似還有乙個投遞語義

說句實在話,其實還是老問題,只是換了一種問法!

ok,開始我們的正文

我們先做如下約定

我們先從投遞語義開始講起,因為要先把這個概念講明白了,才能講消費語義。恰巧,kafka實現了這三種語義,我們以kafka來說明。

如何保證訊息最多投遞一次?

簡單,就是我已經投出去了,收沒收到不管了,會存在訊息丟失。

我們在初始化producer時可以通過配置request.required.acks不同的值,來實現不同的傳送模式。

這裡將request.required.acks設為0,意思就是producer不等待leader確認,只管發出即可;最可能丟失訊息。如果丟了訊息,就是投遞0次。如果沒丟,就是投遞1次。符合最多投遞一次的含義。

如何保證訊息至少投遞一次?

這裡將request.required.acks設為-1。producerkafkaleader(主)節點傳送訊息後,會等follower(從)節點同步完資料以後,再給producer返回ack確認訊息。

但是這裡是有機率出現重複消費的問題的。

例如,kafka儲存訊息後,傳送ack前宕機,producer認為訊息未傳送成功並重試,造成資料重複!

那麼,在這種情況下,就會出現大於1次的投遞情況,符合至少投遞一次的含義。

如何保證訊息恰好投遞一次?

kafka在0.11.0.0版本之後支援恰好投遞一次的語義。

我們將enable.idempotence設定為ture,此時就會預設把request.required.acks設為-1,可以達到恰好投遞一次的語義。

如何做到的?

為了實現producer的冪等語義,kafka引入了producer id(即pid)和sequence number。

kafka為每個producer分配乙個pid,作為該producer的唯一標識。

producer會為每乙個維護乙個單調遞增的seq。

類似的,message queue也會為每個記錄下最新的seq。

當req_seq == message_seq+1時,message queue才會接受該訊息。因為:

這裡我們還是做乙個定義如下所示

注意了,我是以processmsg函式,即處理訊息的過程,定義為消費訊息。

如何保證訊息最多消費一次?

producer:滿足最多投遞一次的語義即可,即只管發訊息,不需要等待訊息佇列返回確認訊息。

message queue:接到訊息後往記憶體中一放就行,不用持久化儲存。

consumer:拉取到訊息以後,直接給訊息佇列返回確認訊息即可。至於後續消費訊息成功與否,無所謂的。即按照以下順序執行

consumer.poll();

consumer.commit();

processmsg(message);

如何保證訊息至少消費一次?

producer:滿足至少投遞一次語義即可,即傳送訊息後,需要等待訊息佇列返回確認訊息。如果超時沒收到確認訊息,則重發。

message queue:接到訊息後,進行持久化儲存,而後返回生產者確認訊息。

consumer:拉取到訊息後,進行消費,消費成功後,再返回確認訊息。即按照如下順序執行

consumer.poll();

processmsg(message);

consumer.commit();

由於這裡producer滿足的是至少投遞一次語義,因此訊息佇列中是有重複訊息的。所以我們的consumer會出現重複消費的情形!

如何保證訊息恰好消費一次?

在保證至少消費一次的基礎上,processmsg滿足冪等性操作即可。

如何保證冪等性操作?

老問題了,比如有狀態的訊息啊。比如唯一表啊。大家搜一搜,一大堆答案,不想重複說了。

Kafka的消費語義

at most once 最多消費一次 訊息0 1 訊息可能丟失 但是不會重複消費 log 解釋 消費者的offset已經提交,但是訊息還在處理,這個時候掛了,再重啟的時候會從上次提交的offset處消費,導致上次在處理的訊息部分丟失。at least once 至少消費1次 訊息 1 消費不可能丟...

go 型別的值語義和引用語義

go語言重大部分型別都是基於值語義,包括 1.基本型別 byte,int,bool,float32,float64,string等 2.復合型別 陣列array,結構體struct,指標pointer等 重點來了,c c 中,陣列傳遞是引用語義,但在go中,陣列和基本型別沒啥區別,都是值語義,也就是...

語義SLAM的資料關聯和語義定位(一)

語義slam和多感測器融合是自動駕駛建圖和定位部分比較熱門的兩種技術。語義slam中,語義資訊的資料關聯相較於特徵點的資料關聯有所不同。我們一般用特徵描述子的相似性來匹配和關聯不同影象中的特徵點。特徵點的描述子會受到光照 視角和感測器的影響,不太適用於大尺度長週期的任務,比如自動駕駛的高精度地圖。得...