什么场景下要使用分布式锁
分布式锁在以下场景中非常有用:
- 共享资源的互斥访问:
- 当多个分布式节点需要同时访问某个共享资源(例如数据库、文件系统)时,为了保证数据的一致性和避免冲突,可以使用分布式锁来确保同一时间只有一个节点能够访问该资源。
- 避免重复操作:
- 在某些情况下,需要防止重复操作,即同一个任务在分布式环境中只能被执行一次。使用分布式锁可以确保只有一个节点能够成功获取锁并执行任务,其他节点则被阻塞或放弃执行。
- 控制并发流量:
- 在高并发环境下,为了避免系统资源耗尽,可以使用分布式锁来控制并发流量。只有获取到锁的节点才能执行某个操作,其他节点需要等待锁释放后才能继续执行。
- 避免竞态条件:
- 当多个节点同时进行某个操作时,可能会产生竞态条件(Race Condition),导致数据不一致或者错误的结果。通过使用分布式锁,可以在关键的操作中保持原子性,避免竞态条件的发生。
- 任务调度与协调:
- 在分布式任务调度中,可以使用分布式锁来协调任务的执行顺序和避免重复执行。只有获取到锁的节点才能执行任务,其他节点需要等待或者跳过。
更常见的场景是:防止超卖 问题
分布式锁的实现方案有哪些
- 基于数据库的分布式锁:
- 可以利用数据库的唯一性约束或者悲观锁来实现分布式锁。通过在数据库中创建一个表或者记录,利用事务的特性来确保锁的唯一性。
- 基于 Redis 的分布式锁:
- 使用 Redis 的 SETNX(SET if Not eXists)指令来实现简单的分布式锁。通过在 Redis 中设置一个键值对表示锁,利用原子操作来确保锁的互斥性。或者直接采用 redisson 客户端;
- 基于 ZooKeeper 的分布式锁:
- 利用 ZooKeeper 的临时顺序节点和 Watch 机制来实现分布式锁。通过创建临时顺序节点来竞争锁,同时利用 Watch 机制监听节点变化来实现分布式锁的释放和获取。
如何选择分布式锁方案
1、redisson:可以使用在并发高,性能要求高的场景;
2、zookeeper:采用cp模式保证高可靠性,对于更高要求绝对可靠的场景;
redisson分布式锁如何应用
在 Redisson 中使用分布式锁通常包括以下步骤:
- 创建 Redisson 客户端连接到 Redis 服务器。
- 通过 Redisson API 获取分布式锁对象。
- 在关键代码段中使用分布式锁的加锁和解锁方法来控制对共享资源的访问。
如何实现分布式锁的可重入
可重入锁意思:是对于同一线程可以多次获取锁;那不同线程之间同一把锁不能重复获取怎么保证线程可重入获取锁呢?
解决:我们可以通过维护当前持有锁的计数来实现可重入功能。
- 加锁的时候,因为保存了锁的线程标识,后续再次获取锁,先看是否是同一个线程,如果是的话只对锁计数进行递增
- 解锁时,对锁计数进行递减,同时刷新锁的过期时间。如果计数为 0,最终才释放锁