此文是对http://zhangtielei.com/posts/blog-redlock-reasoning-part2.html文章的个人归纳,如有问题请联系删除

什么是redlock

redlock是redis给出的分布式锁的实现规范

先说说基于单节点redis实现的分布式锁

SET resource_name random_value NX PX 30000 如果执行成功说明获取到锁了

random_value需要设置一个唯一标识避免冲突

resource_name 只有不存在的时候才能set成功 代表获取到了锁

px 30000 代表过期时间30秒

需要注意的是

1. 过期时间必须得设置 避免锁不能释放的情况

2. random_value还是很有必要的必须不重复 确保锁只能被锁的持有者删除

  举例:

  A获取锁 执行超过px时间 锁被释放

  B获取锁成功 执行

  A执行完释放锁 这时B是没有锁保护的

3. 释放锁必须要用lua脚本保证原子性

4. 在主从的情况下,A在master获取到锁 如果master宕机 并且 key还未同步到slave B从slave也可以获取到锁

由于第4点 单节点redis无法解决这个问题,所以才有了redlock

redlock算法获取锁的步骤

1. 记录当前时间

2. 按顺序依次向客户端申请锁,跟单节点申请锁一样只是多了一个超时时间用于redis节点不可用的情况(几十毫秒级别),获取锁失败立即向下一个客户端申请锁

3. 当前时间减去第一步获取的时间,如果n/2+1的节点获取锁成功,并且消耗时间未超过锁的有效时间,获取锁成功否则失败

4.重新计算锁的有效时间,有效时间减去第三步算出来的时间

5. 如果失败则向所有的redis节点发送lua删除锁操作 (避免redis加锁成功但是客户端未受到消息的情况)

虽然避免了failover但是 节点崩溃重启的时候仍然有安全性问题

1. A客户端锁住了 123节点 45没锁住

2. 此时3节点崩溃但是A客户端在上面加的锁未持久化

3. 3节点重启 B客户端锁住了 345 获取锁成功

解决方法有:

1. 延迟重启,节点崩溃了不立即重启,而是等到超过锁的失效时间之后再重启

依赖系统时钟导致的不安全性

1. A客户端在123节点获取锁成功

2.3节点时钟发生向前跳跃只是3节点上的锁过期

3.B客户端获取了345节点的锁

gc pause导致的不安全性

1. A客户端在接收到12345节点的成功获取锁之前 进行了gc pause超过了锁的有效时间

2. B客户端获取了123节点的锁

3. A节点恢复过来之后 拿到了成功的结果 认为自己获取锁成功了

注意:这个是在获取到成功信息之前 锁就过期了,以前是客户端获取到成功信息之后 锁才过期,破坏了锁服务本身的安全性 这个是不成立的对于redlock 因为redlock有一步是检查获取锁的时间是否超过锁的有效时间

zookeeper实现分布式锁

zookeeper的比redis功能多的地方是

创建/node之后 如果客户端长时间不能应答心跳 zookeeper会删除这个失联客户端创建的所有node节点 不用想redis一样考虑如何设置锁的过期时间

如果锁被A客户端持有,B客户端来申请锁失败,这时B客户端可以watch这个/node 当node锁被释放的时候 通知客户端B去获取锁 实现阻塞等待的功能

