当前位置: 首页 > news >正文

分析redis实现分布式锁的思路

文章目录

  • 1、基于redis实现分布式锁:利用key的唯一性
    • 1.1、独占排他
    • 1.2、死锁问题
      • 1.2.1、redis客户端程序获取了锁之后,服务器立马宕机,就会导致死锁。
      • 1.2.2、不可重入:可重入
    • 1.3、原子性:加锁和过期之间:set k v nx ex 3
    • 1.4、防误删:给锁添加 uuid 唯一标识
    • 1.5、可重入锁:
  • 2、代码实现一个基本分布式锁
    • 2.1、AlbumInfoApiController --》testLock()
    • 2.2、AlbumInfoServiceImpl --》testLock()
  • 3、分布式锁程序存在的问题及测试
    • 3.1、AlbumInfoServiceImpl --》testLock()

1、基于redis实现分布式锁:利用key的唯一性

1.1、独占排他

1.2、死锁问题

1.2.1、redis客户端程序获取了锁之后,服务器立马宕机,就会导致死锁。

解决方案:给锁添加过期时间,时间到了自动释放锁。

1.2.2、不可重入:可重入

1.3、原子性:加锁和过期之间:set k v nx ex 3

判断和删除之间:lua 脚本。

1.4、防误删:给锁添加 uuid 唯一标识

先判断是否是自己的锁,如果是才能删除。

1.5、可重入锁:

锁操作:加锁、解锁、自旋
在这里插入图片描述

2、代码实现一个基本分布式锁

2.1、AlbumInfoApiController --》testLock()

@Tag(name = "专辑管理")
@RestController
@RequestMapping("api/album/albumInfo")
@SuppressWarnings({"unchecked", "rawtypes"})
public class AlbumInfoApiController {@GetMapping("test/lock")public Result testLock() {this.albumInfoService.testLock();return Result.ok("测试分布式锁案例");}}

