Redis分布式锁讲解 (redis分布式锁)

教程大全 2025-07-21 08:25:07 浏览

日常开发中,秒杀下单、抢红包等等业务场景,都需要用到分布式锁。而Redis非常适合作为分布式锁使用。

分布式锁是”线程同步”的延续

最近首度应用”分布式锁”,现在想想,分布式锁不是孤立的技能点,这其实就是跨主机的线程同步。

单机 服务器 可以通过共享某堆内存来标记上锁/解锁,线程同步说到底是建立在单机操作系统的用户态/内核态对共享内存的访问控制。

而分布式服务器不是在同一台机器上:跨主机,因此需要将锁标记存储在所有机器进程都能看到的地方。

在开发很多业务场景会使用到锁,例如库存控制,抽奖等。

例如库存只剩1个商品,有三个用户同时打算购买,谁先购买库存立即清零,不能让其他二人也购买成功。

我们常说的线程安全、线程同步方案,包括此次的分布式锁都是基于

“多线程/多进程对特定资源同时有更新操作”。

Redis SET resource-name anystring NX EX max-lock-time

是一种最简单的分布式锁实现方案。

SET 命令支持多个参数:

因为SET命令参数可以替代SETNX,SETEX,GETSET,这些命令在未来可能被废弃。

上面的命令返回OK(或经过重试),客户端就获取到这个锁;

使用DEL命令解锁;到达超时时间会自动释放锁。

在解锁时,增加一些设计,让系统更加健壮:

3.不要使用固定的String值作为锁标记值,而是使用一个不易被猜中的随机值, 业内称为token

4.不使用DEL命令释放锁,而是发送script去移除key

第3、4点是为了解决 :“锁提前过期,客户端A还没有执行完,然后客户端B获取了锁,这时客户端A执行完了,会不会在删锁的时候把B的锁给删掉” — 4是3技术上的推荐实现。

脚本如下:

redis.call(,KEYS1]==ARGV[1])redis.call(,KEYS[1])0end

下面使用StackExchange.Redis 写了基于以上考量的代码示例:

//////Acquiresthelock./////////随机值//////非阻塞锁staticboolLock(stringkey,stringtoken,intexpireSecond=10,doublewaitLockSeconds=0){varwaitIntervalMs=50;boolisLock;DateTimebegin=DateTime.Now;{isLock=Connection.GetDatabase().StringSet(key,token,TimeSpan.FromSeconds(expireSecond),When.NotExists);(isLock);//不等待锁则返回(waitLockSeconds==0);//超过等待时间,则不再等待((DateTime.Now-begin).TotalSeconds>=waitLockSeconds);Thread.Sleep(waitIntervalMs);}(!isLock);;}//////Releasesthelock.//////,lockwasreleased,otherwise.///Key.///valuestaticboolUnLock(stringkey,stringvalue){stringlua_script=@;try{varres=Connection.GetDatabase().ScriptEvaluate(lua_script,newRedisKey[]{key},newRedisValue[]{value});(bool)res;}catch(Exceptionex){Console.WriteLine($);;}}privatestaticLazylazyConnection=newLazy(()=>{ConfigurationOptionsconfiguration=newConfigurationOptions{AbortOnConnectFail=,ConnectTimeout=5000,};configuration.EndPoints.Add(,6379);ConnectionMultiplEXEr.Connect(configuration.ToString());});publicstaticConnectionMultiplexerConnection=>lazyConnection.Value;

以上代码新增了第五点考量:

\5. 为避免无限制抢锁,增加了非阻塞锁:轮询_s等待锁,未等到则不再抢锁

下面并行开启三个任务,同时减少库存:

staticvoidMain(string[]args){//尝试并行执行3个任务Parallel.For(0,3,x=>{stringtoken=$;boolisLocked=Lock(,token,5,10);(isLocked){Console.WriteLine($);Thread.Sleep(1000);Console.WriteLine($loki);}{Console.WriteLine($);}});}

可以看到三个并行任务依次获取/释放锁

Redis分布式锁讲解

本文从基础的线程安全、线程同步,认识到分布式锁是跨主机的资源线程/进程同步方案, 以步步为营的风格 演示了RedisSET命令做分布式锁的设计考量,好记性不如烂笔头。


伤仲永 然 一词多义辨析

重点词语:利:认为…有利可图奇:对…感到惊奇宾客:以宾客之礼相待的意思通假字:通“攀”牵,引◆学习重点: 1.最后一段的议论讲了什么道理? 答:说明了人的天资与后天学习的关系,强调后天学习对成才的重要性. 2.方仲永由天资过人变得泯然众人,原因是什么? 答:从方仲永个人情况来看,原因是父利其然也,日扳仲永环谒于邑人,贪图小利,目光短浅,而不使学.从道理上来说,原因是作者在后面的议论中所认为的那样.方仲永卒之为众人,是因为其受于人者不至,既没有受到后天正常的教育. 3.你对题目是怎样理解的? 答:伤是哀伤感伤之意.仲永,即方仲永,本文的一个神童.文章以伤仲永为题,写的是可伤之事,说的是可伤之道理.字里行间流露出作者对一个神童最终泯然众人的惋惜之情.本文借事说理,以方仲永为实例,说明一个人有天分不足诗,唯有后天的教育与学习,才能让人精益求精,更上一层楼,才能够真正成才. 4.你怎样理解文中的泯然众人矣? 答:泯然众人矣一句点明结局,痛惜之意溢于言表,发人深省.再过七年以后,是方仲永的第三个阶段,才能衰竭,成为了普通人. 5.作者主要表达的意思是什么? 答:本文通过叙述方仲永因为父亲不使学,而从神童到成为普通人的变化过程,说明天资固然重要,但没有好的后天的教育,再好的天赋也不可能得以发挥.告诉我们学习和教育对于人才的培养十分重要!

《极灵混沌决》的内容大致讲的是什么?

机灵混沌决等级划分是武徒、武者、武师、大武师、武灵、武王、武宗、武皇、武尊、武圣、武帝,武圣与武帝之间有个半帝之境称之为圣帝。 1. 机灵混沌决是一本修真小说,讲述了自幼痛失右臂,丹田破碎,万念俱灰的少年破碎极武,铸就巅峰武神路。 2. 斗破苍穹、混沌天体、修罗武神、星武神诀等都属于废柴流的小说。

已知a>0,a不等于1,解关于x的不等式:1+log2(a^x-1)≤log4(4-a^x)

1+log2(a^x-1)≤log4(4-a^x) =log2 2(a^x-1)≤log2 √(4-a^x) 2(a^x-1)≤√(4-a^x) 4(a^2x-2a^x+1)≤4-a^x 4a^2x-7a^x≤0 a^x(4a^x-7)≤0 0≤a^x≤7/4 由定义域知,a^x-1>0,1 1时,0

本文版权声明本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请联系本站客服,一经查实,本站将立刻删除。

发表评论

热门推荐