Java分布式锁理论(redis、zookeeper) 详解

目录

一、分布式锁有哪些应用场景?

二、分布式锁的实现方案

三、zookeeper实现分布式锁

一直不释放锁怎么办?

如何避免分布式锁羊群效应问题?

四、redis实现分布式锁


一、分布式锁有哪些应用场景?

1、定时任务

2、秒杀抢购,防止库存超卖的问题

3、双写一致性协议

比如我们为了高可用性搭建了服务集群,分别是8080和8081,我们在项目中设立定时任务,目的是每天晚上定时拉取用户数据,给每个人发送一些推荐短信。那么这会出现什么问题呢?8080和8081都有定时任务,到半夜2点同时查询数据库,同时调用阿里云接口发短信,那么肯定会重复,使用了分布式锁,8080抢到锁执行定时任务,那么8081就会阻塞不会执行。

那么肯定会有人问,为什么不用synchronized锁呢?

如果我们是单个项目,用synchronized锁可以实现,但我们用的是集群,synchronized是无法跨jvm的。

二、分布式锁的实现方案

(1)基于数据库实现——mysql行锁

(2)基于zookeeper  CP模式

(3)基于redis setnx实现  AP模式

(4)Redis框架 Redisson、RedisLock

要求:

  • 保证一致性:zookeeper 实现分布式锁
  • 保证可用性:redis实现分布式锁

三、zookeeper实现分布式锁

zookeeper有个节点路径的概念,节点路径不能重复,保证了唯一性。

如图,我有4个springboot项目,首先jvm1先抢到了资源,设置了zk的节点路径/lockPath,这个操作就相当于获取到了锁,这时其余三个jvm获取锁失败进行阻塞状态。当jvm1执行任务完毕,调用close()关闭连接,zk自动删除节点路径释放锁,zk通知其余3个jvm节点,它们3个开始竞争锁。

一直不释放锁怎么办?

我们上面说的是正常理想情况,那么问题来了,如果jvm1一直不释放锁,该怎么办?

可以采用续命设计(设置超时时间),续命多次如果业务还是没有执行完毕的情况下,则认为该锁超时应该主动释放该锁,再将所有业务代码回滚,防止其它jvm一直阻塞等待。

如何避免分布式锁羊群效应问题?

如图可以看出,当我们有100个jvm的时候,如果jvm1抢到了锁,执行完业务释放了锁,zk就要唤醒其余99个jvm,那唤醒这个操作成本是很高的。

如何解决呢?

采用zk的临时顺序节点

我们现在有三个jvm,分别创建了三个临时顺序节点路径,谁最小就获取锁成功,首先jvm1最小获取锁成功,jvm2和jvm3就阻塞,jvm2创建的临时节点就去订阅最小的/lockPath1,当jvm1执行完毕释放锁并删除/lockPath1节点,那么现在/lockPath2就是最小的节点,获取锁成功。

其实就相当于synchronized的公平锁,jvm1、jvm2、jvm3依次按顺序执行,这样我们就不用唤醒所有,jvm1节点消失,我只需要唤醒jvm2节点。

四、redis实现分布式锁

如果不存在值,则返回1,如果存在,则返回0。

那也就是说,我jvm1先setnx返回1抢到了锁,这时jvm2也setnx发现返回0,那就无法执行业务。

当我们执行业务完成后,删除此key就起到了释放锁的作用。

那么问题来了,一个老生常谈的话题,如果jvm1一直不释放锁怎么办?

答:先拿setnx来争抢锁,抢到之后,再用expire命令给锁加一个过期时间防止锁忘记了释放。

但这样还有问题,如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那该怎么解决?

答:我们可以使用lua脚本来使setnx+expire成为原子操作。

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

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

相关文章

Proteus 各版本安装指南

Proteus下载链接 https://pan.baidu.com/s/1vHgg8jK9KSHdxSU9SDy4vQ?pwd0531 1.鼠标右击【Proteus8.15(64bit)】压缩包(win11及以上系统需先点击“显示更多选项”)【解压到Proteus8.15(64bit) 】。 2.打开解压后的文件夹&#…

dnSpy调试Web应用程序

