分布式锁

167 阅读2分钟

我们在设计分布式锁需要考虑的问题

  1. 互斥性
  2. 可重入性
  3. 锁超时
  4. 高效的获取锁
  5. 阻塞/非阻塞
  6. 公平/非公平

分布式锁的实现

db实现

db实现分布式锁的流程

  • 缺点
    • 性能瓶颈在数据库,不方便拓展
    • 需要自己实现超时、事务
  • 优点 实现比较简单
  • 互斥性:当然可以保证
  • 可重入性:在db维护机器信息和线程名,可以实现重入
  • 超时:需要自行实现,获取锁时加一个超时时间
  • 阻塞:用while(true)实现即可
  • 公平:是非公平锁,即在锁资源释放时,需要竞争

zk实现

实现原理

  1. 每个请求到zk时,会创建一个临时节点
  2. zk会负责维护这些临时节点的顺序
  3. 客户端获取节点后,比较节点的顺序是否是当前第一个:
    1. 如果是,说明获取到锁。
    2. 如果不是,建立一个监听器,监听第一个节点
  4. 当第一个节点被释放后,其余客户端会收到监听消息,可以获取锁。

缺点

  1. 需要维护一套zk
  2. 据说性能与mysql差别不大

优点

  1. 有现成的实现
  2. 支持锁超时
  3. 支持读写锁
  4. 是公平锁

七张图彻底讲清楚ZooKeeper分布式锁的实现原理

redis

实现简单,大部分分布式锁是用redis实现

  1. 简单实现 setNx+expire,setNx表示当不存在值时,可以插入,expire实现过期时间。 不过这样做,两次操作不是原子操作。
  2. jedis或redisson
    • 使用lual脚本,实现原子操作
    • 需要将value放入,这样释放锁的时候,才知道释放的是自己的锁。
  3. 可能存在的问题
    1. gc的stw

    2. 时钟发生跳跃

    3. 长时间的IO

    参考

TIPS

  1. 再有人问你分布式锁,这篇文章扔给他