Redis分布式锁:
1.采用单实例的正确实现
获取锁:
SET name value NX PX 30000
value必须在所有获取锁的客户端里面唯一. 这个值用来保证可以安全的释放锁
释放锁:
redis.eval(传入lua脚本) 不使用del进行删除(删除时,因为超时已经自动释放了锁,所以删除了其他人的锁)
2.为什么基于故障切换的方案不够好?
2.1 客户端A 在master节点获取到了锁
2.2 master在把A 创建的key同步给slave之前宕机了.
2.3 slave变成了master节点
2.4 客户端B 也得到了和A持有的相同的锁. (因为原来的slave还没有A持有锁的信息)
RedLock算法
获取锁:
1. client得到本地时间.
2. 使用相同的key和唯一的value值. 按顺序在每个master上尝试获取锁. (设置快速失败时间)
3. 获取锁的时间小于锁存活时间,并且在一半以上的master获取到锁认为client成功获取到了锁.
4. 如果获得了锁,client执行任务时间窗口是 锁的存活时间减去获得锁消耗的时间.
5. 如果获得锁数量不足一半,或者获取锁时间超时,认为获取锁失败.
客户端要尝试在所有的master 节点中释放锁,即时获取锁失败的master依然要进行释放操作
能保证锁同步吗?
集群时间误差与锁超时时间相比较小.
失败重试机制.
如果无法获得锁,进行一个随机延迟后继续. 与其他申请同一个锁的client错开时间.
使用redis作为锁服务主要优势是性能.
指标:
1. 加锁和释放锁的延迟.
2. 每秒可以进行多少加锁和解锁操作.
多路发送 减少通信延时.
故障恢复:
延时重启机制,等待一个锁周期后才能进行锁服务. 牺牲一部分可用性
可靠性:
锁续约机制. 如果客户端工作时间较短,可以设置小的工作时间加上锁续约机制. 续约次数做限制,防止key长时间不可用.