7. 100万张代金券,要把代金券发给上亿的用户,你会怎么设计这个系统?
其实就是一个库存扣减的问题,如果是为了保证库存扣减的准确性,我们设计的一个链路最好不要太长和复杂。同时也不考虑把库存放在redis里,因为redis中的异步复制和持久化机制可能会导致数据不一致的问题。所以我想的是直接操作数据库进行扣减,然后引入一个消息队列作为一个削峰的作用避免数据的访问量过高。引入消息队列的话就还需要考虑到一个消费的幂等性处理。所以整个链路应该就是用户点击领取代金卷的时候,先把用户id投递到消息队列中,然后我们后端服务器执行一个消费,消费逻辑就是开启一个数据库事务(先尝试在一张用户表中插入一条整个用户的记录——利用用户id是唯一键的特性,如果插入成功了再执行扣减库存的操作),事务提交成功了再响应用户。
缺点:整个系统处理高并发请求的时候响应会比较慢。优点:保证了库存扣减的强一致性。
其实整个取舍就是CAP理论中的C和A的取舍吧.