✅为什么不用分布式锁来实现秒杀?

典型回答

✅让你设计一个秒杀系统,你会考虑哪些问题?

✅库存扣减如何避免超卖和少卖?

上面两篇文章中,介绍过秒杀的设计,其中关于库存扣减这里,我们选择用 lua 脚本实现的高效的库存扣减,于是有人提出了疑问:为啥不用Redis 的分布式锁,而要用 lua 脚本?


为啥不用不用分布式锁?其实答案就是没必要!

我们要实现秒杀的库存扣减,最重要的是两个点:1、抗更高的并发。2、避免超卖 。**尤其重要的就是这个防止超卖,这也是我们加锁的目的。

拿我们常用的 Redisson 分布式锁来说,如果用了 tryLock,不考虑 waitTime的合理性情况下,和 lua 脚本的执行也差不多,就是排队执行。

但是,如果我们用 lua 脚本,可以直接用利用他的原子性特性,在一个脚本中实现库存的检查、扣减等动作。这样才能避免超卖!

如果使用分布式锁,在不使用 lua 脚本的情况下,每次库存扣减操作都需要多次与 Redis 服务器通信(例如,加锁、读取库存、扣减库存、释放锁等)。这不仅增加了网络延时,还增加了系统的复杂性。

而如果使用 Lua 脚本,所有操作可以在一次脚本执行中完成,这大大减少了网络传输时间和通信次数。

那有人说,我先加分布式锁,然后再用 lua 脚本不行吗?这。。。不就是脱裤子放屁吗?直接用 lua 脚本不就好了吗,因为利用 Redis 的单线程机制,Lua 脚本的执行本身就是串行化的。

✅为什么Lua脚本可以保证原子性?

而且, Lua 脚本是在 Redis 服务器内部执行,它直接操作内存中的数据,执行效率是非常高的。而且使用 Lua 脚本实现的话,我们可以将库存扣减的逻辑集中处理,不需要在应用层做额外的同步处理。这样可以使得应用层的代码更加简洁,易于维护。

而且,用分布式锁需要细致的管理,包括锁的设置、维护锁的存活时间、处理死锁问题等。如果锁没有正确管理,可能会导致死锁或者锁失效,进而影响系统的稳定性和数据一致性。

扩展知识

lua和事务的区别

✅Redis的事务和Lua之间有哪些区别?

原文: https://www.yuque.com/hollis666/xkm7k3/arab9x0v5n8mfm9y