文章目录 前言一、dnSpy是什么?二、如何使用dnSpy三、如何调试Web应用程序四、下载总结 前言 dnSpy是一个.NET程序集调试器和编辑器,主要用于调试和编辑没有源码的.NET程序集。 一、dnSpy是什么? dnSpy是一个.NET程序集调试器和编辑器&#…

Python武器库开发-武器库篇之子域名扫描器开发(四十一)

Python武器库开发-武器库篇之子域名扫描器开发(四十一) 在我们做红队攻防或者渗透测试的过程中,信息收集往往都是第一步的,有人说:渗透的本质就是信息收集,前期好的信息收集很大程度上决定了渗透的质量和攻击面,本文将…

C语言基础知识(6):UDP网络编程

UDP 是不具有可靠性的数据报协议。细微的处理它会交给上层的应用去完成。在 UDP 的情况下,虽然可以确保发送消息的大小,却不能保证消息一定会到达。因此,应用有时会根据自己的需要进行重发处理。 1.UDP协议的主要特点: &#xf…

【C++】STL 算法 ⑥ ( 二元谓词 | std::sort 算法简介 | 为 std::sort 算法设置 二元谓词 排序规则 )

文章目录 一、二元谓词1、二元谓词简介2、 std::sort 算法简介3、 代码示例 - 为 std::sort 算法设置 二元谓词 排序规则 一、二元谓词 1、二元谓词简介 " 谓词 ( Predicate ) " 是一个 返回 布尔 bool 类型值 的 函数对象 / 仿函数 或 Lambda 表达式 / 普通函数 , …

(06)金属布线——为半导体注入生命的连接

01、半导体的核心——“连接” 在上几篇文章中,我们详细讲解了氧化、光刻、刻蚀、沉积等工艺。经过上述工艺,晶圆表面会形成各种半导体元件。半导体制造商会让晶圆表面布满晶体管和电容(Capacitor);而代工厂或CPU制造商则会让晶圆底部排列鳍式场效电晶体(FinFET)等三维…

SSD固态硬盘数据修复方案介绍

这么多故障的可能,那么固态硬盘SSD的数据修复,到底是否有办法呢?我们这里介绍两种尝试修复的方式,不能保证一定会成功。在你误删除一些文件的时候,可以尝试下,市场也有也有很多的修复软件。 方式1:采用修复…

最新版付费进群系统源码 /同城定位付费进群源码 /自带定位完整版/后台分销站点

源码介绍: 最新版付费进群系统源码 ,它是同城定位付费进群源码,而且自带定位完整版和后台分销站点。 看到有些人分享一些虚假的内容或者缺少文件的内容。现在分享完整给大家,功能是完整的。它是同城定位付费进群源码。 功能&am…

在Raspberry Pi Zero W中配置TFT LCD Framebuffer驱动

TFT LCD Framebuffer驱动配置 文章目录 TFT LCD Framebuffer驱动配置1、硬件准备2、软件配置2.1 启用SPI驱动2.2 TFT LCD设备驱动树配置 本文将以ILI9341 LCD为例,将详细介绍如何配置TFT LCD的Framebuffer驱动。 1、硬件准备 Raspberry Pi Zero W开发板一个&#x…

修改Gitee用户名

首先进入首页,点击右上角下拉列表中的账号设置 只想改姓名的话,就只要改下下面这里 还想把个人空间地址改了的话还要改下面这里

java基于SSM的二手交易平台设计与开发论文

摘 要 现代经济快节奏发展以及不断完善升级的信息化技术,让传统数据信息的管理升级为软件存储,归纳,集中处理数据信息的管理方式。本二手交易平台就是在这样的大环境下诞生,其可以帮助使用者在短时间内处理完毕庞大的数据信息&am…

智慧医院预约及支付平台—智慧支付

医保支付流程 自费支付流程 智慧医院支付业务介绍 社保卡绑定(身份认证) 认证方案:银行身份已验证客户,可通过本人银行登记的手机号码登录医院APP后,在完善APP注册身份信息时,将相关信息发送苏州银行,由银行核对客户身份信息正确性并将社保卡绑定本人手机。核实后的身份…