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

分布式锁的执行顺序,有服务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做分布式锁的更多相关文章

  1. 程序员修神之路--redis做分布式锁可能不那么简单

    菜菜哥,复联四上映了,要不要一起去看看? 又想骗我电影票,对不对? 呵呵,想去看了叫我呀 看来你工作不饱和呀 哪有,这两天我刚基于redis写了一个分布式锁,很简单 不管你基于什么做分布式锁,你觉得很 ...

  2. Redis除了做缓存--Redis做消息队列/Redis做分布式锁/Redis做接口限流

    1.用Redis实现消息队列 用命令lpush入队,rpop出队 Long size = jedis.lpush("QueueName", message);//返回存放的数据条数 ...

  3. Redis++:Redis做分布式锁真的靠谱吗

    Redis做分布式锁真的靠谱吗 Redis的分布式锁可以通过Lua进行实现,通过setnx和expire命令连用的方式 || 也可以使用高版本的方法同时设置失效时间,但是假如在以下情况下,就会造成无锁 ...

  4. redis咋么实现分布式锁,redis分布式锁的实现方式,redis做分布式锁 积极正义的少年

    前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...

  5. 基于 Redis 做分布式锁

    基于 REDIS 的 SETNX().EXPIRE() 方法做分布式锁 setnx() setnx 的含义就是 SET if Not Exists,其主要有两个参数 setnx(key, value) ...

  6. redis 做分布式锁

    ok 我们从最基础的一步步来 加锁: 1.setNx没有expire,拿锁线程挂掉后,死锁 2.setNx然后exipre分两步做,setNx后redis宕机,或者线程挂掉,死锁 3.SETNX re ...

  7. 使用redis做分布式锁

    1.使用setnx命令.先看下官方文档http://redis.cn/commands/setnx.html 2.使用getset命令.先获取,再set 实现案例: * create 2018-12- ...

  8. 面试题详解:如何用Redis实现分布式锁?

    说一道常见面试题: 使用Redis分布式锁的详细方案是什么? 一个很简单的答案就是去使用 Redission 客户端.Redission 中的锁方案就是 Redis 分布式锁的比较完美的详细方案. 那 ...

  9. 基于redis 实现分布式锁的方案

    在电商项目中,经常有秒杀这样的活动促销,在并发访问下,很容易出现上述问题.如果在库存操作上,加锁就可以避免库存卖超的问题.分布式锁使分布式系统之间同步访问共享资源的一种方式 基于redis实现分布式锁 ...

随机推荐

  1. .NET 文件格式相关开源项目

    在过去的2年里,我已确定把文件格式作为我的主要研究课题之一,NPOI就是在这样的研究课题下的产物.尽管从严格意义上讲NPOI只是POI的.NET版本,并不是我创造的,但是在开发过程中,我对OLE2有了 ...

  2. Dev_VGridControl的使用

    这个控件适合GridControl 控件相对应的,用来竖排显示用户数据,具体效果如下图: 实现这个效果用户可以参见官方帮助文档中的如下图所示的内容: 这里我对我用到的Category Rows(分类显 ...

  3. EXSI6怎么设置虚拟机从光驱启动

    EXSI在安装完系统以后会默认从磁盘启动,假如需要进入救援模式则需要设置成光驱启动 设置

  4. disconf安装问题

    安装参考文档:https://blog.csdn.net/fengyao1995/article/details/66491226 主要说说遇到的几个问题 1.在步骤6构建的时候,用jdk1.8,进行 ...

  5. 2018-2019-2 20165317《网络对抗技术》Exp1 PC平台逆向破解

    2018-2019-2 20165317<网络对抗技术>Exp1 PC平台逆向破解 实验目的 掌握NOP, JNE, JE, JMP, CMP汇编指令的机器码 NOP:无作用,英文&quo ...

  6. tarjan算法(强连通分量 + 强连通分量缩点 + 桥(割边) + 割点 + LCA)

    这篇文章是从网络上总结各方经验 以及 自己找的一些例题的算法模板,主要是用于自己的日后的模板总结以后防失忆常看看的, 写的也是自己能看懂即可. tarjan算法的功能很强大, 可以用来求解强连通分量, ...

  7. 001-zookeeper 简介-paxos算法,zk简介,特点

    一.概述 大数据体系概述 1.1.什么是zookeeper 是Google的Chubby一个开源的实现,是Hadoop的分布式协调服务 它包含一个简单的原语集,分布式应用程序可以基于他实现同步服务,配 ...

  8. 如何创建自己的composer包

    composer中文网 :https://www.phpcomposer.com/ 一.前期准备: composer 安装 Windows安装: 1.下载安装包,https://getcomposer ...

  9. jenkins深入学习

    一.jenkins深入学习 一.jenkins项目配置 1.Jenkins Gitlab持续集成打包平台搭建 http://blog.csdn.net/zgzhaobo/article/details ...

  10. nginx中的超时设置,请求超时、响应等待超时等

    nginx比较强大,可以针对单个域名请求做出单个连接超时的配置. 比如些动态解释和静态解释可以根据业务的需求配置 proxy_connect_timeout :后端服务器连接的超时时间_发起握手等候响 ...