我們希望同一時間只有乙個執行緒能夠訪問到資源,但是分布式資源點之間的協調會非常麻煩,這個時候我們就需要乙個分布式鎖。
etcd分布式鎖實現原理:
1.利用租約在etcd集群中建立乙個key,這個key有兩種形態,存在和不存在,而這兩種形態就是互斥量。
2.如果這個key不存在,那麼執行緒建立key,成功則獲取到鎖,該key就為存在狀態。
3.如果該key已經存在,那麼執行緒就不能建立key,則獲取鎖失敗。
package main
import
("go.etcd.io/etcd/v3/clientv3"
"context"
"fmt"
"time"
)type etcdmutex struct
func
(em *etcdmutex)
init()
error
em.txn = clientv3.
newkv
(client)
.txn
(context.
todo()
) em.lease = clientv3.
newlease
(client)
leaseresp,err := em.lease.
grant
(context.
todo()
,em.ttl)
if err !=
nil ctx,em.cancel = context.
withcancel
(context.
todo()
) em.leaseid = leaseresp.id
_,err = em.lease.
keepalive
(ctx,em.leaseid)
return err
}func
(em *etcdmutex)
lock()
error
//lock:
em.txn.
if(clientv3.
compare
(clientv3.
createrevision
(em.key)
,"=",0
)).then
(clientv3.
opput
(em.key,
"",clientv3.
withlease
(em.leaseid)))
.else()
txnresp,err := em.txn.
commit()
if err !=
nilif
!txnresp.succeeded
return
nil}
func
(em *etcdmutex)
unlock()
測試分布式鎖
func
main()
, dialtimeout:time.
duration(5
*time.second),}
emutex1 :=
&etcdmutex
emutex2 :=
&etcdmutex
gofunc()
else}(
)gofunc()
else}(
) time.
sleep
(time.second*30)
}
結果 etcd 分布式鎖實現原理
每個mutex會建立乙個租約lease,並且租約是長期有效的 使用prefix leaseid作為key向etcd插入資料 etcd確保每次插入的key都有乙個位移的createrevision,並且createrevision是從0開始遞增的 第2條規定所有mutex按照prefix leasei...
用Etcd實現分布式鎖和選主
etcd的v3版本官方client裡有乙個concurrency的包,裡面實現了分布式鎖和選主。本文分析一下它是如何實現的。先貼一下鎖的code 在code中注釋介紹了具體的實現。是字首,比如 service lock 是乙個64位的整數值,etcd v3引入了lease 租約 的概念,concur...
分布式鎖 使用Redis實現分布式鎖
關於分布式鎖的實現,我的前一篇文章講解了如何使用zookeeper實現分布式鎖。關於分布式鎖的背景此處不再做贅述,我們直接討論下如何使用redis實現分布式鎖。關於redis,筆主不打算做長篇大論的介紹,只介紹下redis優秀的特性。支援豐富的資料型別,如string list map set zs...