分布式锁的详细解析

分布式锁工具

一、背景

当前问题:项目中会使用到分布式锁用于定时任务、接口幂等性处理,但是分布式锁的实现较简单,会出现执行超时、加解锁失败等场景。分布式锁都有哪些实现,他们的优劣势是什么呢?

二、现有技术

分布式锁实现目的如下图:

1.reids分布式锁实现

  1. 第一种直接通过redis提供的setNx命令执行加锁,可以设置value值。不能设置锁的有效期,如果不调用del命令,会一直存在。
  2. 第二种通过lua脚本执行加锁。可以直接使用set命令进行加锁,然后设置锁的有效期,也可以使用hashSet方式,将所有的锁都保存在同一个hash数组中,通过hash中的key值进行区分,缺点是在redis中hash类型key值有效期是针对整个hashKey的。

以上两种方式都能完成加锁操作,第二种能够自由设置锁的有效期。

基于jimdb的加锁实现方式比较如下

  1. jimdb事务方式:批量传入多个命令后,不间断的执行传入的命令,但不保证原子性
  2. pipeline方式:批量传入多个命令后,与其他请求竞争后执行命令,不保证原子性
  3. lua脚本方式:批量传入多个命令后,原子性的执行
  4. set命令,jimdb直接支持setEx命令,可以在设置锁的同时设置锁的有效期,不支持重入

为什么不能先执行setNx,然后在执行expire命令,这样第一种也有有效期了呢?两个命令分开执行不具有原子性,比如加锁成功了,但在执行expire命令时失败了,还是不具有有效期。

优缺点:

  1. 缺点:即使设置有效期成功了,如果操作共享资源的时间大于过期时间,就会出现锁提前过期的问题,进而导致分布式锁直接失效。如果锁的超时时间设置过长,加过期时间与不加没有了区别。
  2. 优点:通过lua脚本可以实现原子性

2.redisson实现方式

需要手动初始化RedissonLock,然后进行lock操作,内部通过lua脚本的方式进行加锁,方法结束后再finally中进行unlock解锁。如果加锁时不指定过期时间,会自动续期。加锁失败会自动重试

缺点:1.目前redisson未解决redLock问题 2.redisson未解决执行超时情况 3.仅支持redis

3.zookeeper分布式锁实现

ZooKeeper 分布式锁是基于临时顺序节点Watcher(事件监听器)实现的。

  • 临时节点:临时节点的生命周期是与客户端会话(session)绑定的,会话消失则节点消失。并且,临时节点只能做叶子节点,不能创建子节点。
  • Watcher事件监听:是 ZooKeeper 中的一个很重要的特性。ZooKeeper 允许用户在指定节点上注册一些 Watcher,并且在一些特定事件触发的时候,ZooKeeper 服务端会将事件通知到感兴趣的客户端上去,该机制是 ZooKeeper 实现分布式协调服务的重要特性。

获取锁:

  1. 首先要有一个持久节点/locks,客户端获取锁就是在locks下创建临时顺序节点。
  2. 假设客户端 1 创建了/locks/lock1节点,创建成功之后,会判断 lock1是否是 /locks 下最小的子节点。
  3. 如果 lock1是最小的子节点,则获取锁成功。否则,获取锁失败。
  4. 如果获取锁失败,则说明有其他的客户端已经成功获取锁。客户端 1 并不会不停地循环去尝试加锁,而是在前一个节点比如/locks/lock0上注册一个事件监听器。这个监听器的作用是当前一个节点释放锁之后通知客户端 1(避免无效自旋),这样客户端 1 就加锁成功了。

释放锁:

  1. 成功获取锁的客户端在执行完业务流程之后,会将对应的子节点删除。
  2. 成功获取锁的客户端在出现故障之后,对应的子节点由于是临时顺序节点,也会被自动删除,避免了锁无法被释放。
  3. 事件监听器监听的就是这个子节点删除事件,子节点删除就意味着锁被释放。

优缺点:性能是唯一缺点,另外仅需要分布式锁功能而搭建zooker集群是不划算的。

4.数据库分布式锁

在数据库中增加一张锁表。

  1. 简单:每次加锁时,插入一条数据,解锁时删除数据。
  2. 使用悲观锁。通过for update增加悲观锁。
  3. 使用乐观锁,表中增加版本号的概念。

优点:不需要额外部署外部服务

缺点:数据库的各种实现方式均有一些问题,通用的缺点就是性能不高,同时为数据库带来很大压力。在实现可重入、自动解锁、自动重试加锁等功能上均比较复杂。写主读从架构上,悲观锁还要考虑主从同步问题。

5.ETCD分布式锁

1.什么是etcd?

etcd 是一个分布式可靠的键值存储,用于存储分布式系统中最重要的数据,重点在于:

  • 简单:定义明确、面向用户的 API(gRPC)
  • 安全:自动 TLS,带有可选的客户端证书身份验证
  • 快速:基准速度为 10,000 次写入/秒
  • 可靠:使用 Raft 分布式协议

