Redis的併發競爭問題的解決方案總結【參考】

什麼是Redis的併發競爭問題

Redis的併發競爭問題,主要是發生在併發寫競爭。

考慮到redis沒有像db中的sql語句,update val = val + 10 where ...,無法使用這種方式進行對數據的更新。

假如有某個key = "price",  value值爲10,現在想把value值進行+10操作。正常邏輯下,就是先把數據key爲price的值讀回來,加上10,再把值給設置回去。如果只有一個連接的情況下,這種方式沒有問題,可以工作得很好,但如果有兩個連接時,兩個連接同時想對還price進行+10操作,就可能會出現問題了。

例如:兩個連接同時對price進行寫操作,同時加10,最終結果我們知道,應該爲30纔是正確。

考慮到一種情況:

T1時刻,連接1將price讀出,目標設置的數據爲10+10 = 20。

T2時刻,連接2也將數據讀出,也是爲10,目標設置爲20。

T3時刻,連接1將price設置爲20。

T4時刻,連接2也將price設置爲20,則最終結果是一個錯誤值20。

解決方案

方案1

利用redis自帶的incr命令,具體用法看這裏http://doc.redisfans.com/string/incr.html。

方案2

可以使用獨佔鎖的方式,類似操作系統的mutex機制。(網上有例子,http://blog.csdn.net/black_ox/article/details/48972085 不過實現相對複雜,成本較高)

方案3

使用樂觀鎖的方式進行解決(成本較低,非阻塞,性能較高)

如何用樂觀鎖方式進行解決?

本質上是假設不會進行衝突,使用redis的命令watch進行構造條件。僞代碼如下:

複製代碼

watch price

get price $price

$price = $price + 10

multi

set price $price

exec

複製代碼

解釋一下:

watch這裏表示監控該key值,後面的事務是有條件的執行,如果從watch的exec語句執行時,watch的key對應的value值被修改了,則事務不會執行。

具體看Redis的事務功能詳解這篇文章裏的watch命令介紹。

方案4

這個是針對客戶端來的,在代碼裏要對redis操作的時候,針對同一key的資源,就先進行加鎖(java裏的synchronized或lock)。

方案5

利用redis的setnx實現內置的鎖。

 

 

基於redis+lua的分佈式鎖客戶端:Redision

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章