这篇文章主要是对 Redis 官方网站刊登的 Distributed locks with Redis 部分内容的总结和翻译。

什么是 RedLock

Redis 官方站这篇文章提出了一种权威的基于 Redis 实现分布式锁的方式名叫 Redlock,此种方式比原先的单节点的方法更安全。它可以保证以下特性:

安全特性:互斥访问,即永远只有一个 client 能拿到锁

避免死锁:最终 client 都可能拿到锁,不会出现死锁的情况,即使原本锁住某资源的 client crash 了或者出现了网络分区

容错性:只要大部分 Redis 节点存活就可以正常提供服务

怎么在单节点上实现分布式锁

SET resourcename myrandom_value NX PX 30000

主要依靠上述命令,该命令仅当 Key 不存在时(NX保证)set 值,并且设置过期时间 3000ms (PX保证),值 myrandomvalue 必须是所有 client 和所有锁请求发生期间唯一的,释放锁的逻辑是:

ifredis.call("get",KEYS[1])==ARGV[1]then

returnredis.call("del",KEYS[1])

else

return0

end

上述实现可以避免释放另一个client创建的锁,如果只有 del 命令的话,那么如果 client1 拿到 lock1 之后因为某些操作阻塞了很长时间,此时 Redis 端 lock1 已经过期了并且已经被重新分配给了 client2,那么 client1 此时再去释放这把锁就会造成 client2 原本获取到的锁被 client1 无故释放了,但现在为每个 client 分配一个 unique 的 string 值可以避免这个问题。至于如何去生成这个 unique string,方法很多随意选择一种就行了。

Redlock 算法

算法很易懂,起 5 个 master 节点,分布在不同的机房尽量保证可用性。为了获得锁,client 会进行如下操作:

得到当前的时间,微妙单位

尝试顺序地在 5 个实例上申请锁,当然需要使用相同的 key 和 random value,这里一个 client 需要合理设置与 master 节点沟通的 timeout 大小,避免长时间和一个 fail 了的节点浪费时间

当 client 在大于等于 3 个 master 上成功申请到锁的时候,且它会计算申请锁消耗了多少时间,这部分消耗的时间采用获得锁的当下时间减去第一步获得的时间戳得到,如果锁的持续时长(lock validity time)比流逝的时间多的话,那么锁就真正获取到了。

如果锁申请到了,那么锁真正的 lock validity time 应该是 origin(lock validity time) - 申请锁期间流逝的时间

如果 client 申请锁失败了,那么它就会在少部分申请成功锁的 master 节点上执行释放锁的操作,重置状态

失败重试

如果一个 client 申请锁失败了,那么它需要稍等一会在重试避免多个 client 同时申请锁的情况,最好的情况是一个 client 需要几乎同时向 5 个 master 发起锁申请。另外就是如果 client 申请锁失败了它需要尽快在它曾经申请到锁的 master 上执行 unlock 操作,便于其他 client 获得这把锁,避免这些锁过期造成的时间浪费,当然如果这时候网络分区使得 client 无法联系上这些 master,那么这种浪费就是不得不付出的代价了。

放锁

放锁操作很简单,就是依次释放所有节点上的锁就行了

性能、崩溃恢复和 fsync

如果我们的节点没有持久化机制,client 从 5 个 master 中的 3 个处获得了锁,然后其中一个重启了,这是注意 整个环境中又出现了 3 个 master 可供另一个 client 申请同一把锁! 违反了互斥性。如果我们开启了 AOF 持久化那么情况会稍微好转一些,因为 Redis 的过期机制是语义层面实现的,所以在 server 挂了的时候时间依旧在流逝,重启之后锁状态不会受到污染。但是考虑断电之后呢,AOF部分命令没来得及刷回磁盘直接丢失了,除非我们配置刷回策略为 fsnyc = always,但这会损伤性能。解决这个问题的方法是,当一个节点重启之后,我们规定在 max TTL 期间它是不可用的,这样它就不会干扰原本已经申请到的锁,等到它 crash 前的那部分锁都过期了,环境不存在历史锁了,那么再把这个节点加进来正常工作。