redlock分布式锁真的安全吗的更多相关文章

  1. 基于Redis的分布式锁真的安全吗?

    说明: 我前段时间写了一篇用consul实现分布式锁,感觉理解的也不是很好,直到我看到了这2篇写分布式锁的讨论,真的是很佩服作者严谨的态度, 把这种分布式锁研究的这么透彻,作者这种技术态度真的值得我好 ...

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

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

  3. RedLock 实现分布式锁

    J并发是程序开发中不可避免的问题,根据系统面向用户.功能场景的不同,并发的重视程度会有不同.从程序的角度来说,并发意味着相同的时间点执行了相同的代码,而有些情况是不被允许的,比如:转账.抢购占库存等, ...

  4. 在.Net中使用RedLock实现分布式锁

    ⒈简介 RedLock 分布式锁算法由 Redis 的作者提出,大部分语言都有对应的实现,查看,RedLock.net 是 RedLock 分布式锁算法的 .NET 版实现,用来解决分布式下的并发问题 ...

  5. Lua脚本在redis分布式锁场景的运用

    目录 锁和分布式锁 锁是什么? 为什么需要锁? Java中的锁 分布式锁 redis 如何实现加锁 锁超时 retry redis 如何释放锁 不该释放的锁 通过Lua脚本实现锁释放 用redis做分 ...

  6. Redis 分布式锁进化史(解读 + 缺陷分析)

    Redis分布式锁进化史 近两年来微服务变得越来越热门,越来越多的应用部署在分布式环境中,在分布式环境中,数据一致性是一直以来需要关注并且去解决的问题,分布式锁也就成为了一种广泛使用的技术,常用的分布 ...

  7. 一文看透 Redis 分布式锁进化史(解读 + 缺陷分析)(转)

    近两年来微服务变得越来越热门,越来越多的应用部署在分布式环境中,在分布式环境中,数据一致性是一直以来需要关注并且去解决的问题,分布式锁也就成为了一种广泛使用的技术,常用的分布式实现方式为Redis,Z ...

  8. Redisson实现Redis分布式锁的N种姿势(转)

    Redis几种架构 Redis发展到现在,几种常见的部署架构有: 单机模式: 主从模式: 哨兵模式: 集群模式: 我们首先基于这些架构讲解Redisson普通分布式锁实现,需要注意的是,只有充分了解普 ...

  9. 一篇文章带你解读Redis分布式锁的发展史和正确实现方式

    前言 近两年来微服务变得越来越热门,越来越多的应用部署在分布式环境中,在分布式环境中,数据一致性是一直以来需要关注并且去解决的问题,分布式锁也就成为了一种广泛使用的技术,常用的分布式实现方式为Redi ...

随机推荐

  1. D. Rescue Nibel! 解析(思維、組合、離散化、差分)

    Codeforce 1420 D. Rescue Nibel! 解析(思維.組合.離散化.差分) 今天我們來看看CF1420D 題目連結 題目 給你\(n\)個區間,求有幾種方法使得\(k\)個區間的 ...

  2. Mybatis---06Mybatis配置文件浅析(四)

    参考链接:深入理解Mybatis插件开发 1.plugins:与其称为Mybatis插件,不如叫Mybatis拦截器,更加符合其功能定位,实际上它就是一个拦截器,应用代理模式,在方法级别上进行拦截. ...

  3. python打印水仙花数的个人总结

    面试过程中,提到python,面试最多的就是让你现场写代码实现水仙花.冒泡.九九乘法表,这些面试方法旨在校验面试者的python基础和思维逻辑. 先从水仙花说起,水仙花是指一个n位正整数(n>= ...

  4. NB-IoT的低功耗是怎么实现的?

    NB-IoT的低功耗是怎么实现的? NB-IoT可以实现低功耗的一个主要原因就是NB-IoT设备的用户终端在省电模式下依然可以工作,这种工作模式可以极大的降低电量的消耗和延长电池使用寿命.在省电模式下 ...

  5. Java学习的第三十四天

    1.今天复习完了第十二章 2.有很多的方法不知道什么意思,也记不清该用什么方法. 3.明天写例题.

  6. git rebase的时候捅娄子了,怎么办?在线等……

    大家在使用git的过程当中有闯过祸吗? 我闯过,我闯的第一个祸就是使用git rebase造成的,虽然后来最终还是解决了,但是还是给我吓得不轻.当时的事情是这样的. 我们来看下这张图: 简单解释一下这 ...

  7. Python爬虫简单实现CSDN博客文章标题列表

    Python爬虫简单实现CSDN博客文章标题列表 操作步骤: 分析接口,怎么获取数据? 模拟接口,尝试提取数据 封装接口函数,实现函数调用. 1.分析接口 打开Chrome浏览器,开启开发者工具(F1 ...

  8. C的输入&输出

    格式说明符 输出 %d整型输出,%ld长整型输出, %o以八进制数形式输出整数, %x以十六进制数形式输出整数,或输出字符串的地址. %u以十进制数输出unsigned型数据(无符号数).注意:%d与 ...

  9. HTML5 实现的一个俄罗斯方块实例代码

    /*实现的功能:方块旋转(W键).自动下落.移动(ASD).消行.快速下落(空格键).下落阴影.游戏结束.*/ <!DOCTYPE html>   <html>    < ...

  10. Git常用命令【ZeyFra】

    // 账户设置 git config --global user.name "ZeyFra" git config --global user.email "zeyfra ...