当前位置:网站首页>Etcd教程 — 第九章 Etcd之实现分布式锁
Etcd教程 — 第九章 Etcd之实现分布式锁
2022-06-30 15:48:00 【西木Qi】
Etcd教程 — 第九章 Etcd之实现分布式锁
一、通过 Etcd txn 实现分布式锁
通过Etcd实现分布式锁,同样需要满足一致性、互斥性和可靠性等要求。Etcd中的事务 txn、lease租约以及 watch 监听特性,能够使得基于Etcd实现上述要求的分布式锁。
1.1 思路分析
通过 Etcd 的事务特性可以帮助我们实现一致性和互斥性。Etcd 的事务特性,使用的 IF-Then-Else 语句,IF 语言判断 Etcd 服务端是否存在指定的 key,即该 key 创建版本号 create_revision 是否为 0 来检查 key 是否已存在,因为该 key 已存在的话,它的 create_revision 版本号就不是 0。
满足 IF 条件的情况下则使用 then 执行 put 操作,否则 else 语句返回抢锁失败的结果。当然,除了使用 key 是否创建成功作为 IF 的判断依据,还可以创建前缀相同的 key,比较这些 key 的 revision 来判断分布式锁应该属于哪个请求。
客户端请求在获取到分布式锁之后,如果发生异常,需要及时将锁给释放掉。因此需要租约,当我们申请分布式锁的时候需要指定租约时间。超过 lease 租期时间将会自动释放锁,保证了业务的可用性。
是不是这样就够了呢?在执行业务逻辑时,如果客户端发起的是一个耗时的操作,操作未完成的请情况下,租约时间过期,导致其他请求获取到分布式锁,造成不一致。这种情况下则需要续租,即刷新租约,使得客户端能够和 etcd 服务端保持心跳。
二、具体实现
2.1 流程图
我们基于如上分析的思路,绘制出实现 etcd 分布式锁的流程图,如下所示:
2.2 实现代码
基于 Go 语言实现的 etcd 分布式锁,测试代码如下所示:
func TestLock(t *testing.T) {
// 客户端配置
config = clientv3.Config{
Endpoints: []string{"localhost:2379"},
DialTimeout: 5 * time.Second,
}
// 建立连接
if client, err = clientv3.New(config); err != nil {
fmt.Println(err)
return
}
// 1. 上锁并创建租约
lease = clientv3.NewLease(client)
if leaseGrantResp, err = lease.Grant(context.TODO(), 5); err != nil {
panic(err)
}
leaseId = leaseGrantResp.ID
// 2 自动续约
// 创建一个可取消的租约,主要是为了退出的时候能够释放
ctx, cancelFunc = context.WithCancel(context.TODO())
// 3. 释放租约
defer cancelFunc()
defer lease.Revoke(context.TODO(), leaseId)
if keepRespChan, err = lease.KeepAlive(ctx, leaseId); err != nil {
panic(err)
}
// 续约应答
go func() {
for {
select {
case keepResp = <-keepRespChan:
if keepRespChan == nil {
fmt.Println("租约已经失效了")
goto END
} else { // 每秒会续租一次, 所以就会受到一次应答
fmt.Println("收到自动续租应答:", keepResp.ID)
}
}
}
END:
}()
// 1.3 在租约时间内去抢锁(etcd 里面的锁就是一个 key)
kv = clientv3.NewKV(client)
// 创建事务
txn = kv.Txn(context.TODO())
//if 不存在 key,then 设置它,else 抢锁失败
txn.If(clientv3.Compare(clientv3.CreateRevision("lock"), "=", 0)).
Then(clientv3.OpPut("lock", "g", clientv3.WithLease(leaseId))).
Else(clientv3.OpGet("lock"))
// 提交事务
if txnResp, err = txn.Commit(); err != nil {
panic(err)
}
if !txnResp.Succeeded {
fmt.Println("锁被占用:", string(txnResp.Responses[0].GetResponseRange().Kvs[0].Value))
return
}
// 抢到锁后执行业务逻辑,没有抢到退出
fmt.Println("处理任务")
time.Sleep(5 * time.Second)
}
预期的执行结果如下所示:
=== RUN TestLock
处理任务
收到自动续租应答: 7587848943239472601
收到自动续租应答: 7587848943239472601
收到自动续租应答: 7587848943239472601
--- PASS: TestLock (5.10s)
PASS
总得来说,如上关于 etcd 分布式锁的实现过程分为四个步骤:
- 客户端初始化与建立连接;
- 创建租约,自动续租;
- 创建事务,获取锁;
- 执行业务逻辑,最后释放锁。
创建租约的时候,需要创建一个可取消的租约,主要是为了退出的时候能够释放。释放锁对应的步骤,在上面的 defer 语句中。当 defer 租约关掉的时候,分布式锁对应的 key 就会被释放掉了。
边栏推荐
- 思源笔记:能否提供页面内折叠所有标题的快捷键?
- 【Verilog基础】十进制负数的八进制、十六进制表示
- 2022 Blue Bridge Cup group B - expense reimbursement - (linear dp| status DP)
- How to get the preferential activities for stock account opening? Is online account opening safe?
- How to connect the Internet Reading Notes - Summary
- 【牛客网刷题系列 之 Verilog快速入门】~ 位拆分与运算
- AVIC UAV technology innovation board is listed: the fist product with a market value of 38.5 billion is pterodactyl UAV
- 从第三次技术革命看企业应用三大开发趋势
- 2020 Blue Bridge Cup group B - move bricks - (greedy sorting +01 backpack)
- Bidding announcement: remote disaster recovery project of Shenzhen Finance Bureau database
猜你喜欢
![[Verilog basics] summary of some concepts about clock signals (clock setup/hold, clock tree, clock skew, clock latency, clock transition..)](/img/54/fd7541dae4aad7e4216bcaabbb146b.png)
[Verilog basics] summary of some concepts about clock signals (clock setup/hold, clock tree, clock skew, clock latency, clock transition..)