redlock java_Redlock分布式锁相关推荐

  1. 分布式锁之三:Redlock实现分布式锁

    之前写过一篇文章<如何在springcloud分布式系统中实现分布式锁?>,由于自己仅仅是阅读了相关的书籍,和查阅了相关的资料,就认为那样的是可行的.那篇文章实现的大概思路是用setNx命 ...

  2. 如何用Redlock实现分布式锁

    转:https://blog.csdn.net/forezp/article/details/70305336 之前写过一篇文章<如何在springcloud分布式系统中实现分布式锁?>( ...

  3. RedLock 实现分布式锁

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

  4. 快来学习Redis 分布式锁的背后原理

    以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存.可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单.在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情况是这 ...

  5. 掌握Redis分布式锁的正确姿势

    本文中案例都会在上传到git上,请放心浏览 git地址:https://github.com/muxiaonong/Spring-Cloud/tree/master/order-lock 本文会使用到 ...

  6. Database · 理论基础 · 关于一致性协议和分布式锁

    关于一致性协议, 分布式锁以及如何使用分布式锁 最近看antirez 和 Martin 关于redlock 的分布式锁是否安全的问题的争吵, 非常有意思 http://martin.kleppmann ...

  7. redisson版本_Redisson实现Redis分布式锁的N种姿势

    来源:公众号 阿飞的博客 , 作者 阿飞的博客 前几天发的一篇文章<Redis分布式锁最牛逼的实现>,引起了一些同学的讨论,也有一些同学提出了一些疑问,这是好事儿.本文在讲解如何使用Red ...

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

    点击蓝色"程序猿DD"关注我哟 来源:阿飞的博客 前几天发的一篇文章<Redlock:Redis分布式锁最牛逼的实现>,引起了一些同学的讨论,也有一些同学提出了一些疑问 ...

  9. 还不知道 Redis 分布式锁的背后原理?还不赶快学习一下

    前言 以前在学校做小项目的时候,用到Redis,基本也只是用来当作缓存.可阿粉在工作中发现,Redis在生产中并不只是当作缓存这么简单.在阿粉接触到的项目中,Redis起到了一个分布式锁的作用,具体情 ...

最新文章

  1. 如何在MFC中使用cout和printf,输出到控制台
  2. 报名软件批次分类code不能为空_技能鉴定报名软件使用说明
  3. Cent6.5 64位yum安装mysql5.5
  4. MySQL 授权用户 ; 存储过程的DEFINER; 命令分隔符DELIMITER
  5. sigmstar SSD201/SSD202 openwrt--应用支持分享
  6. 统计学最全脑图,你只管打开它,剩下的交给「卧槽」
  7. Cornfox Bros.如何将手游移植到Switch
  8. Hadoop学习之yarn
  9. python如何获取输入_python如何从键盘获取输入实例
  10. 【python基础知识】python输出时出错,UnicodeEncodeError: 'gbk' codec can't encode character '\ue4bf.....
  11. 关于Java中子类调用父类方法
  12. 零基础带你学习MySQL—备份恢复数据库(三)
  13. 马哥教育20-2期27号学员的7.27上课笔记
  14. 迅为i.MX6Q开发板-红外 hs0038 测试
  15. 无法格式化sd卡怎么办 sd卡无法格式化怎么弄
  16. 162-SOP8液晶手写板专用IC
  17. Win10开始菜单中使用搜索时没有反应(解决办法)
  18. sci四区大水刊 计算机,sci四区大水刊_sci四区免费大水刊_sci四区什么水平
  19. Oracle EBS 接收事务处理类型 rcv_transactions transaction_type
  20. IOS-简单的自建ipa在线安装服务

热门文章

  1. python多线程操作字典_在Python中使用带有线程的全局字典
  2. python 机器学习_基于 Python 语言的机器学习工具Sklearn
  3. 红旗Linux网卡绑定,Linux bonding 之balance-alb 原理介绍及其实现
  4. oracle用户编辑文件中文乱码
  5. Centos7 安装docker和docker-compose
  6. linux环境 Oracle客户端连接远程Oracle服务端
  7. IDEA中新建项目Static Web 中没有vue.js
  8. form表单提交,后台实体类接收转义问题 解决方案
  9. Flowable通过api查询流程返回流程图节点
  10. idea maven插件tomcat内存溢出