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成为原子操作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

前端性能优化之图像优化

图像优化问题主要可以分为两方面:图像的选取和使用,图像的加载和显示。 图像基础 HTTP Archive上的数据显示,网站传输的数据中,60%的资源都是由各种图像文件组成的,当然这些是将各类型网站平均的结果,单独…

二分查找(一)

算法原理 原理:当一个序列有“二段性”的时候,就可以使用二分查找算法。 适用范围:根据规律找一个点,能将这个数组分成两部分,根据规律能有选择性的舍去一部分,进而在另一个部分继续查找。 除了最普通的…

ROS-机器人仿真urdf-rviz、xacro

文章目录 一、urdf集成rviz1.1 基本流程1.2 优化 rviz 启动 二、urdf语法详解2.1 robot2.2 link2.3 joint2.4 urdf练习2.5 urdf工具 三、URDF优化_xacro3-1 Xacro_语法详解3-2 Xacro_完整使用流程示例3- Xacro_实操 一、urdf集成rviz 1.1 基本流程 需求描述: 在 Rviz 中显示一…

simulink代码生成(四)——SCI模块:接收模块

首先,实现DSP28335的自收自发; 添加串口收发模块; 设置参数,根据硬件选择串口模块: 配置中断触发;SCIB的接收中断的CPU中断号为9,PIE级中断为3; 因此如下配置; 代码生成…

认识Git

🌎初识Git 初识Git 什么是Git Git的安装       Centos平台安装Git       Ubuntu平台安装Git Git的基本操作       创建远程仓库       配置Git 认识工作区、暂存区与版本库       添加文件到暂存区       将暂存区文件提交至本…

如何进行sql优化?

在日常工作中都避免不了要和各种SQL语句打交道,无论是开发还是后期维护,一条执行效率高的SQL语句都会对系统性能产生巨大影响。那么,如何进行有效的SQL优化呢?下面将为大家深入浅出地讲解SQL优化的各个方面: 1、了解数…

WorkPlus AI助理为企业提供智能客服的机器人解决方案

在数字化时代,企业面临着客户服务的重要挑战。AI客服机器人成为了提升客户体验和提高工作效率的关键工具。作为一款优秀的AI助理,WorkPlus AI助理以其智能化的特点和卓越的功能,为企业提供了全新的客服机器人解决方案。 为什么选择WorkPlus A…

格密码基础:光滑参数

目录 一. 铺垫高斯函数 二. 光滑参数图形理解 三. 光滑参数与格基本区 3.1 高斯与均匀分布的统计距离 3.2 光滑参数理解 四. 光滑参数与最短向量 五. 光滑参数与连续最小值 六. 光滑参数与对偶格的上界 七. 光滑参数与格的上界 八. 小结 一. 铺垫高斯函数 定义高斯密…

MIT 6.s081 实验解析——labs2

系列文章目录 MIT 6.s081 实验解析——labs1 MIT 6.s081 实验解析——labs2 文章目录 系列文章目录测试判断流程System call tracingsysinfo![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/ab9ca34f1fc64b6aa1df74613dc1a397.png) 测试判断流程 完成代码后将.c文…

K8S Prometheus-rocketmq-exporter配置

下载rocketmq-exporter 通过Docker仓库下载 docker pull sawyerlan/rocketmq-exporter:latest 然后打标签,推送到自己的仓库 也可通过代码自己build镜像 git clone GitHub - apache/rocketmq-exporter: Apache RocketMQ Prometheus Exporter 然后打标签&#x…

iPhone 恢复出厂设置后如何恢复数据

如果您在 iPhone 上执行了恢复出厂设置,您会发现所有旧数据都被清除了。这对于清理混乱和提高设备性能非常有用,但如果您忘记保存重要文件,那就是坏消息了。 恢复出厂设置后可以恢复数据吗?是的!幸运的是,…

React Portals

简介 React Portal 可以将组件渲染到dom树的不同位置,同时可以渲染到任意父级元素,可以实现漂浮层功能。 使用样例 本篇文章通过React Portals实现对话框,下面将会给出具体实现。 protal组件 Portal.jsx import {useState} from "re…

Java环境准备:JDK与IDEA

新手小白学Java–环境准备篇 文章目录 新手小白学Java--环境准备篇第1节 JDK的下载与安装第2节 IDEA的下载与安装第3节 使用IDEA创建第一个Java项目第4节 使用小技巧查看电脑的操作系统版本显示出文件的后缀名IDEA 修改字体大小IDEA 修改显示主题色IDEA 修改单行注释的颜色IDEA…

Mysql SQL审核平台Yearning本地部署

文章目录 前言1. Linux 部署Yearning2. 本地访问Yearning3. Linux 安装cpolar4. 配置Yearning公网访问地址5. 公网远程访问Yearning管理界面6. 固定Yearning公网地址 前言 Yearning 简单, 高效的MYSQL 审计平台 一款MYSQL SQL语句/查询审计工具,为DBA与开发人员使用…

Postman实现压力测试

从事软件开发对于压力测试并不陌生,常见的一些压测软件有Apache JMeter LoadRunner Gatling Tsung 等,这些都是一些比较专业的测试软件,对于我的工作来说一般情况下用不到这么专业的测试,有时候需要对一些接口进行压力测试又不想再安装新软件,那么可以使用Postman来实现对…

MyBatis入门源码一:配置解析

一、SqlSessionFactory 的构建:SqlSessionFactoryBuilder#build(…) 看一下我们mybatis-config.xml 配置的内容: parser.parse(): 解析配置文件 解析的内容很多,重点看解析数据源、解析mapper文件 build: 创建DefaultSqlSessi…

用队列实现栈oj题——225

. 个人主页:晓风飞 专栏:LeetCode刷题|数据结构|Linux 路漫漫其修远兮,吾将上下而求索 文章目录 题目要求:实现 MyStack 类:注意:示例:解释:提示: 解题核心数据结构的定义…

Redis概览

Redis存储是Key-Value结构的数据,其中Key是字符串类型,Value有5种常见的数据类型 字符串 String 哈希 hash 列表 list 集合 set 有序集合 sorted set / zset 各种数据类型的特性 字符串操作命令 : ● SET ke…

Go-gin-example 添加注释 第一部分 新建项目及api编写

文章目录 go-gin-example环境准备初始化 Go Modules基础使用 gin 安装测试gin是否引入 gin搭建Blog APIsgo-ini简述配置文件 阶段目标 编写简单API错误码包 完成一个demo初始化项目初始化项目数据库编写项目配置包拉取go-ini配置包在conf目录下新建app.ini文件,写入…

数据结构排序(一.基本概念、插入排序和希尔排序实现)

前段时间也是结束了二叉树的知识梳理(大家想必满脑子都是递归了):二叉树链式结构的实现(二叉树的遍历以及各种常用功能函数的实现) 今天也要迈向全新的篇章了——排序。这次就先大概讲解一下排序,然后插入排序和希尔排序的介绍和实…