Memcached和Redis分布式鎖方案例項講解

2021-12-30 10:54:29 字數 1893 閱讀 6013

分布式快取,能解決單台伺服器記憶體不能無限擴張的瓶頸。在分布式快取的應用中,會遇到多個客戶端同時爭用的問題。這個時候,需要用到分布式鎖,得到鎖的客戶端才有操作許可權。

memcached 和 redis 是常用的分布式快取構建方案,下面列舉下基於memcached 和 redis 分布式鎖的實現方法。

memcached分布式鎖

memcached可以使用add命令,該命令只有key不存在時,才進行新增,或者不會處理。memcached所有命令都是原子性的,併發下add 同乙個key ,只會乙個會成功。

利用這個原理,可以先定義乙個 鎖 lockkey ,add 成功的認為是得到鎖。並且設定[過期超時] 時間,保證宕機後,也不會死鎖

在具體操作完後,判斷是否此次操作已超時。如果超時則不刪除鎖,如果不超時則刪除鎖。

偽**:

1 if (mc.add("lockkey", "value", expiredtime))

2

13 }

14 catch (exception e)

15

18

19 }redis 分布式鎖

redis沒有add 命令,但有setnx(set if not exists)若給定的key已經存在,則 setnx不做任何動作。設定成功,返回1。設定失敗,返回0。

setnx 命令不能設定過期時間,需要再使用expire 命令設定過期時間。

偽**:

int lockresult = rd.setnx("lockkey", "value");

if (lockresult == 1)

}catch (exception e)

}這種做法,有乙個很大的潛在風險。[1]得到鎖後,再執行[2] 設定過期時間。如果在這期間出現宕機,則會導致沒有設定過期時間。按redis 的預設快取過期策略,這個鎖將不會釋放,產生死鎖。

所以不推薦用這種做法,應該用其它方式來實現鎖的超時過期策略:

1:setnxvalue 值=當前時間+過期超時時間,返回1 則獲得鎖,返回0則沒有獲得鎖。轉2。

2:get獲取 value 的值 。判斷鎖是否過期超時。如果超時,轉3。

3:getset(將給定key的值設為value,並返回key的舊值),getsetvalue 值=當前時間+過期超時時間, 判斷得到的value 如果仍然是超時的,那就說明得到鎖,否則沒有得到鎖。

從2併發進到3 的操作,會多次改寫超時時間,但這個不會有什麼影響。

偽**:

string expiredtime = datetime.now.addminutes(locktimeoutminutes).tostring();

int lockresult = rd.setnx("lockkey", expiredtime);

bool getlock = false;

if (lockresult == 1)

else

}}if (getlock)

}catch (exception e)

}個人覺得這種做法,還是不完美。 

zookeeper的分布式鎖,下篇再學習**。

memcached和redis的區別

redis的作者salvatore sanfilippo曾經對這兩種基於記憶體的資料儲存系統進行過比較,總體來看還是比較客觀的,現總結如下 1 效能對比 由於redis只使用單核,而memcached可以使用多核,所以平均每乙個核上redis在儲存小資料時比memcached效能更 高。而在100k...

redis和memcached的區別 ?

redis 和 memcache 都是基於記憶體的資料儲存系統。memcached是高效能分布式記憶體快取服務 redis是乙個開源的key value儲存系統。下面我們來進行來看一下redis和memcached的區別。redis的作者salvatore sanfilippo曾經對這兩種基於記憶體...

redis和memcached的區別

相比於memcached,redis擁有更多是資料結構,所以支援更多的資料操作,redis允許的value資料結構型別有5種 string 字串 list 列表 set 集合 hash 雜湊 zset 有序集合 redis只支援單核,memcached可以使用多核,所以平均每乙個核上 redis 在...