分布式锁_redis实现

本文涉及的产品
注册配置 MSE Nacos/ZooKeeper,118元/月
性能测试 PTS,5000VUM额度
容器服务 Serverless 版 ACK Serverless,952元额度 多规格
简介: 分布式锁_redis实现

为什么引入分布式锁?

在微服务中, 例如一个订单系统需要调用不同的商品库, 商品库里的数据保持一致,那么在不同的微服务之间, 一次只能由一个请求来访问, 那么在对两个库上就要加一个东西来识别,有没有线程在访问这个共同的资源,这即使分布式锁的思想

●特性
在这里插入图片描述

实现分布式锁

方式 1:SETNX 命令

要实现分布式锁,必须要求 Redis 有互斥的能力。可以使用 SETNX 命令,
其含义是 SET IF NOT EXIST,即如果 key 不存在,才会设置它的值,否则什么
也不做。两个客户端进程可以执行这个命令,达到互斥,就可以实现一个分布式

在这里插入图片描述

代码

    /*
      扣库存方法
      分布式锁1:
     */
    @RequestMapping(path = "/sub")
    public  String subStock(){
   
   
        //尝试向redis中设置一个键(锁),哪个线程设置成功,就获得锁, 设置成功返回true,失败则返回false
        String clientid = UUID.randomUUID().toString();
       try {
   
   
           boolean res =     redisTemplate.opsForValue().setIfAbsent("stock_lock",clientid,15, TimeUnit.SECONDS);
           if(!res){
   
   //获取锁失败
               return "fail";
           }
           //查询库存
           Integer count =     (Integer) redisTemplate.opsForValue().get("stock");
           if(count>0){
   
   
               count = count-1;
               redisTemplate.opsForValue().set("stock",count);
               return "success";
           }else{
   
   
               return "fail";
           }
       }finally {
   
   
             String id = (String)redisTemplate.opsForValue().get("stock_lock");
             if(id.equals(clientid)){
   
   
                 redisTemplate.delete("stock_lock");// 确保键最终是会被删除释放的
             }
       }
    }

这里由两个要点:

  1. 要给该代码添加finally,保证最后会释放锁,防止死锁; 例如程序报错,宕机
  2. 给redis的key添加失效时间, 防止该线程出错,或者该服务宕机之后, 造成持续持有锁__死锁, 使得其他线程无法操作
  3. 添加UUID,在finally要释放锁之前要判断, 保证是释放当前的锁

但是设置失效时间 10s,有可能业务执行时间大于 10s,那么锁会失效,导致其
他线程进入到减库存业务中,这时,第一个线程执行完成,会误删除第二个线程的
锁标志,导致其他线程进入.导致锁永久失效.

所以锁的失效时间一直是一个问题

所以就有了下面的方案

方式 2: 使用 redission

●依赖

 <dependency>
     <groupId>org.redisson</groupId>
     <artifactId>redisson</artifactId>
     <version>3.6.5</version>
 </dependency>

●创建 Redisson 对象

    //创建 Redisson 对象
    @Bean
    public Redisson getRedisson() {
   
   
        Config config = new Config();
        config.useSingleServer().setAddress("redis://120.48.37.232:6379").se
        tDatabase(0);
        return (Redisson) Redisson.create(config);
    }

●使用 Redisson 实现加锁,释放锁.
在这里插入图片描述

此时就算程序运行时间超过了设置的时间,RLock锁也会添加时间,防止其他线程进入;
始终保证该程序运行完成,同时finally会保证程序不会造成死锁

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
23天前
|
NoSQL Java Redis
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
Redis分布式锁在高并发场景下是重要的技术手段,但其实现过程中常遇到五大深坑:**原子性问题**、**连接耗尽问题**、**锁过期问题**、**锁失效问题**以及**锁分段问题**。这些问题不仅影响系统的稳定性和性能,还可能导致数据不一致。尼恩在实际项目中总结了这些坑,并提供了详细的解决方案,包括使用Lua脚本保证原子性、设置合理的锁过期时间和使用看门狗机制、以及通过锁分段提升性能。这些经验和技巧对面试和实际开发都有很大帮助,值得深入学习和实践。
太惨痛: Redis 分布式锁 5个大坑,又大又深, 如何才能 避开 ?
|
30天前
|
缓存 NoSQL Java
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
53 3
大数据-50 Redis 分布式锁 乐观锁 Watch SETNX Lua Redisson分布式锁 Java实现分布式锁
|
23天前
|
NoSQL Redis 数据库
计数器 分布式锁 redis实现
【10月更文挑战第5天】
44 1
|
27天前
|
NoSQL 算法 关系型数据库
Redis分布式锁
【10月更文挑战第1天】分布式锁用于在多进程环境中保护共享资源,防止并发冲突。通常借助外部系统如Redis或Zookeeper实现。通过`SETNX`命令加锁,并设置过期时间防止死锁。为避免误删他人锁,加锁时附带唯一标识,解锁前验证。面对锁提前过期的问题,可使用守护线程自动续期。在Redis集群中,需考虑主从同步延迟导致的锁丢失问题,Redlock算法可提高锁的可靠性。
68 4
|
30天前
|
存储 缓存 NoSQL
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
大数据-38 Redis 高并发下的分布式缓存 Redis简介 缓存场景 读写模式 旁路模式 穿透模式 缓存模式 基本概念等
53 4
|
30天前
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
51 3
|
1月前
|
存储 NoSQL 关系型数据库
【redis】认识redis和分布式系统
【redis】认识redis和分布式系统
25 1
|
27天前
|
缓存 NoSQL 算法
面试题:Redis如何实现分布式锁!
面试题:Redis如何实现分布式锁!
|
NoSQL Java 关系型数据库
浅谈Redis实现分布式锁
浅谈Redis实现分布式锁
|
NoSQL Redis 数据库
用redis实现分布式锁时容易踩的5个坑
云栖号资讯:【点击查看更多行业资讯】在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 近有不少小伙伴投入短视频赛道,也出现不少第三方数据商,为大家提供抖音爬虫数据。 小伙伴们有没有好奇过,这些数据是如何获取的,普通技术小白能否也拥有自己的抖音爬虫呢? 本文会全面解密抖音爬虫的幕后原理,不需要任何编程知识,还请耐心阅读。
用redis实现分布式锁时容易踩的5个坑