Redis 分布式鎖(PHP實現)

2021-10-09 09:08:38 字數 2608 閱讀 3355

先來看看如果不用分布式鎖,所謂的電商庫存超賣是啥意思?大家看看下面的圖:

這個圖,其實很清晰了,假設訂單系統部署兩台機器上,不同的使用者都要同時買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 ...