业务需求,秒杀iphone,库存10台,同时参与秒杀人员100w,不讨论前端优化(如产品信息缓存,脚本合并等)
解决方案:
N台前端web服务器,redis服务器1台,数据库服务器1台
主要思路就是使用redis做计数器,简单的实现一个排队的策略,从而避免对数据库的频繁更新。redis通过INCR命令递增,INCR命令本身为原子操作,性能至少在每秒5w以上。
具体策略如下:
每台web服务器上保留计数器的全局变量(c#为静态变量,php保存为apc变量),用户点击秒杀按钮,检查变量是否>10(库存数)
1、如果小于10则去redis中incr,检查返回值是否在库存数以内,
(1)如果小于库存数,修改全局变量。
然后进行数据库操作(一条事务内,减少库存update product set stock=stock-1 where stock>10, 插入用户订单数据,),进入后续付款流程。
(2)如果大于库存数,则不做任何操作,直接返回秒杀结束。
2、如果是大于静态变量,则直接返回秒杀结束。
这样做的好处是实现了简单的排队功能,不符合的用户被筛选,减少数据库更新压力,压力集中在redis中,通过全局变量来减缓redis压力。