Redis做分布式锁
在分布式系统中,在接口没有保证幂等性或者在某些场景下相同的服务需要有且仅有一个服务执行的情况下,需要使用分布式锁来保证系统的安全执行。
分布式锁的执行顺序,有服务A,分别部署了三个节点为A1、A2、A3,为满足我们上述需求,我们需要在共享的数据载体中做标记,即,A1开始执行的话,A2、A3不能在执行,直到A1执行完之后,A2或者A3才能继续执行。
Redis的做法:
1、A1在进入系统后先判断Redis中有没有这个标记(key),没有的话,在Redis中放入一条数据。setNx
2、A2或者A3在进入方法时同样执行这个操作,如果有了这个key,则不再执行该方法。
使用该顺序则可保证在分布式系统中某服务有且仅有一个相同的方法在执行。
但是一般在生产环境Redis都是集群部署的,主节点负责写入,从节点负责读取,Redis集群内部的主从复制广播是需要时间的,主节点接收到,但是还没有往从节点写入,A2就去从节点查了,没有,A2就会发起setNX,造成分布式锁失效。
这时候作者Antirez提出了RedLock方式:
1、代码中获取当前时间,毫秒
2、依次向Redis所有节点放置,相同的key和具有唯一性的value(雪花、UUID等),当向Redis请求获取锁时,客户端应该设置一个网络连接和响应超时时间,这个超时时间应该小于锁的失效时间。例如你的锁自动失效时间为10秒,则超时时间应该在5-50毫秒之间。这样可以避免服务器端Redis已经挂掉的情况下,客户端还在死死地等待响应结果。如果服务器端没有在规定时间内响应,客户端应该尽快尝试去另外一个Redis实例请求获取锁。
3、客户端使用当前时间减去开始获取锁时间(步骤1记录的时间)就得到获取锁使用的时间。当且仅当从大多数(N/2+1,这里是3个节点)的Redis节点都取到锁,并且使用的时间小于锁失效时间时,锁才算获取成功。
4、如果取到了锁,key的真正有效时间等于有效时间减去获取锁所使用的时间(步骤3计算的结果)。
5、如果因为某些原因,获取锁失败(没有在至少N/2+1个Redis实例取到锁或者取锁时间已经超过了有效时间),客户端应该在所有的Redis实例上进行解锁(即便某些Redis实例根本就没有加锁成功,防止某些节点获取到锁但是客户端没有得到响应而导致接下来的一段时间不能被重新获取锁)。
这些其实在Redisson里面已经有了很好的实现,截个图吧。



其实,这写下来还有很多疑问,Redis的崩溃选举使用的raft协议,可是数据同步的这一块儿还没有仔细搞清楚,另外哨兵监控感觉也有疑问,慢慢来吧。
参考地址:https://yq.aliyun.com/articles/674394
参考地址:https://blog.csdn.net/u010963948/article/details/79006572
Redis做分布式锁的更多相关文章
- 程序员修神之路--redis做分布式锁可能不那么简单
菜菜哥,复联四上映了,要不要一起去看看? 又想骗我电影票,对不对? 呵呵,想去看了叫我呀 看来你工作不饱和呀 哪有,这两天我刚基于redis写了一个分布式锁,很简单 不管你基于什么做分布式锁,你觉得很 ...
- Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流
1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...
- Redis++:Redis做分布式锁真的靠谱吗
Redis做分布式锁真的靠谱吗 Redis的分布式锁可以通过Lua进行实现,通过setnx和expire命令连用的方式 || 也可以使用高版本的方法同时设置失效时间,但是假如在以下情况下,就会造成无锁 ...
- redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...
- 基于 Redis 做分布式锁
基于 REDIS 的 SETNX().EXPIRE() 方法做分布式锁 setnx() setnx 的含义就是 SET if Not Exists,其主要有两个参数 setnx(key, value) ...
- redis 做分布式锁
ok 我们从最基础的一步步来 加锁: 1.setNx没有expire,拿锁线程挂掉后,死锁 2.setNx然后exipre分两步做,setNx后redis宕机,或者线程挂掉,死锁 3.SETNX re ...
- 使用redis做分布式锁
1.使用setnx命令.先看下官方文档http://redis.cn/commands/setnx.html 2.使用getset命令.先获取,再set 实现案例: * create 2018-12- ...
- 面试题详解:如何用Redis实现分布式锁?
说一道常见面试题: 使用Redis分布式锁的详细方案是什么? 一个很简单的答案就是去使用 Redission 客户端.Redission 中的锁方案就是 Redis 分布式锁的比较完美的详细方案. 那 ...
- 基于redis 实现分布式锁的方案
在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...
随机推荐
- __x__(40)0909第五天__表格 table 的 css 样式 美化
如果就向下面的代码那样,不写 tbody , 则浏览器自添加 tbody , 并将所有的 tr 移入 tbody 意味着 tr 并非 table 的子元素,而是 tbody 的子元素. 所以 以后编写 ...
- Java课程寒假之《人月神话》有感之三
一.未雨绸缪 作者开始谈论实验室代码如何向开发出来的产品转变,化学工程师通过“实验性工厂”的中间步骤做测试来得到经验.而软件系统的构建人员却是按照时间进度将第一次开发的产品发布给顾客.对于我这只没有实 ...
- 20175320 2018-2019-2 《Java程序设计》第7周学习总结
20175320 2018-2019-2 <Java程序设计>第7周学习总结 教材学习内容总结 本周学习了教材的第八章的内容,在这章中介绍了常用的实用类,着重讲了如何利用String类.S ...
- java_基础_异常
之前只是了解的最基础的异常形式,没有过多的深入 今天因为一些原因了解了一下 下面来说说异常的几种形式 1.try-catch语句块 代码示例 class test{ public static voi ...
- 数学和物理太难?这些 GIF 让你秒懂抽象概念
把科学带回家,给孩子最好的科学教育 觉得数学和物理很抽象很难懂吗?今天我们来分享一组数学和物理相关的动图,让你秒懂抽象概念. 数学动图 △ 从椭圆的一个焦点射出的光线总会通过另一个焦点. △ 真人版. ...
- kali2.0安装docker(转)
开始部署 1. Docker需要Linux Kernels 大于3.10并且是64-bit的机器,用uname -a可以查看是否符合要求. 2. 执行命令编辑文本: vim /etc/apt/sour ...
- promise 的学习
promise 是为了解决异步操作的顺序问题而产生的 特性 promise 的实例一旦创建就会执行里面的异步操作 promise 的实例状态一旦改变就变成凝固的了, 无法再对其作出修改, (不明白为 ...
- yii的数据库相关操作
获取某一列数据 self::find()->where(['pid'=>$this->id])->select('id')->column(); 更新操作 $model- ...
- npm run dev/build/serve
1.ERR引发的思考 npm run dev npm ERR! missing script: dev npm ERR! A complete log of this run can be found ...
- minikube windows hyperx填坑记
minikube windows hyperx填坑记 安装了一天半,还是没行,先放弃 开始 minikube start --vm-driver=hyperv --hyperv-virtual-swi ...