秒杀程序数据库设计

        上个月有幸去腾讯逛了一圈,面试一个职位,虽然没被录取但是过程总体来讲还是愉快的。面试过程中面试我的小朋友(看年龄大概在26,7岁)问了我一个关于秒杀的问题,他说腾讯游戏经常会有秒杀的活动,很多次会导致服务器死锁或压力太大,应该如何设计减轻数据库服务器压力。当然因为面试的是PHP职位,我做的是C#和JAVA我知道应该没机会所以本不想太过“配合”的回答,但是看面试我的小朋友看我好像很不削的样子(可能因为面试的是PHP职位而且一上来就让我做题目,虽然我有点不情愿做题但是毕竟是腾讯还是做了但是PHP接触的真的不多所以题目几乎是连蒙带猜的完成的,估计不是很好看),所以还是认真想了想解决方案。

        秒杀说到底就是瞬间大规模访问,导致的压力,前端我们可以使用集群技术,数据库呢?拆表?是个方法,但是如果只是简单拆表仍然会有问题,毕竟秒杀商品被记录到表中后用户秒杀必定是需要通过修改表中已有的秒杀商品记录来确定这个商品是否已经被秒走。为了防止抢到同一条记录加锁是必须。而数据库一锁性能问题就来了。那怎么办呢?我想了一个方法(至少有一点可以确定腾讯游戏没有用这个方法解决),秒杀时并不是立刻去修改数据库中记录(进行update操作),而是先向一张表中插入一条记录,类似进入等待队列,为了防止大规模插入操作导致锁表我们可以将队列表拆成多张相同结构表。有一个job会不断读取这些队列表并按照插入时间排列计算那些记录被秒杀成功。而客户端在点击秒杀按钮后断开连接,几秒后再次通过查询语句来查询结果,并返回给前台客户。

         这样做的好处秒杀过程是分段的,前台用户在秒杀时仅是向(多张队列表中)某一张队列表中插入一条记录,之后便断开本次连接进入等待,job程序通过合并查询将多张秒杀表合并按插入时间排序,按规则得出秒杀成功的用户并修改秒杀商品表,表明此商品已被秒杀,前台程序在等待几秒后查询秒杀商品表获得自己是否已秒杀成功。

         因为第一步仅仅是插入操作,无需担心同步操作带来的脏数据问题,所以我们可以通过拆表来分散压力降低隔离等级。更新操作是有一个单独的job程序完成的,因为只有一个程序会去改记录所以就不存在锁表问题。最后前台通过查询语句来获取结果,因为查询商品秒杀结果也不需要任何的顺序只需要知道是不是你自己抢到的就好,所以可以使用with(nolock)一类的忽略锁机制来执行。

秒杀 程序 设计
您的回应...

相关话题

查看全部

也许你感兴趣

换一批

热门标签

更多