【Redis学习笔记】2:认识Redisson及其分布式锁RLock.lock()

2023-11-06

Redisson和Jedis类似,都是用Java实现的操作Redis的客户端,但是使用场景不同。Redisson更多用在分布式场景下(功能可以看wiki),Jedis更多用在单机场景下。

1 Java接入Redisson

以Spring Boot为例,接入Redisson的依赖:
在这里插入图片描述
和使用Jedis类似,需要初始化一个Redisson客户端,使用提供的API来创建Redisson对象(指定了配置,以及要操作的是哪个Redis实例),然后注入到容器中:
在这里插入图片描述
上面的代码里是单机模式,也支持其他的配置方法,如集群、主从、复制、哨兵等主流的Redis架构:
在这里插入图片描述
在业务代码里注入:
在这里插入图片描述

2 使用Redisson分布式锁

使用方法:
在这里插入图片描述
这里的加锁操作就相当于实现了前面Java笔记70里讲的SETNX加锁+设置超时时间+开分线程做锁续命等一系列操作。


加锁的逻辑(加锁成功就开一个后台线程做锁续命,一般是超时时间的1/3时间续一次,加锁不成功就循环尝试):
在这里插入图片描述

3 RLock.lock()的底层核心实现

3.1 设置key-value和超时时间

这里会执行一个lua脚本来操作Redis:
在这里插入图片描述
首先使用exists命令判断key存不存在。

如果不存在,就使用hset命令来设置key-value,其中key就是传进来的key,value是根据原生线程id做了一些封装得到的线程唯一标识(ARGV[2]对应getLockName(threadId))。

然后使用pexpire命令设置一下超时时间(ARGV[1]对应internalLockLeaseTime),去追溯一下可以看到这个超时时间默认是30秒:
在这里插入图片描述
试想为什么这里可以将设置key和设置超时时间分成两条命令?实际是因为Redis(>=2.6)支持开发者编写Lua脚本传到Redis中执行:
在这里插入图片描述
也就是说Redisson里的一长串Lua脚本实际是原子性执行的。

3.2 锁续命的实现

在执行完前面Lua脚本的异步加锁操作之后,执行了一个回调,调了一个看似要执行定时任务的scheduleXXX
在这里插入图片描述
点进去可以看到确实是拉起了一个定时任务:
在这里插入图片描述
可以看到又执行了一段Lua脚本,先用hexists判断一下自己的主线程设置的key还存不存在(这里KEYS[1]就是要查的key,ARGV[2]是要比较value确认确实是自己主线程加的key)。

然后,如果判断发现这把锁还存在,就调用pexpire命令,重新把锁(key为KEYS[1])的超时时间设置为一开始定的ARGV[1]

