【Redis】Redis实现分布式锁合理的控制锁的有效时长的方法

2024-06-09 11:12

本文主要是介绍【Redis】Redis实现分布式锁合理的控制锁的有效时长的方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在分布式系统中,合理地控制 Redis 分布式锁的有效时长(即过期时间)非常重要,以确保锁既能防止死锁又能提供高可用性。设置合理的过期时间可以防止客户端在持有锁期间崩溃而导致其他客户端无法获取锁的情况,同时也能确保锁在操作未完成时不会过早失效。

以下是实现合理控制 Redis 分布式锁有效时长的方法和注意事项:

方法一:估算操作时间并加上缓冲时间

最简单的方法是根据操作的预期时间设置锁的有效时长。通常会估算操作需要的时间,并加上一些缓冲时间,以应对网络延迟和其他不确定因素。

示例代码

public class RedisDistributedLock {private Jedis jedis;private String lockKey;private int expireTime; // 锁的过期时间(秒)public RedisDistributedLock(Jedis jedis, String lockKey, int expireTime) {this.jedis = jedis;this.lockKey = lockKey;this.expireTime = expireTime;}public boolean acquireLock(String requestId) {String result = jedis.set(lockKey, requestId, "NX", "EX", expireTime);return "OK".equals(result);}public boolean releaseLock(String requestId) {String script ="if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('del', KEYS[1]) " +"else " +"return 0 " +"end";Object result = jedis.eval(script, 1, lockKey, requestId);return "1".equals(result.toString());}
}

在上述代码中,expireTime 应根据操作的预期时间加上缓冲时间来设置。

方法二:锁续命(Lock Renewal)

对于一些可能超过预期时间的长时间操作,可以使用锁续命机制。在锁快要过期时,客户端可以通过续命机制延长锁的有效时间。

实现思路

  1. 在锁快要过期时,客户端定期检查锁是否仍然持有,并尝试续命。
  2. 续命可以通过重新设置过期时间实现。

示例代码

public class RedisDistributedLock {private Jedis jedis;private String lockKey;private int expireTime; // 锁的过期时间(秒)private volatile boolean keepExtending = true;public RedisDistributedLock(Jedis jedis, String lockKey, int expireTime) {this.jedis = jedis;this.lockKey = lockKey;this.expireTime = expireTime;}public boolean acquireLock(String requestId) {String result = jedis.set(lockKey, requestId, "NX", "EX", expireTime);if ("OK".equals(result)) {startRenewalTask(requestId);return true;}return false;}public boolean releaseLock(String requestId) {keepExtending = false;String script ="if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('del', KEYS[1]) " +"else " +"return 0 " +"end";Object result = jedis.eval(script, 1, lockKey, requestId);return "1".equals(result.toString());}private void startRenewalTask(String requestId) {Thread renewalThread = new Thread(() -> {while (keepExtending) {try {Thread.sleep(expireTime * 1000 / 2);String script ="if redis.call('get', KEYS[1]) == ARGV[1] then " +"return redis.call('expire', KEYS[1], ARGV[2]) " +"else " +"return 0 " +"end";jedis.eval(script, 1, lockKey, requestId, String.valueOf(expireTime));} catch (InterruptedException e) {Thread.currentThread().interrupt();}}});renewalThread.setDaemon(true);renewalThread.start();}
}

在上述代码中:

  • startRenewalTask 方法启动一个后台线程,在锁的过期时间的一半时尝试续命。
  • keepExtending 标志用于控制续命线程的生命周期。

方法三:使用 Watchdog 机制

类似于锁续命机制,但更加高级的是 Watchdog 机制。在许多分布式锁实现中(例如 Apache Curator 的分布式锁),Watchdog 机制会自动续命直到客户端明确释放锁。

实现思路

  1. 获取锁时,启动 Watchdog 线程,该线程定期检查并续命。
  2. 释放锁时,停止 Watchdog 线程。

注意事项

  1. 锁的过期时间:设置过期时间时,需要根据操作的复杂度和预期执行时间设置一个合理的值,避免锁过早过期。
  2. 锁续命机制:确保续命操作是安全且高效的,避免过多的续命操作增加 Redis 的负担。
  3. 网络和系统故障:考虑网络延迟和系统故障的情况,确保锁机制在这些情况下仍然有效。
  4. 锁的标识:确保每个锁操作都有唯一的标识,避免误删锁(例如使用 UUID 作为锁的标识)。

