日常工作中總是會有高併發的場景,需要實現鎖機制來保證序列性,接下來我們一步一步實現乙個 單機redis下基本可靠的redis鎖(ps: 如果是redis集群的話,就存在主從切換鎖失效的問題,解決這個問題的話就比較麻煩了,這裡不做討論,現有的解決方案有redlock,大家可以看下它的實現原理)
redis鎖 第一版(php實現):
//加鎖public
function lock($key
)
$res = $redisconnect->setex($key
);
return (bool)$res
; }
//解鎖
public
function unlock($key
)
版本一的問題:如果加鎖之後程序中斷,就會死鎖
版本二,設定鎖的超時時間來解決版本一問題
publicfunction lock($key, $seconds
)
$res = $redisconnect->setex($key, $seconds, 1);
return (bool)$res
; }
//解鎖
public
function unlock($key
)
第二版的問題:設定了超時時間,但是有一種場景,a加鎖之後到了超時時間a還沒執行完,這個時候鎖失效 b可以再加鎖,然後a執行完畢 就會把b加的鎖刪除。 說到底問題出在了,不同的程序加的鎖是沒區別的。
版本三: 解決版本二的問題 可以在設定鎖的時候 加入乙個唯一置,在刪除鎖的時候,如果發現唯一值已經不是設定的了,就不刪除改鎖了。這裡有乙個問題就是刪除的時候需要判斷是否是唯一值,然後再決定刪除與否,這個動作本身就不是原子操作的,所以要封賬乙個lua命令來實現原子性。
publicfunction lock($key, $value, $seconds
)
/*** 解鎖
** @param string $key
* @return bool
*/public
function unlock($key, $value
)
public
function
delifexist()
public
function setnxex($key, $value, $exp
)
public
function
main()
//buy goods
$this->unlock($key, $uniqid
); }
這裡還是沒有完全解決問題,因為a事務執行超時的過程中,鎖超時後被b拿到,那麼整個流程b是不知道和a併發了的,還是沒有做到百分百的完備。
演算法進化歷程之「水壺問題」
演算法進化歷程之 水壺問題 問題描述 假設給定了n個紅色的水壺和n個藍色的水壺,它們的形狀和尺寸都不相同。所有紅色水壺中所盛水的量都不一樣,藍色水壺也是一樣。此外,對於每個紅色的水壺,都有乙個對應的藍色水壺,兩者所盛的水量是一樣的。反之亦然。你的任務是將所盛水量一樣的紅色水壺和藍色水壺找出來。為了達...
演算法進化歷程之剪刀石頭布
演算法進化歷程之剪刀石頭布 小美 阿福,你玩過剪刀石頭布遊戲嗎?阿福 這算什麼問題?誰還能沒玩過剪刀石頭布?要知道它可是一種世界聞名的猜拳遊戲。它起源於中國,然後傳到日本 朝鮮等地,隨著亞歐 的不斷發展它傳到了歐洲,到了近現代逐漸風靡世界。簡單明瞭的規則 石頭打剪刀,布包石頭,剪刀剪布 使得剪刀石頭...
Redis 分布式鎖進化史(解讀 缺陷分析)
redis分布式鎖進化史 近兩年來微服務變得越來越熱門,越來越多的應用部署在分布式環境中,在分布式環境中,資料一致性是一直以來需要關注並且去解決的問題,分布式鎖也就成為了一種廣泛使用的技術,常用的分布式實現方式為redis,zookeeper,其中基於redis的分布式鎖的使用更加廣泛。但是在工作和...