难题,至少对于很多人来说是一个难题,不过实际上这是一个送分题。
你几乎可以预料到但凡是讨论交易流程,那么超卖就是一个大概率要问到的问题。回答这个问题,你要记得总结出来一个规律:绝大多数情况下,所有的超卖问题几乎都依赖于数据库维护正确的库存信息,Redis 只是用作一个缓存,是一个可以容忍短时间不一致的东西。
先参考:如何设计一个秒杀系统? - 面试ICU (mianshi.icu)
秒杀系统,或者说电商系统中,保证不超卖的秘诀就一个:库存信息以数据库为准。从原理上来说,微服务架构下的电商系统,都是采用锁定-释放库存模型。
因此在秒杀架构中,消费者在消费的时候,先在库存服务中锁定库存。其基本操作可以看做是一个本地事务:
这种机制可以看做是一个兜底,也就是不管前面的步骤如何重试、补偿,最终数据库的库存肯定是准确的。
比如说,一种典型的失败场景就是在在扣减 Redis 成功之后,发送消息到 Kafka 收到超时响应,但是实际上 Kafka 收到了消息。假设说,Redis 中原本有库存 100,MySQL 中也有 100。
而后扣减库存成功,Redis 变成了 99,但是发消息到 Kafka 上超时,不过 Kafka 实际上收到了消息。于是消费者会锁定库存,那么 MySQL 中库存会变成 99。
发消息到 Kafka 上失败引发数据库兜底案例
Redis预扣成功但是发消息失败的部分失败场景;其余部分失败场景;