注意,这个锁续命操作是delay做的,延迟时间就是设置的超时时间的1/3:
在这里插入图片描述
但是这样也只是延迟执行一次,如何能做到间隔执行?往下看可以看到,在锁续命执行完一次后,又加了一个监听器来调用自己(指这个scheduleXXX),也就实现了不断的间隔续命:
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【Redis学习笔记】2:认识Redisson及其分布式锁RLock.lock() 的相关文章

  • 是否可以使用带有 FUSE 文件系统的 Linux VFS 缓存?

    默认情况下 Linux VFS 缓存似乎不适用于 FUSE 文件系统 例如 read 调用似乎被系统地转发到 FUSE 文件系统 我在 FUSE 特定的远程文件系统上工作 我需要一个非常积极的缓存 我需要实现自己的页面缓存吗 或者是否可以为
  • 找不到模块“socket.io/node_modules/redis”

    当尝试做的时候 var redis require socket io node modules redis 我收到错误 找不到模块 socket io node modules redis 我不明白为什么 我正在运行 Windows 并运
  • Redis部署配置-主从复制

    目前我有两台服务器 我已经部署了基于node js Express JS的Web服务API 我正在使用 Redis 来缓存 JSON 字符串 将此设置部署到生产中的最佳选择是什么 我懂了here https stackoverflow co
  • 如何在redis中创建自己的数据库?

    There are 0 to 15 databases in redis 我想使用 redis cli 创建自己的数据库 有什么命令可以实现吗 Redis 数据库并不等同于 MySQL 等 DBMS 中的数据库名称 这是一种为键创建隔离和命
  • 使用brew在MacOSx上安装Redis JSON

    如何使用brew 在 macOSx 上安装 RedisJSON 如何在不编译redis的情况下启用redis上的模块 我不想使用 docker 客户端 Redis Stack 可能是最简单的方法 它不仅仅是 RedisJSON 还包括 Re
  • Spring RedisTemplate:8次调用后方法键挂起

    我使用 Spring RedisTemplate spring data redis 1 7 1 与 Redis 进行通信 我需要通过正则表达式获取然后删除键 例如 context user1 我用的方法 RedisTemplate key
  • Node.js 上通过套接字连接 Redis

    由于共享托管 目标主机上的我的 redis 服务器不在端口上运行 而是在非常特定的套接字上运行 可以通过套接字文件连接到该套接字 只有我的用户可以访问 但是 我还没有找到如何通过套接字指定连接node redis and connect r
  • Redis 块推送直到列表有空位

    我正在寻找类似的东西BLPUSH该命令将阻塞 直到列表的长度低于指定值max size 目的是防止生产者运行速度快于消费者时列表无限增长 功能与 python 非常相似Queue put https docs python org 3 li
  • 如何让客户端下载动态生成的非常大的文件

    我有一个导出功能 可以读取整个数据库并创建一个包含所有记录的 xls 文件 然后文件被发送到客户端 当然 导出完整数据库的时间需要大量时间 并且请求很快就会以超时错误结束 处理这种情况的最佳解决方案是什么 例如 我听说过使用 Redis 创
  • 为什么Redis中不建议使用KEYS?

    在Redis中 建议不要使用按键命令 https redis io commands KEYS 为什么会这样呢 是因为它的时间复杂度是 O N 吗 或者是别的什么原因 我做了下面的实验来证明KEYS命令有多么危险 当带有 KEYS 的一个命
  • WSL Redis 遇到系统尚未使用 systemd 作为 init 系统(PID 1)启动。无法操作[已关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我正在尝试遵循本文中讨论的 Redis 安装过程article https www digitalocean com community
  • redis-cli 重定向到 127.0.0.1

    我在PC1上启动Redis集群 然后在PC2上连接它 当需要重定向到另一个集群节点时 它会显示Redirected to slot 7785 located at 127 0 0 1 但应该显示Redirected to slot 7785
  • 如何测试我的 Redis 缓存是否正常工作?

    我已经安装了 django redis cache 和 redis py 我遵循了 Django 的缓存文档 据我所知 以下设置就是我所需要的 但我如何判断它是否正常工作 设置 py CACHES default BACKEND redis
  • 如何在Redis中进行持久化存储?

    关闭redis服务器后 使用set存储的值被破坏 在这里我找到了使用持久性存储的方法 有人帮助我 如何使用javascript实现这一点 我想将客户端的一些值存储在 redis 数据库中 并且必须在其他客户端中使用该值 您需要配置 Redi
  • Redis发布/订阅:查看当前订阅了哪些频道

    我目前有兴趣查看我拥有的 Redis 发布 订阅应用程序中订阅了哪些频道 当客户端连接到我们的服务器时 我们将它们注册到如下所示的通道 user user id 这样做的原因是我希望能够看到谁 在线 目前 我在不知道客户端是否在线的情况下盲
  • Node Js:Redis 作业在完成其任务后未完成

    希望你们做得很好 我在我的 Nodejs 项目中实现了 BullMQ Bull 的下一个主要版本 来安排发送电子邮件的作业 例如 发送忘记密码请求的电子邮件 所以 我编写了如下所示的代码 用户服务 await resetPasswordJo
  • 为什么 Redis TimeSeries 不捕获聚合中的最后一个元素?

    我试图了解 Redis 的时间序列规则创建的工作原理 但我很困惑为什么 Redis 会忽略聚合中的最后一项 并想知道这是否是预期的行为 我在中创建了示例代码redis cli为了显示 127 0 0 1 6379 gt FLUSHALL O
  • 有没有办法用Lettuce自动发现Redis集群中新的集群节点IP

    我有一个Redis集群 3主3从 运行在一个库伯内斯簇 该集群通过Kubernetes 服务 Kube 服务 我将我的应用程序服务器连接到 Redis 集群 使用Kube 服务作为 URI 通过 Redis 的 Lettuce java 客
  • 有没有办法让特定的key在集群模式下定位到特定的redis实例上?

    我想让我的多锁位于不同的redis实例上 我发现redission可以指定一个实例来执行命令 但是如果该命令与key相关 则指定的实例会将命令传输到另一个实例 你能给我一些建议吗 你可以 但这并不是微不足道的 首先 Redis 在键中使用大
  • 如何使redis中的“HSET”子键“过期”?

    我需要使 Redis 哈希中所有超过 1 个月的密钥过期 这不可能 https github com antirez redis issues 167 issuecomment 2559040 为了保持 Redis 简单 https git

随机推荐

  • 实现el-form一行中多个el-form-item

    el form item默认一个占一行 利用el row和el col实现一行中多个 注意 el col span 12 中的12是一个占据的列数 默认一列总共24列 通过调整这个数字 可以调整不同列的宽度 如果只使用el col 不在外面
  • c++23中的新功能之一介绍

    一 c 23的目标和延革 c 的标准发展速度在经过c 11的近乎可以称革新的变化之后 开始步入了快车道 有的人在网上说 c 11后的c 语言和c 11以前的c 语言不是一个语言 这有点夸张了 但不可否认 其内容确实变化非常大 很多人可能都没
  • 异步处理机制 多线程

    在处理程序执行流程时 一定要切记 android的处理机制是异步处理 多线程的它并不会因为一个线程处于阻塞状态时其他的线程就不往下执行了 看看代码是不是一个线程的 如果是一个线程的 线面就阻塞了 转载于 https www cnblogs
  • SpringBoot项目将数据源变成Json文件(Jackson2RepositoryPopulatorFactoryBean实现)

    一 项目情景 有时在我们项目当中需要存储一些固定值时 会使用一些配置文件来存储 例如最常见的 json文件 它可以用来存储相应的属性以及属性值 当你需要的时候进行提取 甚至还可以基于这个 json文件写一些条件查询的语句来获得自己需要的值
  • 正则表达式转义字符

    正则表达式的转义字符 除 外 其他字符与自身匹配 点的转义 gt u002E 美元符号的转义 gt u0024 乘方符号的转义 gt u005E 左大括号的转义 gt u007B 左方括号的转义 gt u005B 左圆括号的转义 gt u0
  • 浙大python网_Python爬虫学习(8):浙大软院网络登陆保持

    在浏览器的验证窗口中输入登陆名和密码后 成功后会弹出一个小的新窗口 如果不小心关闭了这个窗口 则就会无法联网 如果说我在一个不带有桌面的Linux系统中 我是不能够通过浏览器接入网络的 虽然提供了不同系统的不同版本的客户端 没有用过 但是还
  • koa文件上传(详解koa-body)

    koa body const koa require koa const koaBody require koa body const path require path const app new koa let app new Koa
  • linux切换目录shell脚本,【Linux命令行与shell脚本编程】教程三——切换目录

    浏览文件系统 1 Linux文件路径 linux文件路径和windows文件路径不同 一个windows文件的路径可能是这样的 C Users John Documents test txt 而Linux的路径是这样的 home John
  • IOS通知中心(观察者模式)[NSNotificationCenter defaultCenter]

    通知机制和KVO都是通过 观察者模式实现的 KVO 即 Key Value Observing 它提供一种机制 当指定的对象的属性被修改后 则对象就会接受到通知 简单的说就是每次指定的被观察的对象的属性被修改后 KVO就会自动通知相应的观察
  • 深入理解计算机系统(第二版) 家庭作业 第十一章

    11 6 A 因为read requesthdrs中已经打印出了请求报头 所以只要打印请求行即可 在doit函数中第一个sscanf语句之后添加下面的语句即可 printf s s s n method uri version B 用火狐浏
  • webM文件解析--基于Matroska和EBML

    1 什么是webM 要说webM 先说Matroska Matroska是一个可扩展的 开源的多媒体容器 说简单点 容器的作用 就是把视频和音频封装到一个文件 使用这种容器的常见文件 一个是MKV 一个就是webM 两者的区别 无非是支持的
  • 大话西游灯谜答案

  • 《拉勾Java高薪课程》阶段一输出 之 持久层框架设计实现及MyBatis源码分析-学习笔记 --菜鸟小回

    阶段一模块一学习笔记 文章目录 阶段一模块一学习笔记 toc 一 自定义持久层框架 1 JDBC问题总结 2 问题解决思路 3 自定义框架设计 4 实际项目目录分析 5 优化 5 1 将测试类方法 5 2 仍存在问题 5 3 解决方式 6
  • SpringBoot访问静态资源html和jsp

    1 新建springBoot项目 1 2 3 4 5 6 2 配置项目JDK 前面已经配置的可以不用配置 1 2 3 把项目配置成maven项目 1 2 3 4 5 6 有maven项目这里结构有test 4 访问json 配置数据库在默认
  • 使用51单片机实现点阵汉字平滑滚动显示

    使用51单片机实现点阵汉字平滑滚动显示 说明 采用的芯片是89C51 LED点阵屏的规格是16 16 同时使用了两个74HC595芯片 字模生成软件在文末有网盘链接 1 连接原理图 整体的电路连接如上图所示 单片机只需要使用三个IO接口 就
  • 云开发小程序要服务器吗,小程序云开发发布还需要服务器吗

    小程序云开发发布还需要服务器吗 内容精选 换一换 AppCube的服务编排 支持对逻辑判断组件 数据处理组件 以及脚本 子服务编排 商业对象等进行可视化组合编排 实现丰富的业务功能 在传统的开发中程序员一般是基于代码进行开发 程序员需要学习
  • (2019.8.20半解决)Solving environment: failed with initial frozen solve. Retrying with flexible solve.Co

    用conda命令在linux安装python库出现上述错误 这里提到了这个问题 有人建议更新conda 我更新后无效 不过 conda不行 但是pip可以安装 问题先这样 后续有时间再仔细研究
  • ThreadLocal和ThreadLocalMap

    1 ThreadLocal是什么 是用来存放我们需要能够线程隔离的变量的 那就是线程本地变量 也就是说 当我们把变量保存在ThreadLocal当中时 就能够实现这个变量的线程隔离了 entry中的key使用了弱引用 static clas
  • 系统之家装机大师如何制作U盘启动盘?

    U盘的用途非常广泛 现在很多人都会使用U盘重装系统 那就需要先把U盘制作成U盘启动盘来重装系统 那要如何制作U盘启动盘呢 下面小编就教教大家使用系统之家装机大师制作U盘启动盘的方法 系统之家一键重装系统工具下载 系统之家装机大师官方版下载1
  • 【Redis学习笔记】2:认识Redisson及其分布式锁RLock.lock()

    Redisson和Jedis类似 都是用Java实现的操作Redis的客户端 但是使用场景不同 Redisson更多用在分布式场景下 功能可以看wiki Jedis更多用在单机场景下 1 Java接入Redisson 以Spring Boo