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