通过合理设置锁的有效时长,并结合锁续命或 Watchdog 机制,可以有效地控制 Redis 分布式锁的有效性,确保系统在高并发和分布式环境下的稳定性和一致性。

这篇关于【Redis】Redis实现分布式锁合理的控制锁的有效时长的方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1045012

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

问题:第一次世界大战的起止时间是 #其他#学习方法#微信

问题:第一次世界大战的起止时间是 A.1913 ~1918 年 B.1913 ~1918 年 C.1914 ~1918 年 D.1914 ~1919 年 参考答案如图所示

[word] word设置上标快捷键 #学习方法#其他#媒体

word设置上标快捷键 办公中,少不了使用word,这个是大家必备的软件,今天给大家分享word设置上标快捷键,希望在办公中能帮到您! 1、添加上标 在录入一些公式,或者是化学产品时,需要添加上标内容,按下快捷键Ctrl+shift++就能将需要的内容设置为上标符号。 word设置上标快捷键的方法就是以上内容了,需要的小伙伴都可以试一试呢!

大学湖北中医药大学法医学试题及答案,分享几个实用搜题和学习工具 #微信#学习方法#职场发展

今天分享拥有拍照搜题、文字搜题、语音搜题、多重搜题等搜题模式,可以快速查找问题解析,加深对题目答案的理解。 1.快练题 这是一个网站 找题的网站海量题库,在线搜题,快速刷题~为您提供百万优质题库,直接搜索题库名称,支持多种刷题模式:顺序练习、语音听题、本地搜题、顺序阅读、模拟考试、组卷考试、赶快下载吧! 2.彩虹搜题 这是个老公众号了 支持手写输入,截图搜题,详细步骤,解题必备

电脑不小心删除的文件怎么恢复?4个必备恢复方法!

“刚刚在对电脑里的某些垃圾文件进行清理时,我一不小心误删了比较重要的数据。这些误删的数据还有机会恢复吗?希望大家帮帮我,非常感谢!” 在这个数字化飞速发展的时代,电脑早已成为我们日常生活和工作中不可或缺的一部分。然而,就像生活中的小插曲一样,有时我们可能会在不经意间犯下一些小错误,比如不小心删除了重要的文件。 当那份文件消失在眼前,仿佛被时间吞噬,我们不禁会心生焦虑。但别担心,就像每个问题

通过SSH隧道实现通过远程服务器上外网

搭建隧道 autossh -M 0 -f -D 1080 -C -N user1@remotehost##验证隧道是否生效,查看1080端口是否启动netstat -tuln | grep 1080## 测试ssh 隧道是否生效curl -x socks5h://127.0.0.1:1080 -I http://www.github.com 将autossh 设置为服务,隧道开机启动

有效利用MRP能为中小企业带来什么?

在离散制造企业,主流的生产模式主要为面向订单生产和面向库存生产(又称为预测生产),在中小企业中,一般为面向订单生产,也有部分面向库存和面向订单混合的生产方式(以面向订单为主,面向库存为辅),主要是应对市场需求的波动,对生产稳定性造成影响。 制定资源计划至关重要,但很多中小企业目前依赖人工、Excel表格等传统方式做各种记录、统计分析。时常会遇到: 生产任务无法统筹安排, 采购不及时, 订单

Eureka高可用注册中心registered-replicas没有分布式注册中心

自己在学习过程中发现,如果Eureka挂掉了,其他的Client就跑不起来了,那既然是商业项目,还是要处理好这个问题,所以决定用《Spring Cloud微服务实战》(PDF版在全栈技术交流群中自行获取)中说的“高可用注册中心”。 一开始我yml的配置是这样的 server:port: 8761eureka:instance:hostname: 127.0.0.1client:fetch-r

Windows/macOS/Linux 安装 Redis 和 Redis Desktop Manager 可视化工具

本文所有安装都在macOS High Sierra 10.13.4进行,Windows安装相对容易些,Linux安装与macOS类似,文中会做区分讲解 1. Redis安装 1.下载Redis https://redis.io/download 把下载的源码更名为redis-4.0.9-source,我喜欢跟maven、Tomcat放在一起,就放到/Users/zhan/Documents

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测

时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测 目录 时序预测 | MATLAB实现LSTM时间序列未来多步预测-递归预测基本介绍程序设计参考资料 基本介绍 MATLAB实现LSTM时间序列未来多步预测-递归预测。LSTM是一种含有LSTM区块(blocks)或其他的一种类神经网络,文献或其他资料中LSTM区块可能被描述成智能网络单元,因为