首页 > 数据库 >Redis 分布式锁

Redis 分布式锁

时间:2024-06-21 17:14:52浏览次数:27  
标签:KEYS Redis redis ARGV 线程 call 分布式

Redis 分布式锁

分布式锁的演变

  1. 本地锁(单机用)
  2. 利用redis进行分布式锁 使用 set
  3. 防止死锁 加过期时间 使用 setnx
  4. 防止A请求未执行完 锁过期删除 B请求加锁后 A完成后误删该锁 使用 Hash结构, 规定每个请求只能删除自己的锁
  5. 保证并发安全,申请锁和加过期时间需要 原子性,用 lua脚本 加锁或解锁
  6. 考虑到 重入性 (每个请求只拿到一个锁后,可以多函数或线程共用) 使用 Hash结构进行加减(hincrby) 操作
  7. 为了保证业务执行过长,锁不会过期。需要对锁进行 续期

分布式锁的特性

  1. 独占性
  2. 高可用
  3. 防死锁
  4. 不乱抢
  5. 可重入

1. setNX

  • 注意死锁
  • 注意lock过期时间和业务执行时间
  • 加锁不成功时,等待获取机制 ( 注意停几毫秒 )
  • 一般情况下完全够用

2. 考虑look重入性

  • 当一个锁被创建出来之后再同一个请求中不需要再额外申请其他锁,一个锁可以被重复使用,所以使用到 Hash数据结构的锁
  • 如果业务上需要应用到多个函数的锁的情况下,申请一个锁之后固定当前请求的uuid+当前线程id。入一个函数(或者线程)向Hash的uuid +1
  • 直到请求结束后,检查线程锁是否归0 如果是释放该锁,如果不是说明其他线程未能执行完毕。
  • 考虑可重入性的递减。 加锁几次就要减几次,到0后删除
锁的操作保证原子性应对高并发
  • 当一个锁(Hash结构) 创建锁和增加过期时间,两步需要lua脚本进行执行保证原子性。
// lua 脚本编写 
// 加锁操作  如果锁不存在或者当前请求锁的uuid字段存在 则进行加一 (重入性)
KEYS[1]  //  -- 分布式锁的key
ARGV[1]  //  -- 锁的唯一标识,通常是线程ID或调用者标识
ARGV[2]  //  -- 锁的过期时间,单位为毫秒

if redis.call('exists', KEYS[1]) == 0 //锁不存在
or redis.call('hexists', KEYS[1], ARGV[1]) == 1 // 当前请求有锁 进入函数(或新开线程)无需额外申请锁
then
  redis.call('hincrby',KEYS[1], ARGV[1], 1)
  redis.call('expire',KEYS[1], ARGV[2])
  return true
else
  return false
end

//解锁操作
  if redis.call("hexists",KEYS[1], ARGV[1]) == 0 then // 无锁  无需解锁
      return false
  else if redis.call("hincrby",KEYS[1], ARGV[1], -1) == 0 then  // 锁存在且是自己请求的锁 进行减一操作,如果减为0 则解锁(删key)
      retrun redis.call("DEL",KEYS[1])
  else
      return 0
  • 当lock 创建时,需要同步启动一个定时续期任务,锁存在并过该定时时间进行续期,防止业务未完直接释放锁。
  • 当主线程执行完业务流程 并释放锁之后,续期机制同时结束。

标签:KEYS,Redis,redis,ARGV,线程,call,分布式
From: https://www.cnblogs.com/Kuju/p/18260915

相关文章

  • redisson WRONGPASS invalid username-password pair or user is disable
    1、技术架构:若依微服务框架<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2021.1</version></dependency><dependency>......
  • 最全常见分布式ID生成方案
    近两年的技术面试,分布式系列问题是面试官经常会问到的一个高频方向。比如:分布式事务、分布式锁、分布式调度、分布式存储、分布式ID、分布式集群等。今天我们就来聊聊,这里面相对简单的分布式ID,首先来说下,我们为什么需要分布式ID?当系统数据量过大,数据查询已经达到瓶颈,进......
  • redis自学(47)服务端优化
    持久化配置Redis的持久化虽然可以保证数据安全,但也会带来很多额外的开销,因此持久化请遵循下列建议:①用来做缓存的redis实例尽量不要开启持久化功能②建议关闭RDB持久化功能,使用AOF持久化(RDB的数据安全性一直是有问题的,两次RDB的时间比较长,又不能频繁的RDB,因为耗时久而且需......
  • 并发业务使用redis分布式锁
    伴随着业务体量的上升,我们的qps与并发问题越来越明显,这时候就需要用到让代码一定情况下进行串行执行的工具:锁1.业务场景代码@Override@Transactional(rollbackFor=Exception.class)publicObjecttestBatch(Useruser){LambdaQueryWrapper<Us......
  • [转帖]Redis如何绑定CPU
    https://wenfh2020.com/2023/10/08/https/ 发布时间:2022-03-0809:44:39 阅读:649 作者:小新 栏目:开发技术开发者测试专用服务器限时活动,0元免费领,库存有限,领完即止!点击查看>>这篇文章主要介绍了Redis如何绑定CPU,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这......
  • RedisDesktopManager的使用
    简介        RedisDesktopManager(RDM)是一个开源的图形化Redis数据库管理工具,是Redis可视化工具,支持Windows、macOS和Linux平台        它提供了一系列的功能,如连接管理、数据浏览、编辑和调试等,帮助用户管理和操作Redis数据库;适用于多种操作系......
  • Redis集群搭建及原理详解
    1.Redis集群方案比较1.1哨兵模式在redis3.0以前的版本要实现集群一般是借助哨兵sentinel工具来监控master节点的状态,如果master节点异常,则会做主从切换,将某一台slave作为master,哨兵的配置略微复杂,并且性能和高可用性等各方面表现一般,特别是在主从切换的瞬间存在访问瞬断......
  • Redis 缓存应用、淘汰机制
    (四)Redis缓存应用、淘汰机制 合集-Redis(4) 1.(一)LinuxCentOSRedis安装05-082.(二)Redis数据类型与结构05-173.(三)Redis线程与IO模型06-054.(四)Redis缓存应用、淘汰机制06-20收起 1、缓存应用一个系统中不同层面数据访问速度不一样,以计算机为例,CPU、内存......
  • Redis漏洞原理
    Redis漏洞原理Redis简单介绍Redis是一款内存高速缓存的数据库,是一款K-V型数据库,它的所有键值都是用字典来存储的。其中它的value支持多种数据类型,包括String、List、Set、Zset和Hash。‍Redis未授权访问漏洞介绍利用条件Redis默认情况下绑定在127.0.0.1:6379,在没有进......
  • 【异常】nested exception is java.lang.NoClassDefFoundError: redis/clients/jedis/
    原因是版本冲突。以下我原本使用的版本信息<!--SpringBootRedis依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId><version>2.1.8.RELEASE</version><......