Redis分布式锁的实现、优化与Redlock算法探讨

Redis分布式锁最简单的实现

要实现分布式锁,首先需要Redis具备“互斥”能力,这可以通过SETNX命令实现。SETNX表示SET if Not Exists,即如果key不存在,才会设置它的值,否则什么也不做。利用这一点,不同客户端就能实现互斥,从而实现一个分布式锁。

举例:

  • 客户端1申请加锁,加锁成功:
  • 客户端2申请加锁,由于它后到达,所以加锁失败:

加锁成功

当加锁成功的客户端操作完共享资源后,需要及时释放锁,通常通过DEL命令删除这个key即可。

释放锁

避免死锁

如果加锁的客户端出现异常或挂掉,那么可能会造成死锁现象,为避免这种情况,可以给锁设置一个过期时间:

SETNX lock 1    // 加锁
EXPIRE lock 10  // 10s后自动过期

加锁及过期

但是,由于SETNX和EXPIRE是两条命令,无法保证其原子性,因此有可能只执行了SETNX,未执行EXPIRE。为了解决这个问题,可以使用Redis 2.6.12之后扩展的SET命令:

SET lock 1 EX 10 NX

SET EX NX

防止锁被其他客户端释放

为防止锁被其他客户端释放,可以在加锁时设置一个只有自己知道的“唯一标识”:

SET lock $uuid EX 20 NX

释放锁时,先检查锁是否归自己持有:

if redis.get("lock") == $uuid:redis.del("lock")

由于GET和DEL不是原子操作,可以使用Lua脚本来保证原子性:

if redis.call("GET",KEYS[1]) == ARGV[1]
thenreturn redis.call("DEL",KEYS[1])
elsereturn 0
end

Java代码实现分布式锁

