type
status
date
slug
summary
tags
category
icon
password
 

1、基于缓存的分布式锁

1.1、Redis的setNx

SET if Not exits
SETNX命令的原子性可以保证在多个客户端并发访问时,只有一个客户端能成功设置键值,并返回1。返回1的客户端就可以认为获取到了锁。
 

1.2、RedLock

Redlock算法是Redis官方提出的一种分布式锁算法,相比SETNX命令,它在安全性和性能方面都有一定的改进。
RedLock算法是Redis官方推荐的分布式锁实现方案,RedLock算法推荐至少使用5个Redis节点,这是为了确保锁的安全性和稳定性。这个设计主要基于以下两个原因:
  1. 避免单点故障:如果你只有一个Redis节点作为锁的存储,那么一旦这个节点出现故障(比如网络故障、硬件故障等),那么锁就会失效,导致应用程序无法正常工作。有多个节点可以降低这种风险。
  1. 保证一致性:RedLock算法要求你必须在大多数节点上成功设置锁,才算真正获取到锁。这是为了避免因为部分节点出现故障或网络延迟,导致其他客户端误认为锁已经被释放。只有当大多数节点都设置了锁,才能确保即使有部分节点出现问题,锁的状态仍然是正确的。选择5个节点,是为了保证即使有2个节点同时出现问题,其他3个节点的多数也能保证锁的正确性。
实际上,你可以根据自己的实际需求和环境,选择更多的节点。只要节点数是奇数,能够满足"大多数"的要求,就可以实现RedLock的设计目标。但是过多的节点可能会增加网络通信的延迟和复杂性,所以需要做出适当的权衡。
具体的实现步骤如下:
  1. 获取当前时间(单位毫秒)。
  1. 使用相同的key和随机value,依次尝试在所有的Redis节点上设定一个带有过期时间的key(通常使用setnx或set命令配合EX和NX参数)。
  1. 如果在大多数(比如说5个节点中的3个)Redis节点上设定成功,并且设定key的总耗时小于key的过期时间,则认为获取锁成功。
  1. 如果获取锁成功,那么锁的真正有效时间应该等于key的过期时间减去获取锁的总耗时。
  1. 如果获取锁失败,那么应该在所有的Redis节点上删除这个key。
 
java示例 用法如下 :
在这个示例中,首先创建了一个RedissonClient实例,并指定了Redis集群的地址。然后,通过RedissonClientgetLock方法获取了一个RLock对象,该对象代表了一个可重入的分布式锁。调用lock方法获取锁,执行业务逻辑,最后调用unlock方法释放锁。不论业务逻辑是否执行成功,unlock方法都会在finally块中被执行,能避免因为异常导致的锁无法释放的情况。目前没有发现其他java Redis client有实现RedLock算法
 

2、基于Zookeeper的分布式锁

Zookeeper是一个开源的分布式服务协调框架,它内部实现了一套Paxos一致性协议,可以提供基于Znode的分布式锁。当一个客户端想要获取锁时,可以在Zookeeper中创建一个临时顺序Znode,然后获取当前Znode列表,查看自己创建的Znode是否为最小的Znode,如果是则获得锁,如果不是,则监听比自己小的那个Znode的删除事件,当接收到删除事件时,再次进行获取锁的操作。
利用Curator创建临时顺序ZNode示例:
 
 

3、基于etcd的分布式锁

etcd是一个高可用的键值存储系统,用于共享配置和服务发现,它提供了一种基于租约的锁机制,客户端可以通过创建一个带租约的键值对来获取锁,当租约到期时,锁自动释放。
使用Jetcd实现分布式锁的基本步骤:
  1. 创建一个租约,并设置一个适当的TTL。这个租约将用于实现锁的自动过期。
  1. 尝试创建一个带有这个租约的键值对。这个键值对将代表锁。如果创建成功,那么就获取到了锁。
  1. 执行你的业务逻辑。
  1. 完成业务逻辑后,删除这个键值对,以释放锁。
 
代码示例:
 
AMQP Protocol详解MySQL多版本并发控制(MVCC)
Loading...
奥利弗
奥利弗
巴塔哥尼亚的门徒
最新发布
🎨 一键转换,让你的 SVG 飞起来!——介绍「SVG 魔法转换器」
2025-4-30
🚀 告别繁琐,实时掌握币圈脉搏!全新加密货币实时行情追踪神器上线!
2025-4-28
厌倦了千篇一律的鸡汤?来点“毒”的,再加点暖和和疯狂星期四的快乐!
2025-4-28
用呼吸找回内心的平静:一款简单有效的在线冥想工具
2025-4-23
谁在剥夺骑手的自由?——从“外卖平台二选一”事件看平台责任与底层困局
2025-4-21
手把手教你制作吉卜力风格的微信表情包!
2025-4-17
公告
 
世界和平!