redis分布式锁优化如何实现?本篇文章小编给大家分享一下redis分布式锁优化实现代码,文章代码介绍的很详细,小编觉得挺不错的,现在分享给大家供大家参考,有需要的小伙伴们可以来看看。
对于单机的应用来说,可以直接使用synchronized关键字或着Lock工具类来加锁;但是对于分布式应用我们需要凭借一些工具来实现加锁;
加锁流程通俗来解释就是:
1. 占坑
2. 执行逻辑
3. 填坑
我们可以使用redis来完成占坑这个操作;
基础版加锁
//通过占坑的方式获取锁 boolean lock = redis.setIfAbsent(key, value); if (lock) { //业务逻辑 //填坑 redis.delete(lock) }
如果获取锁之后,应用宕机导致未释放锁,会造成死锁
获取锁的时候需要给锁添加过期时间
redis.setIfAbsent(key, value); redis.expire(key, value);
如果在获取锁的时候,意外导致过期时间没设置成功,也会导致死锁
通过lua脚本将set、expire两个操作合并成原子操作,确保过期时间能设置成功
如果锁过期了,但是当前任务未执行结束,此时锁就可能被其他应用获取到,并更新锁的key。如果此时当前任务执行结束去释放锁,会将别人的锁给释放掉
释放锁:
判断当前锁的值和自己上锁的值是不是吻合的;
如果不吻合则不释放;
如果值吻合,就删除key释放锁;
在释放锁的时候,如果判断key值吻合,但此时key过期了,锁被别人获取到,此时再删除key,就是释放了别人的锁了
要保证查询、判断、删除逻辑为原子操作,使用lua脚本
如何保证锁的可重入
如果在递归方法有加锁逻辑或其他调用有
lock.lock(); //逻辑 lock.lock(); //逻辑 lock.unLock(); lock.unLock();
要实现可重入锁,可以在锁的value值上做文章,在value值上记录重入次数,每次重入次数加一,每次unlock次数减一,直至为零,则删除key 释放锁;
key: { "value":1 }
如果业务逻辑时间过长,锁提前过期释放了怎么办
将过期时间设置的长一点
需要给锁添加续期功能。
设置长过期时间的弊端就是,如果应用宕机之后锁需要经历较长的时间才能被别人获取,影响业务;
如果是有续期功能的话,如果宕机,锁也会被较短的过期时间给刷掉,是种更优美的解决方式;
如redission中获取锁后,会启动一个watchDog线程来监控当前线程是否还持有锁,如果还持有锁,就给他续期
具体操作为: 每十秒检查一下是否持有锁,如果锁未释放就重置一下锁的过期时间,实现续期;
如果应用在redis的master节点上获取锁成功,此时该master节点宕机,且锁数据还未同步到slave节点上,主从切换之后,其他应用趁机也获取了分布式锁
redLock
主从结构不是会有问题吗,redlock就换成使用多个不相关的、没有主从关系的redisMaster节点,来保证他们不会同时宕机,总数最好为奇数个。
redLock通过在多个节点上同时获取锁,如果超过半数的节点都获取锁成功,才算成功;否则失败,回滚删除所有节点的锁。
创造与魔法 安卓版v1.0.0750
创造与魔法是一款开放世界手游,在游戏中玩家可探索这个奇妙的世
创造与魔法修改版 最新版v1.0.0750
创造与魔法无限点券版是款探索冒险游戏,该款游戏的操作还是蛮自
战争与文明官方版本 安卓版v1.7.16
战争与文明是一款由上海邮通科技有限公司开发的战争策略游戏,这
迷你世界0元领皮肤无限迷你币版 最新安卓版v1.43.0
迷你世界0元购买皮肤版是这款开放沙盒冒险建造游戏的特殊破解版
创造与魔法无限经验版 安卓版v1.0.0750
创造与魔法无限经验版是款可以改造环境,整个游戏的自由度还是蛮