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实现分布式锁 ...
随机推荐
- 用cocoapods导入第三方库,找不到对应的文件
解决办法 1.找到TARGETS -> Build Settings -> SearchPaths -> User Header Search Paths 在后面的空白处双击 2. ...
- Linux下的文件切割和文件合并
linux下文件分割可以通过split命令来实现,可以指定按行数分割和按大小分割两种模式.Linux下文件合并可以通过cat命令来实现. 在Linux下用split进行文件分割: ①:指定分割后文件行 ...
- AUC计算 - 进阶操作
首先AUC值是一个概率值,当你随机挑选一个正样本以及负样本,当前的分类算法根据计算得到的Score值将这个正样本排在负样本前面的概率就是AUC值,AUC值越大,当前分类算法越有可能将正样本排在负样本前 ...
- 剑指offer——python【第39题】平衡二叉树
题目描述 输入一棵二叉树,判断该二叉树是否是平衡二叉树. 解题思路 平衡二叉树首先是二叉搜索树,且它每个节点的左子树和右子树高度差至多等于1:只要从根节点,依次递归判断每个节点是否满足如上条件即可 ...
- 解决C#中FileSystemWatcher类的Changed事件触发多次的问题
public static void WatchFile() { FileSystemWatcher watcher = new FileSystemWatcher(); watcher.Path = ...
- dtFindNearestPolyQuery :: process
dtFindNearestPolyQuery :: process(const dtMeshTile* tile, dtPoly** polys, dtPolyRef* refs, int count ...
- 多个if语句和else if区别
多个if是所有的if都会进行判断if else if是只要有满足条件的,就不再对之后的else if进行判断比如a = 2;if(a==1) c=1;if(a==2) c=2;if(a%2==0) c ...
- easyui dialog 中 panel-body 高度太小出现 滚动条 的原因
easyui dialog 中 panel-body 高度太小出现 滚动条 的原因: dialog 高度比 iframe 高度大79 就可以了 $.editcompanypersoninfo = fu ...
- keepalived + nginx 实现双机热备
# docker run -itd --name centos_m1 centos # 进入容器 # docker exec -it centos_m1 /bin/bash # 安装nginx # r ...
- 报文分析6、ARP报头结构
ARP报头结构 硬件类型 协议类型 硬件地址长度 协议长度 操作类型 发送方的硬件地址(0-3字节) 源物理地址(4-5字节) 源IP地址(0-1字节) 源IP地址(2-3字节) 目标硬件地址(0 ...