首页 > 其他分享 >分布式锁

分布式锁

时间:2023-07-31 11:47:09浏览次数:29  
标签:SET lock 加锁 key 分布式 客户端

参考:

java guide:分布式锁常见实现方案总结

小林 coding: 如何用 redis 实现分布式锁的?

 

在多线程环境中,如果多个线程同时访问共享资源(例如商品库存、外卖订单),会发生数据竞争,可能会导致出现脏数据或者系统问题,威胁到程序的正常运行。

分布式锁是用于分布式环境下并发控制的一种机制,用于控制某个资源在同一时刻只能被一个应用所使用。

 

Redis 的 SET 命令有个 NX 参数可以实现「key不存在才插入」,所以可以用它来实现分布式锁:

  • 如果 key 不存在,则显示插入成功,可以用来表示加锁成功;
  • 如果 key 存在,则会显示插入失败,可以用来表示加锁失败。

基于 Redis 节点实现分布式锁时,对于加锁操作,我们需要满足三个条件。

  • 加锁包括了读取锁变量、检查锁变量值和设置锁变量值三个操作,但需要以原子操作的方式完成,所以,我们使用 SET 命令带上 NX 选项来实现加锁;
  • 锁变量需要设置过期时间,以免客户端拿到锁后发生异常,导致锁一直无法释放,所以,我们在 SET 命令执行时加上 EX/PX 选项,设置其过期时间;
  • 锁变量的值需要能区分来自不同客户端的加锁操作,以免在释放锁时,出现由非加锁客户端来误释放操作,所以,我们使用 SET 命令设置锁变量值时,每个客户端设置的值是一个唯一值,用于标识客户端;

满足这三个条件的分布式命令如下:

SET lock_key unique_value NX PX 10000 
  • lock_key 就是 key 键;
  • unique_value 是客户端生成的唯一的标识,区分来自不同客户端的锁操作;
  • NX 代表只在 lock_key 不存在时,才对 lock_key 进行设置操作;
  • PX 10000 表示设置 lock_key 的过期时间为 10s(PX 单位为 s EX 单位为 ms),这是为了避免客户端发生异常而无法释放锁。

而解锁的过程就是将 lock_key 键删除(del lock_key),但不能乱删,要保证执行操作的客户端就是加锁的客户端。所以,解锁的时候,我们要先判断锁的 unique_value 是否为加锁客户端,是的话,才将 lock_key 键删除。

可以看到,解锁是有两个操作,这时就需要 Lua 脚本来保证解锁的原子性,因为 Redis 在执行 Lua 脚本时,可以以原子性的方式执行,保证了锁释放操作的原子性。

// 释放锁时,先比较 unique_value 是否相等,避免锁的误释放
if redis.call("get",KEYS[1]) == ARGV[1] then
    return redis.call("del",KEYS[1])
else
    return 0
end

这样一来,就通过使用 SET 命令(加锁)和 Lua 脚本(解锁)在 Redis 单节点上完成了分布式锁的加锁和解锁。

 

标签:SET,lock,加锁,key,分布式,客户端
From: https://www.cnblogs.com/suBlog/p/17593023.html

相关文章

  • 谷粒商城项目篇7_分布式高级篇_全文检索ES、商城业务(商品上架)、Feign源码简析
    目录全文检索ESES入门概念Docker安装ES基本操作举栗查询QueryDSL聚合aggregations映射Mapping安装ik分词器安装Nginx,配置远程词库整合SpringBoot新建微服务模块,导入依赖配置使用测试项目中使用场景商城业务商品上架ES的Mapping设计上架代码编写Feign源码封装消息返回R细节问题一、......
  • 分布式id
    自增idb+树节点是有序的,所以id最好也是有序的,这样存储数据效率高一点,如果不是递增的,那讲数据存储到数据库中效率较低,还得找树的值,递增的话直接按id插入到树中即可,而乱序则还得找相应的位置才能进行插入。趋势递增:总体来看顺序是递增的。单调递增:下一个一定比上一个大。信息......
  • GoRedisLock:Golang保障数据一致性的分布式锁解决方案
    在现代分布式系统中,多个节点之间共享资源是常见的需求。然而,并发访问共享资源可能导致数据不一致性和竞争条件。为了解决这些问题,我们需要引入分布式锁。GoRedisLock是一个出色的分布式锁库,它结合了Go语言和Redis的优势,提供了稳定高效的分布式并发控制解决方案。**项目地址:**htt......
  • Dapr中国社区活动之 分布式运行时开发者日 (2022.09.03)
    自2019年10月首次发布以来,Dapr(DistributedApplicationRuntime,分布式应用运行时)因其“更稳定”、“更可靠”、“更一致”、“更简单”,吸引了大量的关注和喜爱,至今在GitHub上已有近1.9万Stars,俨然已成为开发者圈的新晋“网红”。Dapr具备先天的跨语言优势,其设计更是从根基上兼......
  • 分布式ID性能评测:CosId VS 美团 Leaf
    分布式ID性能评测:CosIdVS美团Leaf基准测试环境MacBookPro(M1)JDK17JMH1.36运行在本机的Docker的mariadb:10.6.4运行基准测试基准测试代码:https://github.com/Ahoo-Wang/CosId/tree/main/[email protected]:Ahoo-Wang/CosId.gitcdco......
  • 智能网卡在分布式 SDN 网络的应用与实践 | 龙蜥技术
    编者按:当前智能网卡能够加速数据处理和传输,并能实现网络、存储和安全等功能卸载,在云计算领域得到广泛的应用。今天,浪潮数据云计算网络架构师王培辉带大家了解智能网卡加速原理和以及在浪潮分布式SDN网络加速的应用,深入理解智能网卡加速虚拟化网络的基本原理。本文整理自龙蜥大......
  • ClickHouse创建分布式表1
    clickhouse集群主要有两个作用,一是数据副本,也就是将数据冗余到另外的机器上,用于保证高可用;二是分布表,就是将一个表的数据分散到多个节点上保存,然后再通过Distributed表引擎将数据拼接起来作为一个完整的表使用。创建分布式表:1.查看clickhouse默认的集群配置SELECT*from......
  • ClickHouse创建分布式表
     技术标签: 大数据开发  分布式  数据库  大数据  flink ClickHouse创建分布式表当数据量剧增的时候,clickhouse是采用分片的方式进行数据的存储的,类似于redis集群的实现方式。然后想进行统一的查询的时候,因为涉及到多个本地表,可以通过分布式表的方式来提供统一的......
  • 【分布式技术专题】「架构设计方案」盘点和总结RBAC服务体系的功能设计及注意事项技术
    前言介绍权限管理是后台系统的重要组成部分,主要目的是控制不同人对资源的访问权限,以避免操作错误和隐私数据泄露等风险问题。我在公司负责权限管理,对该领域的设计很熟悉。公司采用微服务架构,因此权限系统独立于其他业务系统,包括商品中心、订单中心、用户中心、仓库系统、小程序和多......
  • 分布式事务两阶段提交和三阶段提交有什么区别?
    在分布式事务中,通常使用两阶段协议或三阶段协议来保障分布式事务的正常运行,它也是X/Open公司定义的一套分布式事务标准。X/Open公司是由多家国际计算机厂商所组成的联盟组织,它建立之初是为了向UNIX环境提供标准。分布式事务是指在分布式系统中,多个节点之间进行的事务操作......