開發時,碰到互斥問題,須要保證在分佈式環境下,避免重複性操做修改用戶狀態,如:用戶訂單狀態,購票時,修改票的餘額等javascript
SET key value NX PX 30000
複製代碼
可是這種方法在主庫錯誤時,會發生錯誤,redis主從同步是異步,主庫錯誤時,從庫若尚未鎖的信息,則會致使多個進程持有鎖java
在分佈式版本的算法裏咱們假設咱們有N個Redis master節點,這些節點都是徹底獨立的,咱們不用任何複製或者其餘隱含的分佈式協調算法。咱們已經描述瞭如何在單節點環境下安全地獲取和釋放鎖。所以咱們理所固然地應當用這個方法在每一個單節點裏來獲取和釋放鎖。在咱們的例子裏面咱們把N設成5,這個數字是一個相對比較合理的數值,所以咱們須要在不一樣的計算機或者虛擬機上運行5個master節點來保證他們大多數狀況下都不會同時宕機。一個客戶端須要作以下操做來獲取鎖:node
npm i --save ioredis
npm i --save redlock
複製代碼
/** 請求鎖 */
Redlock.prototype.lock(resource, ttl, ?callback)
// resource鎖的名稱
// ttl鎖的有效期
// callback 回調函數,當使用promise的寫法的時候,能夠填寫這個參數
/** 釋放鎖 */
Redlock.prototype.unlock(lock, ?callback)
/** 延長鎖的有效時間 */
Lock.prototype.extend(lock, ttl, ?callback)
// 都支持callback、promise、yield寫法
複製代碼
const ioredis = require('ioredis')
const Redlock = require('redlock')
const client = new ioredis(REDIS_SERVER)
const redlock = new Redlock([client])
co(function* () {
while (true) {
let lock = null
try {
lock = yield redlock.lock('lock', 1000) // 這種寫法取不到鎖時會直接拋出錯誤
} catch (error) {
lock = null
}
yield sleep(30 * 1000)
// 處理邏輯
lock.unlock()
}
})
複製代碼