红色难题里Redis资源冲突咋解决,真是让人头疼的问题
- 问答
- 2025-12-24 09:05:31
- 2
(根据知乎专栏“技术琐话”和多位开发者在社区论坛的讨论整理)
这红色难题里的Redis资源冲突,说白了就是大家伙儿一窝蜂地去抢同一个东西,结果谁都干不好,甚至把东西给弄坏了,想象一下,就像超市大减价,一群人去抢最后一桶油,你推我挤,最后可能油没抢到,人还打起来了,在Redis里,这个“油”可能就是某个关键的数据,比如一个商品的库存数量,或者一个用户的账户余额。
最常见的冲突场景:超卖问题
这个是最经典,也最让人头疼的例子,比如一个热门商品就剩最后1件了,这时候十万个人同时点击“立即购买”,如果没有妥善处理,很可能发生什么呢?系统A查了一下Redis,看到库存是1,心想“有货!”,于是准备下单,可就在它准备把库存减成0的这个瞬间,系统B、系统C……系统Z也都查了库存,它们看到的也都是1,因为它们查询的时候,系统A还没来得及扣减呢,结果就是,这好几十个系统都认为货在自己手里,都成功创建了订单,造成了“超卖”——卖了1件商品,却产生了N个订单,这物流怎么发?客户投诉怎么处理?简直是一场灾难。
解决思路:核心就俩字——“排队”
既然一拥而上会出问题,那最直接的想法就是让大家排好队,一个一个来,在技术世界里,这就是“串行化”处理,怎么实现排队呢?有几种常见的土办法和好办法。

用Redis自己实现一把“锁”(悲观锁)
这是最直观的想法,既然你们要抢,那我就在这个资源(比如那个商品库存)上挂把锁,谁先来,谁就把锁拿走(SETNX命令可以干这个事,意思是“如果这个键不存在就设置它”),拿到锁的人,才有资格去进行接下来的查库存、扣库存操作,其他后来的人,一看锁被别人拿走了,就只能干等着,或者过一会儿再来试试,等第一个操作完成,库存扣减成功,订单生成完毕,他再把锁释放掉(删除那个锁的键),这样第二个排队的人才能拿到锁。
这个方法听起来不错,但坑也不少,万一第一个拿到锁的系统,在操作过程中突然崩溃了,没来得及释放锁,那这个锁就永远挂在那里了,后面所有人都得傻等着,这就是“死锁”,为了解决死锁,通常会给锁设置一个“过期时间”,比如10秒,这样就算第一个人崩溃了,10秒后锁自动释放,队伍还能继续移动,但设置多久的过期时间又是个学问,设短了业务没做完锁就没了,设长了系统崩溃后其他人要等很久。
(来源:Redis官方文档关于SETNX和分布式锁的说明)
利用Redis的“原子操作”特性(乐观锁)

这个方法更巧妙一些,它不强制排队,而是相信冲突不常发生,但会在最后提交修改的那一刻检查一下有没有人“插队”,Redis的命令是单线程执行的,它的某些命令本身是具有原子性的,也就是说,执行过程中不会被其他命令打断。
对于上面的库存问题,我们不一定非要用锁,可以用Redis的DECR命令,这个命令的作用就是将键的值减1,而且这个“读取当前值”和“减去1”是两个动作合在一起的,是一个原子操作,十万人同时发来DECR stock:product_id这个命令,Redis会乖乖地让这些命令排着队一个一个执行,第一个DECR把库存从1减到0,返回0(表示扣减成功);后面所有的DECR命令都是在0的基础上减1,结果变成负数,返回-1,这样,我们在程序里判断,如果返回值大于等于0,才算抢购成功;如果是负数,就告诉用户“库存不足”,这就完美避免了超卖。
不是所有业务逻辑都能用一个简单的DECR搞定,如果操作很复杂,比如要先检查用户积分,再扣库存,再增加用户订单记录,这时候原子命令就不够用了。
(来源:博客园“阿飞的博客”对Redis原子性的详解)
使用Lua脚本

当业务逻辑复杂,不能用一两个原子命令解决,又不想用锁搞得系统很复杂时,Lua脚本就是大救星了,你可以把一整段复杂的业务逻辑(检查库存、检查用户资格、扣库存、记录日志)写成一个Lua脚本,然后一次性提交给Redis执行。
关键点在于:Redis会保证整个Lua脚本的执行是原子性的!脚本在执行时,不会被任何其他命令打断,这就相当于你把一段复杂的插队代码打包成一个“超级原子命令”,这样,即使有十万个请求,它们提交的Lua脚本也会在Redis内部排成队,顺序执行,每个脚本在执行时,它看到的都是前一个脚本执行完后的数据状态,绝对不会出现中间状态被干扰的情况,这相当于把排队的逻辑从你的应用服务器转移到了Redis内部,既简单又高效。
(来源:GitHub上多个开源项目对Redis Lua脚本的应用实践)
总结一下
面对Redis资源冲突这个红色难题,别头疼,解决办法是现成的,关键看你的业务场景:
- 简单增减:直接用Redis的原子命令(INCR, DECR等),最简单高效。
- 复杂逻辑:首选Lua脚本,把一堆操作打包成一个原子任务。
- 万不得已:再考虑用分布式锁(SETNX),但要小心处理过期时间和死锁问题。
这些东西说起来不复杂,但在真正高并发的场景下,每个细节都可能导致严重的生产问题,多测试,理解每种方案的优缺点,才能选出最适合自己业务的那把“钥匙”,解开资源冲突的锁。
本文由盘雅霜于2025-12-24发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:http://waw.haoid.cn/wenda/67456.html
