关于秒杀、抢购等高并发库存量问题
今天看到群里有人在说关于秒杀、抢购等高并发库存量问题,有说用mysql innodb的,有说用队列的等等,基本都是从存储载体上去寻求解答。
我这还有这样一个方向。
首先这类问题的特点是高并发,解决高并发的最有效的是直接读写内存,但是内存又是昂贵的,且数据崩溃难以找回。所以这个方案就是把此类过程分为三步:
- 各客户端在内存中抢号(也就是争抢下单的令牌(权限)。如在内存中incr一个数字id,然后给这个id加签名防止伪造,id+签名唯一。将带签名的id保存到数据库并将其发送给客户端)
- 校验(校验令牌:(1)id签名验证通过 (2)id数字小于初始库存量)
- 下单(到这一步剩下的客户端已经不多了,所以在这里你可以花较长的时间做许多复杂的事情,比如分发cdkey,这里即使让用户等上1分钟都没多大关系)
- 超时(对于超过指定时间未使用的令牌,如何回收?)
这里“初始库存量”是一个常量,始终不变。
2015-09-07=================================================
方案二:
- 根据库存量,离线生成令牌,存于(分布式)数据库
- 把令牌放到内存中发放客户端,已发出的令牌在(分布式)令牌库中标记发放时间和用户,因为令牌码唯一,所以不会造成争锁问题,同时也可以使用延迟写入(此处并发最高,应尽量少做其他事情)
- 使用令牌下单,支付时确保令牌有效,支付后标记令牌已使用
- 离线作业:超时未使用的令牌,清除发放时间和用户,重新放到内存中发放