在分布式架构下,特别是微服务架构下,很多业务场景为了解决共享资源访问的问题,都会采用分布式锁,但是不同业务场景对分布式锁的可用性要求不一样,因此出现了几种分布式锁的实现版本,这篇文章简单总结一下。
首先分布式锁需要有以下几个特性:
这个是最常见的, 也是最容易实现的,其中获取锁用redis的SETNX命令:
SET {key} {random_value} NX PX {expire_time_ms}
释放锁需要通过lua脚本的方式来操作:
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
之所设置随机值,是为了在释放锁的时候,在删除key之前检查随机值,如果和之前设置的随机值不一样,则认为是不同客户端的删除锁操作,就不会做del操作。
如果锁被其他客户端释放了,新的获取锁请求就被允许了,超过1个客户端同时获取到锁,这是不允许的。
单实例的redis分布式锁,存在一个很大的问题,就是可用性问题,如果单个redis实例挂了,分布式锁服务就不可用了,而且存的锁数据都不存在了。
为了提高可用性,可以增加副本,但是副本也不能解决可能有不同客户端获取到锁的问题。
集群方案也是不可行的,因为集群方案本质上key-value也是到单个实例上。
RedLock提出用多个master节点共同决策获取锁操作,具体步骤如下: