消息隊列如果持久化到資料庫的話,相對於直接操作資料庫有啥優勢?

Activemq可以將消息持久化到Mysql中。未被取走的消息存在Mysql中,消息被取走後,會從Mysql中刪除。Mysql中保存的是消息的副本呢還是消息本身?如果是消息本身的話,那豈不是相當於直接進行資料庫讀寫操作了?


之前因為知乎內部的需求做過一些調研,如果沒弄錯的話,應該是這樣的:ActiveMQ 的消息是有存儲在內存中的(至少當前需要處理的消息是在內存里),可以設置一個閾值,超過的部分消息不保留在內存里而是只保留在持久層,但這部分消息訪問的時候延遲會很高。消息如果是持久化到 MySQL,MySQL 中當然就有完整的消息內容。不太理解你說的「副本」是指什麼。

至於說這樣做和直接訪問 MySQL 有什麼區別……區別還是很大。首先 MySQL 做消息的分發之類的非常不方便,基本上你要自己實現一套消息的分發邏輯,而這部分本來 ActiveMQ 已經給你做好了;而是如果你自己輪訓 MySQL 的話顯然對性能和負載都不好,而 ActiveMQ 可以避免這個問題,降低對 MySQL 的壓力。最後 MySQL 只是眾多持久層中的一種,業務需求變化或者性能問題時你可以繼續用 ActiveMQ,只需要更換持久層即可,如果你直接用 MySQL 當消息隊列用就沒有這個靈活性了。

另外推薦一篇文章 5 subtle ways you"re using MySQL as a queue, and why it"ll bite you 意思很簡單,就是不要使用關係型資料庫作為消息隊列或者消息隊列的持久層。

最後吐槽一下,ActiveMQ 是個非常笨重的怪物,如果業務需求可以用其他更簡單的工具實現,不推薦使用 ActiveMQ.


Mysql中保存的是消息的副本呢還是消息本身?如果是消息本身的話,那豈不是相當於直接進行資料庫讀寫操作了?.....

1.即時通信IM 或 微博等消息,是消息主題已經發到伺服器了,那麼用戶就無法再修改了。

2.信息主題可修改場景,如BLOG或論壇回帖等,是很多少把文字主題發給用戶,只是標題,URL而已....且修改不影響

只知道我們曾經做SNS的Feeds及阿里旺旺,是直接存儲副本信息,也即一個消息的唯一ID值而已....

至於消費發出去之後,不是直接DELETE而是UPDATE,並且採用冷熱數據的做法,也即把冷數據從當下表中移出去....大家可以考慮採用分區表的做法...


MQ的作用很多,典型作用:

1、削峰填谷:如果短時間內要處理的業務量大於資料庫的服務能力,則可能會卡死資料庫;使用MQ可以慢慢處理。

2、非同步化:如果處理的工作非常耗時,則RPC的請求一直halt,對系統性能是個很大影響,發到MQ上,直接繼續處理其他請求,則是一個更好的選擇。

3、解耦:系統直接不像是RPC那些直接依賴了,不管有多少系統,都跟MQ打交道即可。

4、負載均衡:如果一台機器處理消息不夠及時,可以多上幾台機器做消息消費。

另外,感覺題主對ActiveMQ持久化到MySQL有一些誤解。

1、如果指的是ActiveMQ配置文件里制定用jdbcPersistenceAdapter,這樣是當消息是持久化的時候,消息的openwire序列化成的二進位數據,存入MySQL的ActiveMQ_MSGS表中的一個blob欄位了。這個消息,你可以看做是send的消息的副本的二進位序列化數據。

2、如果指的是消息被消費以後,作為數據再應用程序的代碼里被寫入到MySQL,則參見上面的作用。

對於第一種理解,你可以看做是Quartz和Spring Batch的區別。

直接存數據到MySQL,這樣對於如果一次沒有發成功怎麼辦,處理數據失敗了怎麼辦,超時了怎麼辦,要不要重新發送,不同類型的數據怎麼不同對待,怎麼保證不同應用去到的數據是不同的,等等,如果你在資料庫的基礎上實現了這些策略,實際上你就實現了一個基於資料庫的消息隊列。

實際上,在MQ出現之前,大家使用文件系統、socket、內存、資料庫等多種方式來在系統之間共享數據。後來RPC和MQ出現了,現代化的分散式技術的兩塊基石就此建立起來。後端技術世界就有了如今金碧輝煌的大廈。

MQ、RPC從理論上講,都是屬於EIP的範疇,這個回答里的所有觀點,在《Enterprise Integration Patterns》中都有討論。


推薦閱讀:

時間序列數據的存儲和計算 - 開源時序資料庫解析
分散式關係型資料庫 TiDB 正式發布 RC2 版
原諒我這麼幼稚,所以才會喜歡你這麼久 #MySQL#
MySQL學習筆記(一)表類型的選擇

TAG:資料庫 | 消息隊列 | ActiveMQ |