etcd 用 Go 编写,使用Raft共识算法来管理高可用性复制日志。

etcd 特性:

  • 租约机制:用于支撑异常情况下的锁自动释放能力。可以自由设置过期时间
  • 前缀和 Revision 机制:用于支撑公平获取锁和排队等待的能力,通过前缀和获取,通过revision进行顺序执行
  • 监听机制:用于支撑抢锁能力
  • 集群模式:用于支撑锁服务的高可用

2.如何用etcd实现分布式锁?

优点:通过raft协议保证一致性,防止脑裂,惊群效应,自带续期功能,性能高,高可用。

缺点: 吞吐量低(相比redis)。公司提供etcd集群使用,但是之前出现过购物车开天窗问题,集团不允许在高负载情况下请求直接打到etcd,所以这是唯一缺点。

6.分布式锁横向对比

三、分布式锁工具结论

方案:以上对比可知,在较低低吞度量场景下,etcd的实现方式是最好的

四、参考资料

  1. redis官方文档:Distributed Locks with Redis | Docs
  2. 分布式锁中的王者方案 - Redisson_redis_悟空聊架构_InfoQ写作社区
  3. Redis 分布式锁|从青铜到钻石的五种演进方案 - 悟空聊架构的个人空间 - OSCHINA - 中文开源技术交流社区
  4. jimdb支持命令:https://cf.jd.com/pages/viewpage.action?pageId=584518003
  5. jimdb帮助文档:登录JoySpace
  6. jimdb事务:事务 — Redis 设计与实现
  7. redisson:https://github.com/redisson/redisson/wiki
  8. etcd:GitHub - etcd-io/etcd: Distributed reliable key-value store for the most critical data of a distributed system
  9. etcd实现分布式锁:https://www.51cto.com/article/722138.html

关于redLock:

  1. How to do distributed locking — Martin Kleppmann’s blog
  2. Is Redlock safe? - <antirez>
  3. http://zhangtielei.com/posts/blog-redlock-reasoning.html、基于Redis的分布式锁到底安全吗(下)? - 铁蕾的个人博客 对于第一个和第二个的中文翻译和总结。。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/864984.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【第13章】MyBatis-Plus流式查询

文章目录 前言一、常用方法二、使用示例总结 前言 MyBatis-Plus 从 3.5.4 版本开始支持流式查询&#xff0c;这是 MyBatis 的原生功能&#xff0c;通过 ResultHandler 接口实现结果集的流式查询。这种查询方式适用于数据跑批或处理大数据的业务场景。 在 BaseMapper 中&#…

【信息系统项目管理师知识点速记】组织通用管理:知识管理

23.3 知识管理 23.3.1 知识管理基础 知识管理是通过利用各种知识和技术手段,帮助组织和个人生产、分享、应用和创新知识,以形成知识优势并在个人、组织、业务目标、经济绩效和社会效益方面产生价值的过程。它能为组织带来知识增值,创造新的价值,提升决策效能和水平,是提…

《昇思 25 天学习打卡营第 8 天 | 模型保存与加载使用静态图加速 》

活动地址&#xff1a;https://xihe.mindspore.cn/events/mindspore-training-camp 签名&#xff1a;Sam9029 保存与加载模型没有多少内容&#xff0c;就把使用静态图加速一起看了 先说说现有理解的概念 在学习深度学习的过程中&#xff0c;经常需要保存训练好的模型参数&#…

snowflake 不再是个数据仓库公司了

标题先上结论&#xff0c;为啥这么认为&#xff0c;且听接下来道来。 snowflake 非常成功&#xff0c;开创了云数仓先河&#xff0c;至今在数仓架构上也是相对比较先进的&#xff0c;国内一堆模仿的公司&#xff0c;传统上我们会认为 snowflake 肯定是一家数据仓库公司。不过最…

网络攻防题录集

文章目录 第一章 网络攻防概述第二章 密码学第三章 网络协议脆弱性分析第四 自测题三第五章 自测题五第六章 自测题六第七章 自测题七第八章 自测题八第九章 自测题九第十章 自测题十第十一章 自测题十一第十二章 自测题十二第十三章 自测题十三 第一章 网络攻防概述 第一代安…

【Android面试八股文】App对内存是如何限制的?应该如何合理使用内存?

文章目录 一、内存管理概览二、垃圾回收三、共享内存四、分配与回收应用内存五、限制应用内存六、切换应用七、进程间的内存分配八、内存类型九、物理内存 虚拟内存9.1 物理内存9.2 虚拟内存9.3 虚拟内存的好处9.4 共享库内存十、VSS RSS PSS USS区别十一、Android系统的页面置…

JavaSEJava8 时间日期API + 使用心得

文章目录 1. LocalDate2. LocalTime3. LocalDateTime3.1创建 LocalDateTime3.2 LocalDateTime获取方法 4. LocalDateTime转换方法4.1 LocalDateTime增加或者减少时间的方法4.2 LocalDateTime修改方法 5. Period6. Duration7. 格式转换7.1 时间日期转换为字符串7.2 字符串转换为…

