這個圖,其實很清晰了,假設訂單系統部署兩台機器上,不同的使用者都要同時買10臺iphone,分別發了乙個請求給訂單系統。
接著每個訂單系統例項都去資料庫里查了一下,當前iphone庫存是12臺。
倆大兄弟一看,樂了,12臺庫存大於了要買的10臺數量啊!
於是乎,每個訂單系統例項都傳送sql到資料庫裡下單,然後扣減了10個庫存,其中乙個將庫存從12臺扣減為2臺,另外乙個將庫存從2臺扣減為-8臺。
現在完了,庫存出現了負數!淚奔啊,沒有20臺iphone發給兩個使用者啊!這可如何是好。
乙個鎖key,同一時間只能有乙個客戶端拿到鎖,其他客戶端會陷入無限的等待來嘗試獲取那個鎖,只有獲取到鎖的客戶端才能執行下面的業務邏輯。
大家可以順著上面的那個步驟序號看一遍,馬上就明白了。
從上圖可以看到,只有乙個訂單系統例項可以成功加分布式鎖,然後只有他乙個例項可以查庫存、判斷庫存是否充足、下單扣減庫存,接著釋放鎖。
釋放鎖之後,另外乙個訂單系統例項才能加鎖,接著查庫存,一下發現庫存只有2臺了,庫存不足,無法購買,下單失敗。不會將庫存扣減為-8的。
當然有啊!比如悲觀鎖,分布式鎖,樂觀鎖,佇列序列化,非同步佇列分散,redis原子操作,等等,很多方案,我們對庫存超賣有自己的一整套優化機制。
但是前面說過了,這篇文章就聊乙個分布式鎖的併發優化,不是聊庫存超賣的解決方案,所以庫存超賣只是乙個業務場景而已。
1、在分布式系統環境下,乙個方法在同一時間只能被乙個機器的乙個執行緒執行;
2、高可用的獲取鎖與釋放鎖;
3、高效能的獲取鎖與釋放鎖;
4、具備可重入特性;
5、具備鎖失效機制,防止死鎖;
6、具備非阻塞鎖特性,即沒有獲取到鎖將直接返回獲取鎖失敗。
class
redismutexlock
/** * 獲得鎖,如果鎖被占用,阻塞,直到獲得鎖或者超時。
* -- 1、如果 $timeout 引數為 0,則立即返回鎖。
* -- 2、建議 timeout 設定為 0,避免 redis 因為阻塞導致效能下降。請根據實際需求進行設定。
** @param string $key 快取key。
* @param int $timeout 取鎖超時時間。單位(秒)。等於0,如果當前鎖被占用,則立即返回失敗。如果大於0,則反覆嘗試獲取鎖直到達到該超時時間。
* @param int $locksecond 鎖定時間。單位(秒)。
* @param int $sleep 取鎖間隔時間。單位(微秒)。當鎖為占用狀態時。每隔多久嘗試去取鎖。預設 0.1 秒一次取鎖。
* @return bool 成功:true、失敗:false
*/public
static
function
lock
($key
,$timeout=0
,$locksecond=20
,$sleep
=100000)if
(!is_int
($timeout)||
$timeout
<0)
$start
= self:
:getmicrotime()
;$redis
= self:
:getredis()
;do",
1,['nx'
,'ex'
=>
$locksecond])
;if($acquired)if
($timeout
===0
)usleep
($sleep);
}while
((self:
:getmicrotime()
)<
($start+(
$timeout
*1000000))
);return
$acquired
?true
:false;}
/** * 釋放鎖
** @param mixed $key 被加鎖的key。
* @return void
*/public
static
function
release
($key
)$redis
= self:
:getredis()
;$redis
->
del(
"lock:")
;}/** * 獲取當前微秒。
** @return bigint
*/protected
static
function
getmicrotime()
}
Redis實現分布式鎖 php
一 分布式鎖的作用 redis寫入時不帶鎖定功能,為防止多個程序同時進行乙個操作,出現意想不到的結果,so.對快取進行插入更新操作時自定義加鎖功能。二 redis的nx字尾命令 redis有一系列的命令,其特點是以nx結尾,nx的意思可以理解為 not exists 不存在 setnx命令 set ...
PHP實現Redis分布式鎖
鎖在我們的日常開發可謂用得比較多。通常用來解決資源併發的問題。特別是多機集群情況下,資源爭搶的問題。但是,很多新手在鎖的處理上常常會犯一些問題。今天我們來深入理解鎖。一 redis 鎖錯誤使用之一 我曾經見過有的專案把查詢結果儲存到 redis 當中時的偽 如下 redis new redis 12...
Redis實現分布式鎖 php
一 分布式鎖的作用 redis寫入時不帶鎖定功能,為防止多個程序同時進行乙個操作,出現意想不到的結果,so.對快取進行插入更新操作時自定義加鎖功能。二 redis的nx字尾命令 redis有一系列的命令,其特點是以nx結尾,nx的意思可以理解為 not exists 不存在 setnx命令 set ...