RabbitMQ 冪等性概念及業界主流解決方案

 

RabbitMQ 冪等性概念及業界主流解決方案

1、什麼是冪等性

能夠參考數據庫樂觀鎖機制,好比執行一條更新庫存的 SQL 語句,在併發場景,爲了性能和數據可靠性,會在更新時加上查詢時的版本,而且更新這個版本信息。可能你要對一個事情進行操做,這個操做可能會執行成百上千次,可是操做結果都是相同的,這就是冪等性。html

2、消費端的冪等性保障

在海量訂單生成的業務高峯期,生產端有可能就會重複發生了消息,這時候消費端就要實現冪等性,這就意味着咱們的消息永遠不會被消費屢次,即便咱們收到了同樣的消息。redis

業界主流的冪等性有兩種操做:算法

1.惟一 ID + 指紋碼 機制,利用數據庫主鍵去重數據庫

2.利用redis的原子性去實現
 緩存

3、惟一 ID + 指紋碼 機制

你們確定懂惟一 ID 的,就很少說了,爲何須要指紋碼呢?這是爲了應對用戶在一瞬間的頻繁操做,這個指紋碼多是咱們的一些規則或者時間戳加別的服務給到的惟一信息碼,它並不必定是咱們系統生成的,基本都是由咱們的業務規則拼接而來,可是必定要保證惟一性,而後就利用查詢語句進行判斷這個id是否存在數據庫中。架構

好處就是實現簡單,就一個拼接,而後查詢判斷是否重複。併發

壞處就是在高併發時,若是是單個數據庫就會有寫入性能瓶頸高併發

解決方案 :根據 ID 進行分庫分表,對 id 進行算法路由,落到一個具體的數據庫,而後當這個 id 第二次來又會落到這個數據庫,這時候就像我單庫時的查重同樣了。利用算法路由把單庫的冪等變成多庫的冪等,分攤數據流量壓力,提升性能。工具

4、利用 redis 的原子性去實現

相信你們都知道 redis 的原子性操做,我這裏就不須要過多介紹了。性能

使用 redis 的原子性去實現須要考慮兩個點

一是 是否 要進行數據落庫,若是落庫的話,關鍵解決的問題是數據庫和緩存如何作到原子性? 數據庫與緩存進行同步確定要進行寫操做,到底先寫 redis 仍是先寫數據庫,這是個問題,涉及到緩存更新與淘汰的問題

二是若是不落庫,那麼都存儲到緩存中,如何設置定時同步的策略? 不入庫的話,可使用雙重緩存等策略,保障一個消息副本,具體同步可使用相似 databus 這種同步工具。

5、怎麼保證消息隊列消費的冪等性?

先大概說一說可能會有哪些重複消費的問題。

首先就是好比rabbitmq、rocketmq、kafka,都有可能會出現消費重複消費的問題,正常。由於這問題一般不是mq本身保證的,是給你保證的。而後咱們挑一個kafka來舉個例子,說說怎麼重複消費吧。

kafka實際上有個offset的概念,就是每一個消息寫進去,都有一個offset,表明他的序號,而後consumer消費了數據以後,每隔一段時間,會把本身消費過的消息的offset提交一下,表明我已經消費過了,下次我要是重啓啥的,你就讓我繼續從上次消費到的offset來繼續消費吧。

可是凡事總有意外,好比咱們以前生產常常遇到的,就是你有時候重啓系統,看你怎麼重啓了,若是碰到點着急的,直接kill進程了,再重啓。這會致使consumer有些消息處理了,可是沒來得及提交offset,尷尬了。重啓以後,少數消息會再次消費一次。

其實重複消費不可怕,可怕的是你沒考慮到重複消費以後,怎麼保證冪等性。

給你舉個例子吧。假設你有個系統,消費一條往數據庫裏插入一條,要是你一個消息重複兩次,你不就插入了兩條,這數據不就錯了?可是你要是消費到第二次的時候,本身判斷一下已經消費過了,直接扔了,不就保留了一條數據?

一條數據重複出現兩次,數據庫裏就只有一條數據,這就保證了系統的冪等性

冪等性,我通俗點說,就一個數據,或者一個請求,給你重複來屢次,你得確保對應的數據是不會改變的,不能出錯

 

6、其實仍是得結合業務來思考,我這裏給幾個思路:
(1)好比你拿個數據要寫庫,你先根據主鍵查一下,若是這數據都有了,你就別插入了,update一下好吧

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

(3)好比你不是上面兩個場景,那作的稍微複雜一點,你須要讓生產者發送每條數據的時候,裏面加一個全局惟一的id,相似訂單id之類的東西,而後你這裏消費到了以後,先根據這個id去好比redis裏查一下,以前消費過嗎?若是沒有消費過,你就處理,而後這個id寫redis。若是消費過了,那你就別處理了,保證別重複處理相同的消息便可。

還有好比基於數據庫的惟一鍵來保證重複數據不會重複插入多條,咱們以前線上系統就有這個問題,就是拿到數據的時候,每次重啓可能會有重複,由於kafka消費者還沒來得及提交offset,重複數據拿到了之後咱們插入的時候,由於有惟一鍵約束了,因此重複數據只會插入報錯,不會致使數據庫中出現髒數據

如何保證MQ的消費是冪等性的,須要結合具體的業務來看

相關文章
相關標籤/搜索