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

分布式锁的执行顺序,有服务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. angular.js使用ui-router注入报错,这里是版本问题导致的

    报错如下: common.ts:604Uncaught SyntaxError: Unexpected token ) stateEvents.ts:211Uncaught SyntaxError: ...

  2. Tornado-基于正则的路由和动态分页

    概览 这一小节涉及了三部分内容: 1.动态分页设计 2.基本的路由系统以及基于正则的路由 3.模块引擎的继承和导入 4.web项目文件夹和ReuquestHandler的分类 5.跨站脚本攻击 文件结 ...

  3. 变量类型-Tuple

    教程:一:元组的创建        元组(tuple)与列表类似,不同之处在于元组的元素不能修改    (1)tuple写在圆括号之间,元素用逗号隔开    (2)元组元素的类型可以不同    (3) ...

  4. Git飞行规则

    原文链接 Git飞行规则(Flight Rules)

  5. Autofac之类型注册

    本次主要学习一下Autofac中实现类型注册的几种方式,这里并不打算一开始就从基于接口开发的服务关联切入,而是先从一个简单的类型注册来学起,虽然实际开发中可能不会这么做,但是个人感觉从这里学起理解能能 ...

  6. Ubuntu18.04 快速返回桌面 【快捷键】

    设置->设备->键盘->窗口->隐藏窗口 :双击重置快捷键

  7. oracle根据某个字段的值进行排序

    需求:按照颜色为蓝色.红色.黄色进行排序: order by  case                  when color = '蓝色' then                   1     ...

  8. React之ref

    作为响应式开发框架React,我们知道他是数据驱动的,但有时候避免不了还是得动用到DOM操作,这个时候我们就可以用到ref:用法如下: 然后这样做有个弊端,当一个 ul 下面的 li 是动态添加的时候 ...

  9. spring 数据库多数据源路由

    项目中需要根据不同业务进行分库,首先是将业务不同业务映射到不同过的数据库( biz --> db,可能存在多对一情况), 查看springjdbc源码发现AbstractRoutingDataS ...

  10. Mysql8安装与配置

    网上的教程有很多,基本上大同小异.但是安装软件有时就可能因为一个细节安装失败.我也是综合了很多个教程才安装好的,所以本教程可能也不是普遍适合的. 安装环境:win7 1.下载zip安装包: MySQL ...