在高并发场景下,使用 syncronize 或者 Lock 锁的方式可以保证一个变量被一个线程所执行,且数据一致。而在分布式系统中,即使能够保证数据被一个线程所执行,但是多机环境,无法保证其他机器是否对数据进行了操作。这就需要用到分布式锁。
redis 实现分布式锁
set lock value NX PX 30000 或 setnx lock value + expire lock 300000
setnx 当key存在时,设置失败。
NX:只有 key 不存在时才会设置成功。
PX 30000:30s 后锁会自动释放。如果存在该锁则不能加锁。
释放锁就是将key删除。
删除锁的时候,找到 key 对应的 value,跟自己传过去的 value 做比较,如果是一样的才删除。
if redis.call(“get”,KEYS[1]) == ARGV[1] then
return redis.call(“del”,KEYS[1])
else
return 0
end
一般分布式锁中的value都为随机值,一位客户端获取到锁,阻塞很久才执行完,超时执行完毕,锁已经被其他客户端争抢到,此时直接删除锁会出问题。
zookeeper 实现分布式锁
在某个节点尝试创建临时 znode,此时创建成功就获取到这个锁;此时其他客户端来创建锁就会失败,只能注册监听这个锁。释放锁就是删除这个 znode,一旦释放掉就会通知客户端,然后有一个等待着的客户端就可以再次重新加锁。
redis 分布式锁与 zookeeper 分布式锁的区别
- redis 分布式锁,需要不断尝试获取锁,消耗性能。
- zookeeper 分布式锁,获取不到锁,注册个监听器即可,无需不断尝试获取锁,性能开销小。