package com.msb.redis.lock;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.params.SetParams;import java.util.Arrays;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;@Component
public class RedisDistLock implements Lock {private final static int LOCK_TIME = 5*1000;private final static String RS_DISTLOCK_NS = "tdln:";private final static String RELEASE_LOCK_LUA ="if redis.call('get',KEYS[1])==ARGV[1] then\n" +"        return redis.call('del', KEYS[1])\n" +"    else return 0 end";private ThreadLocal<String> lockerId = new ThreadLocal<>();private Thread ownerThread;private String lockName = "lock";@Autowiredprivate JedisPool jedisPool;public String getLockName() {return lockName;}public void setLockName(String l

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

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

相关文章

提升学术研究效率与质量的关键

科研工具与资源的发展在信息时代尤为重要&#xff0c;它们不仅能够提升学术研究的效率&#xff0c;还能够促进科学成果的共享与交流。本文旨在探讨几种主要的科研工具与资源&#xff0c;涵盖文献检索、语言翻译、实验方案、数据库查询、在线绘图等多个方面&#xff0c;帮助研究…

(科学:某天是星期几)泽勒一致性是由克里斯汀·泽勒开发的用于计算某天是星期几的算法。

(科学:某天是星期几)泽勒一致性是由克里斯汀泽勒开发的用于计算某天是星期几的算法。这个公式是: 其中: h是一个星期中的某一天(0 为星期六;1 为星期天;2 为星期一;3 为星期二;4 为 星期三;5 为星期四;6为星期五)。 q 是某月的第几天。 m 是月份(3 为三月&#xff0c;4 为四月,…

朴素贝叶斯分类器 #数据挖掘 #Python

朴素贝叶斯分类器是一种基于概率统计的简单但强大的机器学习算法。它假设特征之间是相互独立的&#xff08;“朴素”&#xff09;&#xff0c;尽管在现实世界中这通常不成立&#xff0c;但在许多情况下这种简化假设仍能提供良好的性能。 基本原理&#xff1a;朴素贝叶斯分类器…

笔记本开机原理

从按下开机键开始&#xff0c;机器是如何开到OS的呢&#xff1f;今天这篇文章和大家极少EC-BIOS-OS的整个开机流程。首先大家要对笔记本的基本架构有所了解&#xff0c;基本架构如下图所示&#xff08;主要组成部分为大写黑体内容&#xff09;。 一、按下PowerButton按钮&#…

说下你对Spring IOC 的理解

总结&#xff1a;IOC是一个容器&#xff0c;用来管理对象之间的依赖关系。 控制反转&#xff0c;依赖注入--->注入的方式。。。 说下你对Spring IOC 的理解 1. Spring IOC是一个管理对象之间依赖关系的容器&#xff0c;它实现了依赖注入技术&#xff0c;可以解决传统的紧耦…

人工智能发展历程了解和Tensorflow基础开发环境构建

目录 人工智能的三次浪潮 开发环境介绍 Anaconda Anaconda的下载和安装 下载说明 安装指导 模块介绍 使用Anaconda Navigator Home界面介绍 Environment界面介绍 使用Jupter Notebook 打开Jupter Notebook 配置默认目录 新建文件 两种输入模式 Conda 虚拟环境 添…

酷开会员丨酷开系统K歌模式,父亲节的家庭欢聚时光

K歌以其独特的魅力&#xff0c;为家庭娱乐带来了无限乐趣。想象一下&#xff0c;父亲节这天&#xff0c;打开电视进入K歌频道&#xff0c;与家人一起嗨唱&#xff0c;客厅里充满了欢声笑语&#xff0c;酷开系统的K歌应用也就成为了连接亲情的桥梁&#xff0c;让爸爸们都能在这个…

STM32面试题

STM32面试题通常涉及STM32微控制器的特性、功能、应用以及编程知识。以下是一些可能的面试问题: STM32微控制器的基本介绍: STM32微控制器是由哪家公司生产的?STM32微控制器主要应用于哪些领域?STM32的特性和功能: STM32微控制器有哪些主要特性?请描述STM32的GPIO(通用输…

SQL join和EXISTS效率

先看两个查询&#xff0c;查询目的是在a表中找出b表出现的vid 1.join查询 select a.vid, a.attach_url, a.attach_url_type, a.create_time from ods_truck.tl_vehicle_attach_log ajoin (select distinct vidfrom ods_truck.tl_truck_log_20240613where oprater in (remove,…

Nvidia芯片Jetson系列 系统烧录环境 搭建

一、序言 Jetson 系列产品烧录系统的方法一般有两种&#xff1a; 一种为使用 NVIDIA 官方提供 的 SDK manager 软件给 Jetson 设备烧录系统&#xff08;请查看说明文档《Jetson 产品使用 SDKmanager 烧录系统》&#xff09;。 另一种即为当前文档所描述的&#xff0c;在安装 Ub…

基于SSM+Jsp的旅游景点线路网站

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

开源新纪元:ChatTTS——引领对话式文本转语音的新潮流

✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点赞、关注、收藏、评论&#xff0c;是对我最大…

好用的库函数,qsort函数大详解(干货满满!)(进阶)

前言&#xff1a; 小编在上一篇文章说了这一篇将要写qsort函数的模拟实现&#xff0c;那么废话不多说&#xff0c;现在开始进入今天的代码之旅喽&#xff01; 目录&#xff1a; 1.qsort函数的模拟实现的逻辑和思路 2.qsort函数模拟实现的代码实现 3.代码展示 1.qsort函数的模…

【WEB前端2024】3D智体编程:乔布斯3D纪念馆-第41课-动态添加3D对象

【WEB前端2024】3D智体编程&#xff1a;乔布斯3D纪念馆-第41课-动态添加3D对象 使用dtns.network德塔世界&#xff08;开源的智体世界引擎&#xff09;&#xff0c;策划和设计《乔布斯超大型的开源3D纪念馆》的系列教程。dtns.network是一款主要由JavaScript编写的智体世界引擎…

2.华为配置静态路由

通过配置静态路由让PC1和PC2互通 AR1 [Huawei]int g0/0/0 [Huawei-GigabitEthernet0/0/0]ip add 192.168.1.254 24 [Huawei]int g0/0/1 [Huawei-GigabitEthernet0/0/1]ip add 1.1.1.1 24 [Huawei]ip route-static 192.168.2.0 24 1.1.1.2AR2 [Huawei]int g0/0/0 [Huawei-Gig…

【Android面试八股文】讲一讲String、StringBuffer和StringBuilder在进行字符串操作时候的效率

文章目录 一、String二、StringBuffer三、StringBuilder四、String、StringBuffer和StringBuilder的效率测试五、String、StringBuffer和StringBuilder的选择一、String String是不可变的,final修饰,任何对String的操作都会创建一个新的String对象。在进行大量字符串拼接或修…

盘点有趣的人工智能开源项目一

字幕导出 zh_recogn是一个专注于中文语音识别的字幕生成工具&#xff0c;基于魔塔社区Paraformer模型。它不仅支持音频文件&#xff0c;还能处理视频文件&#xff0c;输出标准的SRT字幕格式。这个项目提供了API接口和简单的用户界面&#xff0c;使得用户可以根据自己的需求灵活…

前端面试题日常练-day72 【面试题】

题目 希望这些选择题能够帮助您进行前端面试的准备&#xff0c;答案在文末 在Sass中&#xff0c;以下哪个关键字用于定义一个占位符选择器&#xff0c;以便在后续使用时进行扩展&#xff1f; a) placeholder b) extend c) mixin d) import Sass中的函数&#xff08;Function&…

GitLab、jenkins

Gitlab服务器&#xff1a;192.168.10.20 jenkins服务器&#xff1a;192.168.10.30 web应用服务器&#xff1a;192.168.10.100 通过容器部署gitlab&#xff1a; 安装容器管理软件podman 修改主机的22端口&#xff0c;该gitlab软件包中会使用到该端口 gitlab容器需要使用/etc/res…

一二三应用开发平台应用开发示例(3)——生成库表及后端代码

生成库表 前端页面的配置&#xff0c;也就是视图功能&#xff0c;我们先放一放&#xff0c;来看看生成库表和后端代码。 关闭实体配置界面&#xff0c;回到实体列表&#xff0c;勾选“文件夹”实体&#xff0c;点击“生成库表”&#xff0c;并确定。 系统提示成功后&#xff…