2.2、AlbumInfoServiceImpl --》testLock()

    @Overridepublic  void testLock(){// 加锁Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111");if (!lock) {try {// 获取锁失败,进行自旋Thread.sleep(50);this.testLock();} catch (InterruptedException e) {throw new RuntimeException(e);}}// 获取锁成功,执行业务Object numObj = this.redisTemplate.opsForValue().get("num");if (numObj == null) {this.redisTemplate.opsForValue().set("num", 1);return;}Integer num = Integer.parseInt(numObj.toString());this.redisTemplate.opsForValue().set("num", ++num);// 解锁this.redisTemplate.delete("lock");}

启动多个运行实例:
在这里插入图片描述
在这里插入图片描述
redis中的值重新改为0。

[root@localhost ~]# ab -n 5000 -c 100 http://192.168.74.1:8500/api/album/albumInfo/test/lock
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.74.1 (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requestsServer Software:        
Server Hostname:        192.168.74.1
Server Port:            8500Document Path:          /api/album/albumInfo/test/lock
Document Length:        76 bytesConcurrency Level:      100
Time taken for tests:   16.625 seconds
Complete requests:      5000
Failed requests:        577(Connect: 0, Receive: 0, Length: 577, Exceptions: 0)
Write errors:           0
Total transferred:      2352885 bytes
HTML transferred:       382885 bytes
Requests per second:    300.75 [#/sec] (mean)
Time per request:       332.506 [ms] (mean)
Time per request:       3.325 [ms] (mean, across all concurrent requests)
Transfer rate:          138.21 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    3   2.6      2      38
Processing:    11  306 566.7     92    6553
Waiting:       10  305 566.7     92    6552
Total:         11  308 567.5     95    6560Percentage of the requests served within a certain time (ms)50%     9566%    18875%    31880%    42490%    83795%   140598%   219099%   2905100%   6560 (longest request)

在这里插入图片描述

3、分布式锁程序存在的问题及测试

3.1、AlbumInfoServiceImpl --》testLock()

    @Overridepublic  void testLock(){// 加锁Boolean lock = this.redisTemplate.opsForValue().setIfAbsent("lock", "111");if (!lock) {try {// 获取锁失败,进行自旋Thread.sleep(50);this.testLock();} catch (InterruptedException e) {throw new RuntimeException(e);}}else {// 获取锁成功,执行业务Object numObj = this.redisTemplate.opsForValue().get("num");if (numObj == null) {this.redisTemplate.opsForValue().set("num", 1);return;}Integer num = Integer.parseInt(numObj.toString());this.redisTemplate.opsForValue().set("num", ++num);// 解锁this.redisTemplate.delete("lock");}}

启动多个运行实例:
在这里插入图片描述
在这里插入图片描述
redis中的值重新改为0。

[root@localhost ~]# ab -n 5000 -c 100 http://192.168.74.1:8500/api/album/albumInfo/test/lock
This is ApacheBench, Version 2.3 <$Revision: 1430300 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.74.1 (be patient)
Completed 500 requests
Completed 1000 requests
Completed 1500 requests
Completed 2000 requests
Completed 2500 requests
Completed 3000 requests
Completed 3500 requests
Completed 4000 requests
Completed 4500 requests
Completed 5000 requests
Finished 5000 requestsServer Software:        
Server Hostname:        192.168.74.1
Server Port:            8500Document Path:          /api/album/albumInfo/test/lock
Document Length:        76 bytesConcurrency Level:      100
Time taken for tests:   46.550 seconds
Complete requests:      5000
Failed requests:        683(Connect: 0, Receive: 0, Length: 683, Exceptions: 0)
Write errors:           0
Total transferred:      2353415 bytes
HTML transferred:       383415 bytes
Requests per second:    107.41 [#/sec] (mean)
Time per request:       931.003 [ms] (mean)
Time per request:       9.310 [ms] (mean, across all concurrent requests)
Transfer rate:          49.37 [Kbytes/sec] receivedConnection Times (ms)min  mean[+/-sd] median   max
Connect:        0    2   5.0      1      58
Processing:     5  892 2805.1     13   43782
Waiting:        5  892 2805.1     13   43781
Total:          5  894 2805.7     14   43785Percentage of the requests served within a certain time (ms)50%     1466%    13475%    44180%    80490%   242895%   446998%   903799%  13259100%  43785 (longest request)

在这里插入图片描述


http://www.mrgr.cn/news/32975.html

相关文章:

  • mmsegmentation: 安装 并使用自定义数据集进行训练 ·1
  • 38配置管理工具(如Ansible、Puppet、Chef)
  • 民锋科技如何通过量化分析提升金融市场投资决策
  • 【TensorRT】使用C++将yolov8 onnx转化为tensorrt格式
  • ubuntu20.04 解决Pytorch默认安装CPU版本的问题
  • macOS解决U盘装完系统容量变小的问题
  • 【亿美软通-注册/登录安全分析报告】
  • 掌握 JavaScript 中的函数表达式
  • 安装黑群晖系统,并使用NAS公网助手访问教程(好文)
  • Android通知服务及相关概念
  • Flutter 获取手机连接的Wifi信息
  • Ribbon布局和尺寸调整
  • 详解lsof
  • NXP官方或正点原子mfgtool下载系统报错initialize the library falied error code:29
  • 【读书笔记-《网络是怎样连接的》- 0】全书整体结构
  • 直通滤波-PassThrough Filter-原理-代码实现
  • 数据结构——二叉搜索树
  • grbl移植日志第二天移植串口数据接收
  • 图像锐化的算法总结
  • LeetCode --- 139双周赛
  • python:给1个整数,你怎么判断是否等于2的幂次方?
  • KVM环境下制作ubuntu qcow2格式镜像
  • Java面试——集合篇
  • Python基于TensorFlow实现Transformer分类模型(Transformer分类算法)项目实战
  • C语言的一些小知识(四)
  • 跨游戏引擎的H5渲染解决方案(腾讯)