美文网首页
etcdctl查看分布式锁状态

etcdctl查看分布式锁状态

作者: Ballpenww | 来源:发表于2022-09-27 11:54 被阅读0次

etcd提供分布式锁能力,经常会出现获取锁超时报错,当然这个在逻辑上是正常,一个进程持有锁在没有释放期间,其他进程不能获取锁。但从运维测如何确认这个锁是否工作正常呢?

首先etcd实现分布式锁的原理

分布式锁要求

  • 互斥性:在任意时刻,对于同一个锁,只有一个客户端能持有,从而保证一个共享资源同一时间只能被一个客户端操作;
  • 安全性:即不会形成死锁,当一个客户端在持有锁的期间崩溃而没有主动解锁的情况下,其持有的锁也能够被正确释放,并保证后续其它客户端能加锁
  • 可用性:当提供锁服务的节点发生宕机等不可恢复性故障时,“热备” 节点能够接替故障的节点继续提供服务,并保证自身持有的数据与故障节点一致。
  • 对称性:对于任意一个锁,其加锁和解锁必须是同一个客户端,即客户端 A 不能把客户端 B 加的锁给解了。

etcd实现原理

etcd的几种特殊的机制都可以作为分布式锁的基础。etcd的键值对可以作为锁的本体,锁的创建与删除对应键值对的创建与删除。etcd的分布式一致性以及高可用可以保证锁的高可用性

  • prefix 由于etcd支持前缀查找,可以将锁设置成“锁名称”+“唯一id”的格式,保证锁的对称性,即每个客户端只操作自己持有的锁
  • lease 租约机制可以为锁做一个保活操作,在创建锁的时候绑定租约,并定期进行续约,如果获得锁期间客户端意外宕机,则持有的锁会被自动删除,避免了死锁的产生。
  • Revision etcd内部维护了一个全局的Revision值,并会随着事务的递增而递增。可以用Revision值的大小来决定获取锁的先后顺序,在上锁的时候已经决定了获取锁先后顺序,后续有客户端释放锁也不会产生惊群效应。
  • watch watch机制可以用于监听锁的删除事件,不必使用忙轮询的方式查看是否释放了锁,更加高效。同时,在watch时候可以通过Revision来进行监听,只需要监听距离自己最近而且比自己小的一个Revision就可以做到锁的实时获取。
    image.png

分布式锁的操作

  • 加锁 在对共享资源操作时候,首先需要加锁,在加锁时候,抢到锁的进程可以直接返回,进而操作共享资源,而没有抢到锁的进程需要等待锁的释放,对于同一个锁,同一时刻只能有一个进程来持有,这体现了锁的互斥性。
  • 锁期间 由于是多进程情况,需要考虑进程宕机的情况,假如抢到锁的进程突然宕机,需要能够有释放锁的机制,避免后面的进程一直阻塞导致死锁。提供锁的组件也应该具备高可用性,在某个节点宕机后能够继续提供服务。
  • 解锁 对资源的操作结束之后,需要及时释放锁,但是不能释放其他进程的锁,后面没有抢到锁的进程可以获得锁。如果抢锁的进程过多,可能会导致惊群效应,提供锁的组件应在一定程度上避免该现象。

etcdctl查看锁状态

了解了etcd实现分布式锁的原理,可以支持etcd中分布式锁的结构是:lock_name/lease_id

  • 加锁
# etcdctl lock <lockname> [exec-command arg1 arg2 ...]
# exec-cmd 是说执行完改名了后释放锁;如果不加命令,会一直持有锁
# --ttl=10  timeout for session 
# 从命令介绍看,默认10s的lease租期
$ ETCDCTL_API=3 etcdctl lock a1_lock sleep 5  【等待5s都释放锁】
  • 通过watch命令查看锁状态
    其实就是查看lease_id是否变化,如果持续变化,则锁一直在进行 加锁/解锁操作
