博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Redis做分布式锁
阅读量:7240 次
发布时间:2019-06-29

本文共 1155 字,大约阅读时间需要 3 分钟。

在分布式系统中,在接口没有保证幂等性或者在某些场景下相同的服务需要有且仅有一个服务执行的情况下,需要使用分布式锁来保证系统的安全执行。

分布式锁的执行顺序,有服务A,分别部署了三个节点为A1A2A3,为满足我们上述需求,我们需要在共享的数据载体中做标记,即,A1开始执行的话,A2A3不能在执行,直到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+1Redis实例取到锁或者取锁时间已经超过了有效时间),客户端应该在所有的Redis实例上进行解锁(即便某些Redis实例根本就没有加锁成功,防止某些节点获取到锁但是客户端没有得到响应而导致接下来的一段时间不能被重新获取锁)。

这些其实在Redisson里面已经有了很好的实现,截个图吧。

 

 

 

 

 

 

其实,这写下来还有很多疑问,Redis的崩溃选举使用的raft协议,可是数据同步的这一块儿还没有仔细搞清楚,另外哨兵监控感觉也有疑问,慢慢来吧。

参考地址:   

参考地址: 

转载于:https://www.cnblogs.com/yidiandhappy/p/10782629.html

你可能感兴趣的文章
Django进阶
查看>>
栅格布局的两种简单的实现方式
查看>>
PyQt5使用http请求获取天气
查看>>
对象拷贝
查看>>
JVM(一)
查看>>
MapReduce项目之气温统计
查看>>
PHP登录及处理
查看>>
Spring Bean的生命周期(非常详细)
查看>>
《Unix环境高级编程》读书笔记 第8章-进程控制
查看>>
login/logout切换
查看>>
销毁react组件的方法
查看>>
获取VirtualBox COM对象失败,Unable to start the virtual device
查看>>
磁盘阵列柜 和存储有什么区别
查看>>
requests bs4 爬取 资讯 图片
查看>>
zabbix 调用python脚本监控 磁盘剩余空间(创建模版,创建监控项,创建触发器)...
查看>>
LeetCode:453. Minimum Moves to Equal Array Elements
查看>>
python之logging模块
查看>>
JDBC(1)——获取数据库连接
查看>>
并查集专题2
查看>>
ASP.NET中的验证控件
查看>>