用Etcd实现分布式锁和选主

简介: Etcd的v3版本官方client里有一个concurrency的包,里面实现了分布式锁和选主。本文分析一下它是如何实现的。

Etcd的v3版本官方client里有一个concurrency的包,里面实现了分布式锁和选主。本文分析一下它是如何实现的。

先贴一下锁的code (https://github.com/coreos/etcd/blob/master/clientv3/concurrency/mutex.go#L26)

在code中注释介绍了具体的实现。

//m.pfx是前缀,比如"service/lock/"
//s.Lease()是一个64位的整数值,etcd v3引入了lease(租约)的概念,concurrency包基于lease封装了session,每一个客户端都有自己的lease,也就是说每个客户端都有一个唯一的64位整形值
//m.myKey类似于"service/lock/12345"
m.myKey = fmt.Sprintf("%s%x", m.pfx, s.Lease())


//etcdv3新引入的多键条件事务,替代了v2中Compare-And-put操作。etcdv3的多键条件事务的语意是先做一个比较(compare)操作,如果比较成立则执行一系列操作,如果比较不成立则执行另外一系列操作。有类似于C语言中的条件表达式。
//接下来的这部分实现了如果不存在这个key,则将这个key写入到etcd,如果存在则读取这个key的值这样的功能。
//下面这一句,是构建了一个compare的条件,比较的是key的createRevision,如果revision是0,则存入一个key,如果revision不为0,则读取这个key。
//revision是etcd一个全局的序列号,每一个对etcd存储进行改动都会分配一个这个序号,在v2中叫index,createRevision是表示这个key创建时被分配的这个序号。当key不存在时,createRivision是0。
cmp := v3.Compare(v3.CreateRevision(m.myKey), "=", 0)
put := v3.OpPut(m.myKey, "", v3.WithLease(s.Lease()))
get := v3.OpGet(m.myKey)
resp, err := client.Txn(ctx).If(cmp).Then(put).Else(get).Commit()
if err != nil {
    return err
}
m.myRev = resp.Header.Revision
if !resp.Succeeded {
    m.myRev = resp.Responses[0].GetResponseRange().Kvs[0].CreateRevision
}

//如果上面的code操作成功了,则myRev是当前客户端创建的key的revision值。
//waitDeletes等待匹配m.pfx ("service/lock/")这个前缀(可类比在这个目录下的)并且createRivision小于m.myRev-1所有key被删除
//如果没有比当前客户端创建的key的revision小的key,则当前客户端者获得锁
//如果有比它小的key则等待,比它小的被删除
err = waitDeletes(ctx, client, m.pfx, m.myRev-1)

总结一下,上面的锁的实现,所有的客户端都在service/lock下创建一个自己的key,createrevision最小的那个客户端获得锁,也就是最早建立key的客户端获得锁,之后按照创建的时间先后依次获得锁。

选主(https://github.com/coreos/etcd/blob/master/clientv3/concurrency/election.go#L31)的实现与锁的实现非常类似,这里就不做详述了。

目录
相关文章
|
3月前
|
存储 Kubernetes 监控
etcd:分布式键值存储系统技术
`etcd` 是一个用于共享配置和服务发现的高度可用键值存储系统,基于Raft算法保证数据一致性。它提供HTTP/GRPC API,常用于服务发现、配置共享和分布式锁。etcd集群包含多个节点,每个节点可为领导者或跟随者。在Kubernetes中,etcd存储集群状态,其稳定性和一致性至关重要。维护etcd涉及备份、状态监控、日志审计和安全措施。
58 2
|
10月前
|
SQL Kubernetes 关系型数据库
​Kubernetes的演变:从etcd到分布式SQL的过渡
​Kubernetes的演变:从etcd到分布式SQL的过渡
​Kubernetes的演变:从etcd到分布式SQL的过渡
|
存储 监控 算法
分布式系统 Etcd 解析
随着移动互联网技术的快速发展,在新业务、新领域、新场景的驱动下,基于传统大型机的服务部署方式,不仅难以适应快速增长的业务需求,而且持续耗费高昂的成本,从而使得各大生产厂商以及企业只能望洋兴叹。此时,分布式系统的出现无疑给大家带来了些许振奋。而后随着大数据、区块链技术以及云计算技术的蓬勃发展,使得将分布式系统推向新的高潮。
166 0
|
Go 微服务
微服务架构上篇:5. 基于etcd实现分布式锁
微服务架构上篇:5. 基于etcd实现分布式锁
|
存储 缓存 NoSQL
|
存储 运维 Kubernetes
分布式锁实战-偶遇 etcd 后就想抛弃 Redis ?
分布式锁实战-偶遇 etcd 后就想抛弃 Redis ?
668 0
分布式锁实战-偶遇 etcd 后就想抛弃 Redis ?
|
存储 缓存 NoSQL
Etcd 实现分布式锁的分析
锁,主要是用来解决并发情况时对共享资源的使用时互斥控制。
182 0
分布式学习十四:etcd实现服务注册/发现
分布式学习十四:etcd实现服务注册/发现
88 0
分布式学习十四:etcd实现服务注册/发现
Zookeeper,etcd,consul内部机制和分布式锁和选主实现的比较
我的另外3篇文章分别介绍了Zookeeper,etcd,consul是如何实现分布式锁和选主的。本文想比较一下Zookeeper、etcd、consul内部机制有哪些不同,他们实现锁和选主的方式相同和不同。
7199 0