用redis实现分布式锁:
分布式锁在多个进程互斥的操作共享资源的时候非常有用。
很多库和博客都描述了如何使用redis实现分布式锁管理,但是每个库用的方式都不一样,很多简单实现方式没有很好保证。
这篇试图提供一个权威的算法-Redlock,使用redis实现分布式锁。
分布式锁最少的三个保证:
1. 安全性:互斥,一个时间,只能有一个客户端持有锁。
2. 活跃性A:死锁,最终总是能获取到锁。
3. 活跃性B: 容错,只要大部分redis节点起来了,客户端就能够获取和释放锁。
为什么基于故障转移的实现不够:
为了理解我们想提升什么,我们先分析下当前一些分布式锁的实现。
1.最简单的通过redis锁住一个资源是创建一个key实例。key通常设置过期时间。当客户端需要释放资源的时候,删除这个key.
表面上看这种方式工作的很好,其实有一个问题:单点问题。如果redis master down掉了怎么办?slave 无法保证安全性:互斥。因为redis replication 是异步的。
这种方案,如果在某些失败的情况下,多个客户端可以同时获取到锁,完全可以基于这种方案。
这种方案的正确实现:
set resource_name my_random_value nx px 30000
my_random_value必须是独一无二的,random value用来安全的释放锁,可以用lua:
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
后续:作者推了 redLock 目测接受度不太好。
替代方案是:zookeeper 实现分布式锁
对于要求性能的场景 能够容忍极端情况 可以使用redis简单实现的锁,如果是不能容忍极端情况的,可以使用zookeeper实现分布式锁。