分布式锁的几种实现方式
# 分布式锁特性
- 互斥(线程独享):即同一时刻只有一个线程能够获取锁
- 避免死锁:获得锁的线程崩溃后,不会影响后续线程获取锁,操作共享资源
- 隔离性:A获取的锁,不能让B去解锁(解铃还须系铃人)
- 原子性:加锁和解锁必须保证为原子操作
# 实现方案
# 数据库
通过唯一索引的方式实现,创建not null union的索引,数据库中有相同记录会报错,没有则成功,插入成功获取锁,删除释放锁
# Redis
setnx + set expire +lua 或者 hsetnx + set expire +lua
# Zookeeper
方案一:创建临时顺序节点node_n(编号不可重复),对节点进行排序,是最小号则获取锁成功,通过watch机制监听节点的删除事件
- 每个线程抢占锁之前,先尝试创建自己的 ZNode。
- 同样,释放锁的时候需要删除创建的 Znode。创建成功后,如果不是序号最小的节点, 就处于等待通知的状态。
- 每一个等通知的 Znode 节点,需要监视(watch)序号在自己前面的那个 Znode,以获取其删除事件。
- 只要上一个节点被删除了,就进行再一次判断,看看自己是不是序号最小的那个节点,如果是,自己就获得锁。就这样不断地通知后一个 ZNode 节点。
- 获得锁的客户端出现网络异常失联情况下,节点会自动删除,其他节点可获取锁。
方案二:创建相同key的临时节点,创建成功获取到锁,失败则获取不到,通过watch机制监听节点的删除事件
# Redisson
基于redis实现
最后更新时间: 2024/03/15, 17:35:22