redis使用消息隊列的場合?

學習redis中,碰到幾個概念性的問題,在高並發中,如果使用普通的mysql,會存在衝突死鎖,而redis的消息隊列可以避免這種情況,那麼消息隊列是怎麼做到的?請說下執行過程。


題主的問題描述的不是很清楚,看題主是剛學習Redis,那應該是想了解為什麼並發插入數據下Redis的性能會比Mysql高,至於消息隊列,應該是說Redis沒有鎖等待的問題,不知道是否理解正確,先按這個問題來解釋下,若有出入,歡迎修正。

先來看看Redis和Mysql的數據存儲,Mysql是需要落到磁碟的,而Redis的數據是寫入內存即表示成功,至於持久化是非同步刷到磁碟的(雖然可以同步刷到磁碟,但那樣效率和Mysql沒有多大差別)。內存的讀寫性能大概是磁碟的1-2個數量級,所以這裡從本質上決定了Redis的讀寫性能高於Mysql。

再來看看Redis和Mysql的存儲模型,Redis是Key-Value的,Mysql是關係型資料庫,Key-Value的插入和查找基本都是O(1)的複雜度,而關係型資料庫會涉及到索引的查找和插入,是對數級的複雜度(InnoDB,有索引),但這個在InnoDB下並不是太大的問題,因為Mysql是多線程的,並且引入了MVCC(多版本並發控制),插入的時候不會鎖表,還能更好的利用多核,所以不會因為並發在插入時造成太大的性能問題。

然後看看樓主提出的並發問題,應該指的是Mysql使用MyISAM時,數據的插入都會鎖表,但並不是死鎖(死鎖是互相持有對方所需資源等待對方釋放),只是這個時候針對單表的插入Mysql的多線程並不能發揮優勢,所有的數據只能一條一條插入,所以相對於Redis,最終的性能差異在磁碟和演算法本身的複雜度上。

最後說說題主說的Redis的消息隊列,題主的意思應該是Redis的線程模型是單線程的,所有的命令都是在一個命令隊列里,一個接著一個執行,並不能並發執行。這種模型的最大優勢是編程簡單,並不會為並髮帶來優勢,相反,不能利用多核是其最大的弊病,這種模型基本都是利用NIO來解決並發問題。當然,Redis這樣也就不會造成死鎖,因為沒有資源的競爭,但Mysql的死鎖是可以通過良好的設計避免的,所以,消息隊列並不是Redis性能高的原因。

謝謝,希望對大家有幫助。


瀉藥

mysql大並發下的插入死鎖是可以通過調整SQL和mysql配置避免的。

消息隊列的模式一般都是內部維護了一個自增mutex(互斥量,一種輕量級的鎖),mysql的非表鎖auto incement insert就是用的這種方式。


單線程,原子操作, 不存在這個問題, 一個請求執行完才進行下一個,完全沒交叉關聯


MySQL的寫操作會鎖表,大量並發請求時尤其突出;

Redis可以應對高並發場景,是因為它的讀寫請求均是單線程機制,不存在並發問題。而且Redis是基於內存的,讀寫速度也比MySQL快得多;


Redis服務端一個實例是單線程處理所有的客戶端請求的,不存在並發、鎖之類的問題。

一個伺服器可以啟動多個實例,目前新版支持集群了。

但是仍然存在很多客戶端同時訪問一個實例的情況, 這個沒辦法,單線程模式,那些客戶端只能排隊。


阻塞隊列


推薦閱讀:

redis+mysql有幾種用法?
redis的安裝和分散式配置簡潔教程
求指教學習redis源碼的方法?
集群環境中資料庫與緩存的三板斧

TAG:MySQL | Redis | 消息隊列 |