标签:表示 通过 future模式 安全 客户 redis margin 缺陷 场景
先聊下redis普通的分布式锁,用
或许你了解过,通过如下方式加锁:
设置锁时,使用set命令,因为其包含了setnx,expire的功能,起到了原子操作的效果,给key设置随机值,并且只有在key不存在时才设置成功返回True,并且设置key的过期时间(最好用毫秒)
1 SET key_name my_random_value NX PX 30000 # NX 表示if not exist 就设置并返回True,否则不设置并返回False PX 表示过期时间用毫秒级, 30000 表示这些毫秒时间后此key过期
2.在获取锁后,并完成相关业务后,需要删除自己设置的锁(必须是只能删除自己设置的锁,不能删除他人设置的锁);
删除原因:保证服务器资源的高利用效率,不用等到锁自动过期才删除;
删除方法:最好使用Lua脚本删除(redis保证执行此脚本时不执行其他操作,保证操作的原子性),代码如下;逻辑是 先获取key,如果存在并且值是自己设置的就删除此key;否则就跳过;
1 if redis.call("get",KEYS[1]) == ARGV[1] then 2 return redis.call("del",KEYS[1]) 3 else 4 return 0 5 end
单点Redis锁的缺陷:这个缺陷其实很明显,如果只有一个Redis实例,这个挂了,所有依赖他的服务都挂了。显然不太适合大型的应用。
为了避免单点故障,我们给Redis做一个Master/Slave的主从架构,一个Master,一台Slave。下面就会碰到这么一个问题。下面是使用场景。
全名叫做 Redis Distributed Lock;即使用redis实现的分布式锁; RedLock官网说明 Distributed locks with Redis,英文不好的小伙伴,可以参考这篇文章,坐着翻译的还不错 《Redis分布式锁RedLock》
个人总结如下:
假设我们有N(假设5)个Redis master实例,所有节点相互独立,并且业务系统也是单纯的调用,并没有什么其他的类似消息重发之类的辅助系统。下面来模拟一下算法:
释放比较简单,直接删除所有实例上对应的key就好。确定要释放的是自己所的value.别释放了他人的。
以上是RedLock释放锁的源码,用到了
Future模式、Lua脚本,这部分可以自己了解下,看源码总是头疼,但是大牛写的源码就是这样。以后会专门写一篇分析redLock源码的文章。
标签:表示 通过 future模式 安全 客户 redis margin 缺陷 场景
原文地址:https://www.cnblogs.com/amberJava/p/12593648.html