分佈式鎖設計

分佈式鎖即在分佈式環境下鎖定共享資源,讓請求處理串行化,實際表現爲互斥鎖。分佈式鎖能夠解決業務中的冪等性問題。git

在用戶對商品下單的時候,若是商戶正在對商品改價,同時用戶正在支付,就可能發生併發問題,這個時候就須要串行化操做,防止出現業務問題。redis

分佈式鎖要解決的幾個問題:算法

  • 互斥性,同一時刻只能有一臺服務器能訪問資源
  • 安全性,鎖只能被持有該鎖的客戶端刪除或者釋放
  • 容錯,在服務器宕機的時候,鎖仍能獲得釋放或者其餘服務器能夠進行加鎖
  • 避免死鎖

分佈式鎖設計目標:安全

  • 強一致性
  • 服務高可用,系統穩健
  • 鎖自動續約及自動釋放
  • 代碼高度抽象與業務接入簡單
  • 可監控管理

Redis實現

參考我早先寫的Redis實現分佈式鎖bash

set key value [EX seconds] [PX milliseconds] [NX|XX]
複製代碼

官方建議redis使用redlock算法來保證,可是redlock算法至少須要3臺redis主從實例來完成,維護成本高,redlock至關於本身實現簡單的一致性協議,細節繁瑣,且容易出錯。關於redLock算法,參考redis分佈式鎖官方介紹服務器

分佈式鎖方案對比

redis zookeeker etcd
一致性算法 paxos/ZAB raft
CAP AP CP CP/AP
高可用 主從 N+1可用(奇數個) N+1可用
接口類型 客戶端 客戶端 http/grpc
實現 set命令 臨時節點 restful API

關於分佈式一致性協議,參考我以前的整理:幾種常見的分佈式一致性協議介紹restful

基於ectd的分佈式鎖流程:網絡

  • 多個客戶端同時到etcd獲取同一把鎖,可是隻能有一個客戶端能獲取到鎖
  • 在獲取鎖的時候,請求中會設置過時時間,獲取到鎖以後etcd會生成uuid做爲惟一憑證
  • 後臺新啓動一個線程,不斷的刷新鎖的租期

產品要想真正投入使用,要作一些兼容性測試:併發

  • 集羣下停掉某個節點觀察是否正常工做
  • 當只有一個節點時會發生什麼狀況,(etcd讀會停機,寫入正常)
  • 理論上不是多節點同時停機,線上服務是不會受影響的

etcdV3版本提供gRPC接口,自然提供分佈式鎖的功能,只需申請鎖,釋放鎖,不用關心鎖的租期問題。分佈式

分佈式鎖注意點

  • 分佈式鎖只是同一天然時間的互斥鎖,自己不解決冪等性問題 ==> 業務問題
  • 鎖沒有按照預期續租,可能會這種狀況。好比網絡問題,好比GC回收時間比較長 ==> 極端狀況
  • etcd內部選主的時候,去拿鎖是拿不到的。 ==> etcd內部問題
相關文章
相關標籤/搜索