linux的Top学习

学习文档 https://www.cnblogs.com/liulianzhen99/articles/17638178.html TOP 问题 1&#xff1a;top 输出的利用率信息是如何计算出来的&#xff0c;它精确吗&#xff1f; top 命令访问 /proc/stat 获取各项 cpu 利用率使用值内核调用 stat_open 函数来处理对 /proc/sta…

AcWing 1256:扩展二叉树

【题目来源】https://www.acwing.com/problem/content/1258/【题目描述】 由于先序、中序和后序序列中的任一个都不能唯一确定一棵二叉树&#xff0c;所以对二叉树做如下处理&#xff0c;将二叉树的空结点用 补齐&#xff0c;如图所示。 我们把这样处理后的二叉树称为原二叉树…

持续集成(Continuous Integration)

定义 持续集成&#xff08;Continuous Integration&#xff0c;简称CI&#xff09;是一种软件开发实践&#xff0c;开发者频繁地将代码集成到共享的代码库中&#xff0c;每次集成都通过自动化构建和测试来验证&#xff0c;从而尽早发现并修复错误。CI的目标是提高软件开发的质量…

[C++] 退出清理函数解读(exit、_exit、abort、atexit)

说明&#xff1a;在C中&#xff0c;exit、_exit&#xff08;或_Exit&#xff09;、abort和atexit是用于控制程序退出和清理的标准库函数。下面是对这些函数的详细解读&#xff1a; exit 函数原型&#xff1a;void exit(int status);作用&#xff1a;exit函数用于正常退出程序…

基于Java的早教系统的设计与实现【附源码】

摘要&#xff1a;随着家长对孩子教育的重视程度越来越高&#xff0c;早教也越来越受家长的青睐&#xff0c;因为它可以有针对性地单独授课&#xff0c;能显著提高学生学习的效果。同时互联网的兴起&#xff0c;对教育的形式也产生了重大影响&#xff0c;为此基于B/S的早教平台应…

零知识证明技术:隐私保护的利器

在当今信息时代&#xff0c;数据安全和隐私保护的重要性日益凸显。随着技术的发展&#xff0c;密码学在保障信息安全方面发挥着越来越重要的作用。其中&#xff0c;零知识证明技术作为一种新兴的密码学方法&#xff0c;为隐私保护提供了强有力的支持。本文将简要介绍零知识证明…

3.js - premultiplyAlpha

你瞅啥啊&#xff01;&#xff01;&#xff01; 先看效果图吧 代码 // ts-nocheck // 引入three.js import * as THREE from three // 导入轨道控制器 import { OrbitControls } from three/examples/jsm/controls/OrbitControls // 导入lil.gui import { GUI } from three/ex…

c#与倍福Plc通信

bcdedit /set hypervisorlaunchtype off

pycharm中新建的临时python文件存放在哪里?

在pycharm中建立的临时python文件&#xff0c;从哪里可以找到呢&#xff1f; 1.我们打开cmd窗口&#xff0c;进入根目录&#xff0c;用dos命令“dir scratch*.py/a/s”进行查找&#xff0c;发现这些临时文件存放在Roaming\JetBrains\PyCharmCE2022.2\scratches 的目录里面 2.…

base64字符串空格问题

客户端使用的Content-Type为application/x-www-form-urlencoded时&#xff0c;字符串中出现了空格&#xff0c;base64解码时出错了&#xff0c;因为原来的字符有号&#xff0c; Spring Boot 对于Content-Type为application/x-www-form-urlencoded的HTTP请求&#xff0c;默认情…

我全都要,全网聚合神器!绝了!

哈喽&#xff0c;各位小伙伴们好&#xff0c;我是给大家带来各类黑科技与前沿资讯的小武。 现在有不少开发者都会以“壳源”的方式&#xff08;如TVBox、阅读APP等&#xff09;&#xff0c;为用户提供了更为灵活性的选择。 而今天给大家安利的是一款“壳源”的聚合神器&#…

Profibus DP主站转Modbus网关连接智能化电表通讯

Profibus DP主站转Modbus网关&#xff08;XD-MDPBM20&#xff09;&#xff0c;是实现不同工业通信协议之间互联互通的设备&#xff0c;主要将Profibus DP协议转换为Modbus协议&#xff0c;实现数据的双向传输。通过Profibus DP主站转Modbus网关&#xff08;XD-MDPBM20&#xff…

记一次阿里云服务器java应用无法响应且无法远程连接的问题排查

问题表现 java服务无响应&#xff0c;无法远程链接到服务器。 今天中午12点多&#xff0c;应用直接崩溃。后续进入到服务器&#xff0c;发现java进程都不在了&#xff0c; 排查过程 先安装atop工具 安装、配置并使用atop监控工具 等下次再出现时看相关时间点日志&#xff…