1. 前言
开发时,碰到互斥问题,需要保证在分布式环境下,避免重复性操作修改用户状态,如:用户订单状态,购票时,修改票的余额等
2. 分布式锁的条件
- 分布式锁需要满足下列条件
- 锁需要有充足的可访问的存储空间
- 锁必须被唯一标识
- 锁至少要有两种状态
- 同时,要保证
- 安全特性:互斥访问,永远只有一个client能拿到锁
- 避免死锁:client最后可以拿到锁,不会出现死锁,即使原本上锁的client出现问题无法解锁
- 容错性:容错,只要大多数redis节点能够正常工作,客户端端都能获取和释放锁。
3.Redis单节点上锁的实现
- 使用下列语句获取一个不存在的key,如果可以已存在则创建失败,确保key值唯一, 加上过期时间,确保系统错误后及时解锁,避免死锁
SET key value NX PX 30000
但是这种方法在主库错误时,会发生错误,redis主从同步是异步,主库错误时,从库若还没有锁的信息,则会导致多个进程持有锁
3. Redlock算法(官方文档)
在分布式版本的算法里我们假设我们有N个Redis master节点,这些节点都是完全独立的,我们不用任何复制或者其他隐含的分布式协调算法。我们已经描述了如何在单节点环境下安全地获取和释放锁。因此我们理所当然地应当用这个方法在每个单节点里来获取和释放锁。在我们的例子里面我们把N设成5,这个数字是一个相对比较合理的数值,因此我们需要在不同的计算机或者虚拟机上运行5个master节点来保证他们大多数情况下都不会同时宕机。一个客户端需要做如下操作来获取锁:
<