Redis缓存:简洁实用的Redis分布式锁用法
mhr18 2024-11-27 11:57 17 浏览 0 评论
在微服务中很多情况下需要使用到分布式锁功能,而目前比较常见的方案是通过Redis来实现分布式锁,网上关于分布式锁的实现方式有很多,早期主要是基于Redisson等客户端,但在Spring Boot2.x以上版本中使用Redis时,其客户端库已经默认使用lettuce。
所以本文将直接介绍在Spring Boot2.x以上项目中快速使用Redis分布式锁的功能的方法,希望能够更新你的知识库!
Redis分布式锁原理概述
实际上Redis服务本身并不提供分布式锁这样的机制,但是作为全局Key-Value存储系统,客户端可以利用Redis提供的基本功能并通过一定的算法设计来实现分布式锁功能。目前已有不少博客文章及代码库描述了如何使用Redis来实现分布式锁,但是许多实现相对比较简单,安全性也比较低。
在Redis的官方文档中推荐了一种叫做RedLock的算法来实现基于Redis的分布式锁功能,现阶段已存在基于该算法的多种语言版本的Redis客户端实现库。其中Java领域最为知名的是Redisson库。但由于Redisson不仅实现了分布式锁功能,还额外实现了一套Redis分布式数据结构,因此会显得比较重,加上最新的基于Spring Boot.2.x以上版本使用Redis时,其客户端库已经默认使用了lettuce(比Redisson、Jedis线程更安全、更轻量级的一种Java Redis客户端库)的封装,所以为了更加符合微服务场景下的使用,在实践中往往会选择基于RedLock算法自行实现分布式锁。
本案例也将演示如何RedLock算法来实现Redis分布式锁功能,不过在此之前让我们先来看看RedLock算法是如何运行的,示意图如下:
以上就是实现Redis分布式锁官方推荐的RedLock算法逻辑,它是一种多节点Redis的分布式锁算法,可以有效防止单节点故障问题。其执行步骤说明如下:
- 首先Redis客户端获取当前系统时间,以毫秒为单位;
- 然后客户端会顺序地尝试向Redis集群中的每个节点获取锁,其具体步骤是使用相同的键Key名和随机值;在向每个Redis节点获取锁的过程中,客户端会以比锁过期时间小得多的时间来设定超时机制,例如锁的整个超时时间为10秒,集群有5个节点,那么每个节点获取锁的超时时间可能会被限制在5~50毫秒之间,这是为了防止在某个节点不可用的情况下,客户端等待时间过长,造成性能阻塞;
- 之后随着各节点获取锁结果的反馈,Redis客户端会对获取情况进行判断,如果获取各节点锁的总时间小于锁的超时时间设置,并且成功获取锁的节点数目大于N/2+1个(例如5个节点至少要有3个节点成功获取锁),满足上述条件的情况下,Redis客户端才会认为获取锁成功,否则就会认为锁获取失败,并依次释放掉各个节点的锁信息;
- 获取锁成功后即可以安全地执行操作,完成后再依次释放各节点锁持有的锁信息;
实现上述算法的Redis客户端可以基本上保证分布式锁的有效性及安全性的几个基本特性要求:
- 互斥:任何时刻只能有一个Redis客户端获取锁;
- 无死锁:即使锁定资源的服务崩溃或者分区,仍然能释放锁);
- 容错性:只要多数redis节点(一半以上)在使用,Redis客户端就可以获取和释放锁;
Spring Boot集成使用方式
通过前面内容的描述,相信你对实现Redis分布式锁的基本算法应该有了一定的认识和理解。而在实践的过程中可以依据该算法自行定制实现,但实际上Spring早就提供了基于该算法的Redis的分布式锁的实现。其具体使用步骤如下:
1)在工程pom.xml文件中引入Spring Integration依赖,代码如下:
<!-- spring integration -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<!-- spring integration与redis结合,实现redis分布式锁 -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
目前Spring所提供的分布式锁相关的代码被迁移在Spring Integration子项目中,所以这里引入其相关依赖。
2)编写RedisLock的配置类,代码如下:
@Configuration
public class RedisLockConfiguration {
@Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "payment");
}
}
以上配置代码加载的前提在于应用已经集成了Redis服务访问链接信息,具体Spring Boot项目集成Redis访问的方式比较简单可以参考其他资料。
3)分布式锁的具体使用方式,代码片段如下:
/**
* 引入Redis分布式锁依赖组件
*/
@Autowired
private RedisLockRegistry redisLockRegistry;
@Override
public UnifiedPayBO unifiedPay(UnifiedPayDTO unifiedPayDTO) {
...
//创建Redis分布式锁
Lock lock = redisLockRegistry.obtain(redisLockPrefix + unifiedPayDTO.getOrderId());
try {
//尝试获取锁
boolean isLock = lock.tryLock(1, TimeUnit.SECONDS);
if (isLock) {
//执行业务逻辑
...
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//释放分布式锁
lock.unlock();
}
...
}
上述代码为订单防重时使用Redis分布锁的示例代码,通过依赖注入RedisLockRegistry实例来实现分布式锁的相关操作,例如obtain()方法创建锁、tryLock()持有锁及unlock()释放锁等。
本文转载于公众号:无敌码农
- 上一篇:redis 分布式锁
- 下一篇:死磕面试:redis分布式锁和zk的,有什么不同?
相关推荐
- Docker安装详细步骤及相关环境安装配置
-
最近自己在虚拟机上搭建一个docker,将项目运行在虚拟机中。需要提前准备的工具,FinallShell(远程链接工具),VM(虚拟机-配置网络)、CentOS7(Linux操作系统-在虚拟机上安装)...
- Linux下安装常用软件都有哪些?做了一个汇总列表,你看还缺啥?
-
1.安装列表MySQL5.7.11Java1.8ApacheMaven3.6+tomcat8.5gitRedisNginxpythondocker2.安装mysql1.拷贝mysql安装文件到...
- Nginx安装和使用指南详细讲解(nginx1.20安装)
-
Nginx安装和使用指南安装1.检查并安装所需的依赖软件1).gcc:nginx编译依赖gcc环境安装命令:yuminstallgcc-c++2).pcre:(PerlCompatibleRe...
- docker之安装部署Harbor(docker安装hacs)
-
在现代软件开发和部署环境中,Harbor作为一个企业级的容器镜像仓库,提供了高效、安全的镜像管理解决方案。通过Docker部署Harbor,可以轻松构建私有镜像仓库,满足企业对镜像存储、管理和安全性...
- 成功安装 Magento2.4.3最新版教程「技术干货」
-
外贸独立站设计公司xingbell.com经过多次的反复实验,最新版的magento2.4.3在oneinstack的环境下的详细安装教程如下:一.vps系统:LinuxCentOS7.7.19...
- 【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu
-
学习Linux并掌握Java环境配置及SpringBoot项目部署是一个系统化的过程,以下是从零开始的详细指南,帮助你逐步掌握这些技能。一、Linux基础入门1.安装Linux系统选择发行版:推荐...
- cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务
-
cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务(yum选择的,时间不同,版本不同)如果对运维课程感兴趣,可以在b站上搜索我的账号:运维实战课程,可以关注我,学习更多免费的运...
- 时隔三月,参加2020秋招散招,终拿字节跳动后端开发意向书.
-
3个月前头条正式批笔试4道编程题只AC了2道,然后被刷了做了200多道还是太菜了,本来对字节不抱太大希望,毕竟后台竞争太大,而且字节招客户端开发比较多。后来看到有散招免笔试,抱着试一试的心态投了,然而...
- Redisson:Java程序员手中的“魔法锁”
-
Redisson:Java程序员手中的“魔法锁”在这个万物互联的时代,分布式系统已经成为主流。然而,随着系统的扩展,共享资源的争夺成为了一个棘手的问题。就比如你想在淘宝“秒杀”一款商品,却发现抢的人太...
- 【线上故障复盘】RPC 线程池被打满,1024个线程居然不够用?
-
1.故障背景昨天晚上,我刚到家里打开公司群,就看见群里有人讨论:线上环境出现大量RPC请求报错,异常原因:被线程池拒绝。虽然异常量很大,但是异常服务非核心服务,属于系统旁路,服务于数据核对任务,即使...
- 小红书取消大小周,有人不高兴了!
-
小红书宣布五一节假日之后,取消大小周,恢复为正常的双休,乍一看工作时长变少,按道理来说大家应该都会很开心,毕竟上班时间缩短了,但是还是有一些小红书的朋友高兴不起来,心情很复杂。因为没有了大小周,以前...
- 延迟任务的多种实现方案(延迟机制)
-
场景订单超时自动取消:延迟任务典型的使用场景是订单超时自动取消。功能精确的时间控制:延时任务的时间控制要尽量准确。可靠性:延时任务的处理要是可靠的,确保所有任务最终都能被执行。这通常要求延时任务的方案...
- 百度java面试真题(java面试题下载)
-
1、SpingBoot也有定时任务?是什么注解?在SpringBoot中使用定时任务主要有两种不同的方式,一个就是使用Spring中的@Scheduled注解,另一个则是使用第三方框架Q...
- 回归基础:访问 Kubernetes Pod(concurrent.futures访问数据库)
-
Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多概念。在这里,学习几种访问集群外pod的方法。Kubernetes是一头巨大的野兽。在它开始有用之前,您需要了解许多不同的...
- Spring 缓存神器 @Cacheable:3 分钟学会优化高频数据访问
-
在互联网应用中,高频数据查询(如商品详情、用户信息)往往成为性能瓶颈。每次请求都触发数据库查询,不仅增加服务器压力,还会导致响应延迟。Spring框架提供的@Cacheable注解,就像给方法加了一...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- Docker安装详细步骤及相关环境安装配置
- Linux下安装常用软件都有哪些?做了一个汇总列表,你看还缺啥?
- Nginx安装和使用指南详细讲解(nginx1.20安装)
- docker之安装部署Harbor(docker安装hacs)
- 成功安装 Magento2.4.3最新版教程「技术干货」
- 【Linux】——从0到1的学习,让你熟练掌握,带你玩转Linu
- cent6.5安装gitlab-ce最新版本-11.8.2并配置邮件服务
- 时隔三月,参加2020秋招散招,终拿字节跳动后端开发意向书.
- Redisson:Java程序员手中的“魔法锁”
- 【线上故障复盘】RPC 线程池被打满,1024个线程居然不够用?
- 标签列表
-
- oracle位图索引 (63)
- oracle批量插入数据 (62)
- oracle事务隔离级别 (53)
- oracle 空为0 (50)
- oracle主从同步 (55)
- oracle 乐观锁 (51)
- redis 命令 (78)
- php redis (88)
- redis 存储 (66)
- redis 锁 (69)
- 启动 redis (66)
- redis 时间 (56)
- redis 删除 (67)
- redis内存 (57)
- redis并发 (52)
- redis 主从 (69)
- redis 订阅 (51)
- redis 登录 (54)
- redis 面试 (58)
- 阿里 redis (59)
- redis 搭建 (53)
- redis的缓存 (55)
- lua redis (58)
- redis 连接池 (61)
- redis 限流 (51)