[TOC]
1.使用互斥锁(mutex key)
业界比较常用的做法,是使用mutex。简单地来说。
SETNX,是「SET if Not eXists」的缩写,也就是只有不存在的时候才设置,可以利用它来实现锁的效果。
1 | public String get(key) { |
2.zookeeper
创建一个锁目录 /lock;
当一个客户端需要获取锁时,在 /lock 下创建临时的且有序的子节点;
客户端获取 /lock 下的子节点列表,判断自己创建的子节点是否为当前子节点列表中序号最小的子节点,如果是
则认为获得锁;否则监听自己的前一个子节点,获得子节点的变更通知后重复此步骤直至获得锁;
执行业务代码,完成后,删除对应的子节点。
3.Redis 的 RedLock 算法
使用了多个 Redis 实例来实现分布式锁,这是为了保证在发生单点故障时仍然可用。
尝试从 N 个互相独立 Redis 实例获取锁;
计算获取锁消耗的时间,只有当这个时间小于锁的过期时间,并且从大多数(N / 2 + 1)实例上获取了锁,那
么就认为锁获取成功了;
如果锁获取失败,就到每个实例上释放锁。
区别
①redis分布式锁,其实需要自己不断去尝试获取锁,比较消耗性能
②zk分布式锁,获取不到锁,注册个监听器即可,不需要不断主动尝试获取锁,性能开销较小
③另外一点就是,如果是redis获取锁的那个客户端bug了或者挂了,那么只能等待超时时间之后才能释放锁;而zk的话,因为创建的是临时znode,只要客户端挂了,znode就没了,此时就自动释放锁