# 通过prefix参数就能监听a1_lock的锁状态
$ ETCDCTL_API=3 etcdctl watch a1_lock --prefix 
PUT
a1_lock/3668830c8895c46b

DELETE
a1_lock/3668830c8895c46b
  • 就算持有锁的进程异常,在lease_id的ttl到期后,也会释放锁
    如下:持有锁,并kill命令
$ time etcdctl lock a2_lock
a2_lock/3668830c889630c7

^C   # kill 命令
real    0m15.283s
user    0m0.009s
sys 0m0.023s

查看终端

$ while [[ 1 > 0 ]]; do etcdctl lease timetolive 3668830c889630c7; sleep 1; done
lease 3668830c889630c7 granted with TTL(10s), remaining(8s)
lease 3668830c889630c7 granted with TTL(10s), remaining(7s)
lease 3668830c889630c7 granted with TTL(10s), remaining(9s)
lease 3668830c889630c7 granted with TTL(10s), remaining(8s)
lease 3668830c889630c7 granted with TTL(10s), remaining(7s)  # 持有进程异常点,
lease 3668830c889630c7 granted with TTL(10s), remaining(9s)
lease 3668830c889630c7 granted with TTL(10s), remaining(8s)
lease 3668830c889630c7 granted with TTL(10s), remaining(7s)
lease 3668830c889630c7 granted with TTL(10s), remaining(6s)
lease 3668830c889630c7 granted with TTL(10s), remaining(5s)
lease 3668830c889630c7 granted with TTL(10s), remaining(4s)
lease 3668830c889630c7 granted with TTL(10s), remaining(3s)
lease 3668830c889630c7 granted with TTL(10s), remaining(2s)
lease 3668830c889630c7 granted with TTL(10s), remaining(1s)
lease 3668830c889630c7 granted with TTL(10s), remaining(0s)
lease 3668830c889630c7 granted with TTL(10s), remaining(0s)
lease 3668830c889630c7 already expired     # 释放锁
lease 3668830c889630c7 already expired

谢各位,如对您有帮助请点赞!

相关文章

  • etcdctl查看分布式锁状态

    etcd提供分布式锁能力,经常会出现获取锁超时报错,当然这个在逻辑上是正常,一个进程持有锁在没有释放期间,其他进程...

  • Redisson分布式锁使用即源码解读

    Redisson 提供的分布式锁 使用实例 如果拿到分布式锁的节点宕机,且这个锁正好处于锁住的状态时,会出现锁死的...

  • ETCD删除命令

    ETCDCTL_API=3 etcdctl --endpoints=http://10.24.75.53:1159...

  • 分布式锁

    为什么要用分布式锁 数据库乐观锁redis分布式锁zookeeper分布式锁 使用分布式锁的场景 实现分布式锁的方...

  • 分布式锁

    因为扩展性考虑,分布式的服务一般不能有状态,这个时候我们会将状态数据转移到数据库或分布式缓存中。分布式锁就是与状态...

  • kubernetes笔记-etcd存储结构

    配置别名etcdctl3,添加证书等参数 查询都有哪些daemonsets 与kubectl查看的结果一致 在et...

  • 什么是分布式锁?几种分布式锁分别是怎么实现的?

    一、什么是分布式锁: 1、什么是分布式锁: 分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资...

  • Linux系统编程7:读写锁

    1. 接口 1.1 锁操作 参数 锁信息 返回值 给指定文件添加读锁 查看当前锁的状态 给指定文件添加写锁 给指定...

  • Redis实现分布式锁相关注意事项

    Redis实现分布式锁相关注意事项 查看了不少关于redis实现分布式锁的文章,无疑要设计一个靠谱的分布式并不太容...

  • 4:Redis 分布式锁 (文末有项目连接)

    1:什么是缓存分布式锁 2:分布式锁的关键代码 3:业务代码使用分布式缓存锁 4:业务代码使用分布式缓存锁 5:测...

网友评论

      本文标题:etcdctl查看分布式锁状态

      本文链接:https://www.haomeiwen.com/subject/ssyfartx.html