上面两篇文章中,介绍过秒杀的设计,其中关于库存扣减这里,我们选择用 lua 脚本实现的高效的库存扣减,于是有人提出了疑问:为啥不用Redis 的分布式锁,而要用 lua 脚本?
为啥不用不用分布式锁?其实答案就是没必要!
我们要实现秒杀的库存扣减,最重要的是两个点:1、抗更高的并发。2、避免超卖 。**尤其重要的就是这个防止超卖,这也是我们加锁的目的。
拿我们常用的 Redisson 分布式锁来说,如果用了 tryLock,不考虑 waitTime的合理性情况下,和 lua 脚本的执行也差不多,就是排队执行。
但是,如果我们用 lua 脚本,可以直接用利用他的原子性特性,在一个脚本中实现库存的检查、扣减等动作。这样才能避免超卖!
如果使用分布式锁,在不使用 lua 脚本的情况下,每次库存扣减操作都需要多次与 Redis 服务器通信(例如,加锁、读取库存、扣减库存、释放锁等)。这不仅增加了网络延时,还增加了系统的复杂性。
而如果使用 Lua 脚本,所有操作可以在一次脚本执行中完成,这大大减少了网络传输时间和通信次数。
那有人说,我先加分布式锁,然后再用 lua 脚本不行吗?这。。。不就是脱裤子放屁吗?直接用 lua 脚本不就好了吗,因为利用 Redis 的单线程机制,Lua 脚本的执行本身就是串行化的。
而且, Lua 脚本是在 Redis 服务器内部执行,它直接操作内存中的数据,执行效率是非常高的。而且使用 Lua 脚本实现的话,我们可以将库存扣减的逻辑集中处理,不需要在应用层做额外的同步处理。这样可以使得应用层的代码更加简洁,易于维护。
而且,用分布式锁需要细致的管理,包括锁的设置、维护锁的存活时间、处理死锁问题等。如果锁没有正确管理,可能会导致死锁或者锁失效,进而影响系统的稳定性和数据一致性。