redis分布式锁的一个简单直接的实现方法就是用 SET NX 命令设置一个设定了存活周期 TTL 的 Key 来获取锁,通过删除 Key 来释放锁,通过存活周期来避免死锁。不过这个方法存在单点故障风险,如果部署了 master/slave 节点,则在特定条件下可能会导致安全性方面的冲突,比如:

  1. 客户端 A 从 master 节点获得锁
  2. master 节点在将 key 复制到 slave 节点之前崩溃了
  3. slave 节点提升为新的 master 节点
  4. 客户端 B 从新的 master 节点获得了锁,而这个锁实际上已经由客户端 A 所持有,导致了系统中有两个客户端在同一时间段内持有同一个互斥锁,破坏了互斥锁的安全性。

redis官方给出一个高可用分布式锁的实现:https://redis.io/topics/distlock

在 Redlock 算法中,通过类似于下面这样的命令进行加锁: SET resource_name my_random_value NX PX 30000

建立一个有 N(N 为奇数)个节点的redis集群,这种情况下,一个客户端获得锁和释放锁的算法如下:

  1. 先获取当前时间戳 timestamp_1,以毫秒为单位。
  2. 以相同的 Key 和随机数值,依次从 N 个节点获取锁,每次获取锁都设置一个超时,超时时限要保证小于所有节点上该锁的自动释放时间,以免在某个节点上耗时过长,通常都设的比较短。
  3. 客户端将当前时间戳减去第一步中的时间戳 timestamp_1,计算获取锁总消耗时间。只有当客户端获得了半数以上节点的锁,而且总耗时少于锁存活时间,该客户端才被认为已经成功获得了锁。
  4. 如果获得了锁,则其存活时间为开始预设锁存活时间减去获取锁总耗时间。
  5. 如果客户端不能获得锁,则应该马上在所有节点上解锁。
  6. 如果要重试,则在随机延时之后重新去获取锁。
  7. 获得了锁的客户端要释放锁,在所有节点上解锁即可。

Redlock 算法不需要保证 Redis 节点之间的时钟是同步的(不论是物理时钟还是逻辑时钟),这点和传统的一些基于同步时钟的分布式锁算法有所不同。

Redis分布式锁实现的更多相关文章

  1. 利用redis分布式锁的功能来实现定时器的分布式

    文章来源于我的 iteye blog http://ak478288.iteye.com/blog/1898190 以前为部门内部开发过一个定时器程序,这个定时器很简单,就是配置quartz,来实现定 ...

  2. Redis分布式锁

    Redis分布式锁 分布式锁是许多环境中非常有用的原语,其中不同的进程必须以相互排斥的方式与共享资源一起运行. 有许多图书馆和博客文章描述了如何使用Redis实现DLM(分布式锁管理器),但是每个库都 ...

  3. redis分布式锁和消息队列

    最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存不同,利用的是redis可设置key的有效时间和redis的BRPOP命令. 分布式锁 由于目前一些编程语言,如PHP ...

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

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

  5. spring boot redis分布式锁

    随着现在分布式架构越来越盛行,在很多场景下需要使用到分布式锁.分布式锁的实现有很多种,比如基于数据库. zookeeper 等,本文主要介绍使用 Redis 做分布式锁的方式,并封装成spring b ...

  6. Redis分布式锁的正确实现方式

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

  7. Redis分布式锁---完美实现

    这几天在做项目缓存时候,因为是分布式的所以需要加锁,就用到了Redis锁,正好从网上发现两篇非常棒的文章,来和大家分享一下. 第一篇是简单完美的实现,第二篇是用到的Redisson. Redis分布式 ...

  8. redis分布式锁实践

    分布式锁在多实例部署,分布式系统中经常会使用到,这是因为基于jvm的锁无法满足多实例中锁的需求,本篇将讲下redis如何通过Lua脚本实现分布式锁,不同于网上的redission,完全是手动实现的 我 ...

  9. Redis分布式锁的try-with-resources实现

    Redis分布式锁的try-with-resources实现 一.简介 在当今这个时代,单体应用(standalone)已经很少了,java提供的synchronized已经不能满足需求,大家自然 而 ...

  10. 关于分布式锁原理的一些学习与思考-redis分布式锁,zookeeper分布式锁

    首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保,在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法.变量. 在一个进程中,也就是一个jvm 或者说应用中,我们很容易去处理控制,在j ...

随机推荐

  1. div中文字上下居中

    <div class="title">Title</div> 1. 将div高度设成定值 2. 将line-height设成定值 3. 将text-alig ...

  2. -bash: /etc/init.d/nginx: /bin/bash^M: bad interpreter: No such file or directory

    -bash: /etc/init.d/nginx: /bin/bash^M:bad interpreter: No such file or directory 这个使为了弄nginx自启的,然后在官 ...

  3. 前端框架之Vue.js

    前言: 前端主流框架有Vue.react.angular,目前比较火因为Vue比较容易学习,运营起来比较快速: Vue是什么呢? 是一个基于MVVM架构的,前端框架: 如果你之前已经习惯了用jQuer ...

  4. for循环的字节码

    源代码: public class Wizard { private int age; private void forCycle() { for (int i = 0; i < 10; i++ ...

  5. spark使用正则表达式读入多个文件

    String dir = "s3a://example/";String currentDir = dir + "{1[5-9],2[01]}/*.txt";J ...

  6. POJ 1936 All in All 匹配, 水题 难度:0

    题目 http://poj.org/problem?id=1936 题意 多组数据,每组数据有两个字符串A,B,求A是否是B的子串.(注意是子串,也就是不必在B中连续) 思路 设置计数器cnt为当前已 ...

  7. OO第三次课程总结分析

    OO第三次课程总结分析 规格化设计发展历史 在网上找了好久也没找到合适的信息,稍稍参考了同学的博客.大致如下:最初的的软件并没有形式化方法,随着软件工程的兴起,为了便于工程间的协调管理,人们提出采用工 ...

  8. flask项目结构(一)mariadb

    简介: 本文主要是根据自己所学,创建一个flask项目,使用sqlalchemy,alembic,mariadb,bootstrap,APScheduler,selenium,request…………技 ...

  9. Java获取系统时间的四种方法

    1.Date day=new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); ...

  10. java中的方法method

    java中的方法必须存在于类class里,不能独立存在.类是描述具有某种特征的事物,方法则是这类 事物具有的某种功能,通过调用方法可以实现某种特定的功能.方法名一般以小写的动词开头. 例: publi ...