华为帐号多端协同,打造美好互联生活

The image variables in the Halcon variable window are not displayed, and it is useless to restart the software and the computer

RT-Thread 堆区大小设置

Symantec electronic sprint technology innovation board: Tan Jian, the actual controller, is an American who plans to raise 620million yuan

边缘计算平台如何助力物联网发展

Arcmap操作系列:80平面转经纬度84

MC Instruction Decoder

容联云首发基于统信UOS的Rphone,打造国产化联络中心新生态

What role does "low code" play in enterprise digital transformation?
随机推荐
Table responsive layout tips for super nice
[Verilog quick start of Niuke online question series] ~ bit splitting and operation
register_chrdev和cdev_init cdev_add用法区别
腾讯二面:@Bean 与 @Component 用在同一个类上,会怎么样?
云和恩墨中标天津滨海农村商业银行2022-2023年度Oracle维保项目
Mysql8 error: error 1410 (42000): you are not allowed to create a user with grant solution
halcon知识:矩阵专题【02】
附加:(还没写,别看~~~)CorsFilter过滤器;
ArcMap operation series: 80 plane to latitude and longitude 84
flink sql cdc 同步sqlserver 报错什么原因啊
MC Instruction Decoder
构建适合组织的云原生可观测性能力
Wechat emoticons are written into the judgment, and the OK and bomb you send may become "testimony in court"
Cesium-1.72 learning (earth model creation online offline tile)
CVPR 2022 - Tesla AI proposed: generalized pedestrian re recognition based on graph sampling depth metric learning
中国传奇教授李泽湘,正在批量制造独角兽
MicroBlaze serial port learning · 2
7 月 2 日邀你来TD Hero 线上发布会
The inspiration from infant cognitive learning may be the key to the next generation of unsupervised machine learning
KDD 2022 | how far are we from the general pre training recommendation model? Universal sequence representation learning model unisrec for recommender system