search

Home  >  Q&A  >  body text

php - 并发问题 1000并发、3个奖品,如何保证秒杀稳定进行?

1000并发 3个奖品 保证秒杀稳定进行,并且中奖者和奖品数量不要出问题
这个问题怎么处理 ,mysql的 希望各位有经验的同学分享下经验以及解决方案,谢谢,在先等

阿神阿神2896 days ago692

reply all(10)I'll reply

  • 怪我咯

    怪我咯2017-04-10 17:33:23

    Redis 队列
    Redis 可以应对高并发场景,是因为它的读写请求均是单线程机制,不存在并发问题。而且 Redis 是基于内存的,读写速度也比 MySQL 快得多

    reply
    0
  • PHPz

    PHPz2017-04-10 17:33:23

    因为奖品只有三个,所以无论多少个请求过来,最多只能有三个请求可以正确获得奖品,所以可以将大部分的请求不做任何处理,直接返回秒杀失败,剩下很小的请求进入到下环节,此时并发很小,所以接下来的处理几乎可以不再考虑并发问题。
    当然此方案仅因为奖品数很少,如果奖品本身很多,即使抛弃大部分的请求,系统也承受较大并发冲击,此时需要考虑其它方案。

    reply
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-10 17:33:23

    看你描述你的秒杀场景感觉比我们的稍微简单一些,如果不考虑非常严谨的扩展性,只考虑当下,我感居然可以如下方式简单实现:

    假设你优化下mysql或升级下硬件,1000并发全部查询mysql数据库是否还有库存,可以顶得住的话,那么只需要一个队列服务,把所有并发秒杀用户全部进入到队列逐条同步筛选出3个中奖用户,然后在生成订单的时候扣掉mysql里面的库存,并且响应给前端页面检测是否秒杀成功的进程即可,其他的997个用户全部响应给前端进程秒杀失败提醒

    假设顶不住或者没钱升级?那就用redis之类的服务把1000个奖品信息存入缓存,秒杀成功生成订单的时候同步更新mysql和redis里面的库存数量

    reply
    0
  • 高洛峰

    高洛峰2017-04-10 17:33:23

    请用缓存把奖品全部加入到里面。然后全部从缓存里秒,秒到了才更新数据库

    reply
    0
  • 天蓬老师

    天蓬老师2017-04-10 17:33:23

    因为题主声明了只使用MySQL,我认为可以这样做:

    1.将3个奖品放入一张表中;
    2.到点后系统进入高并发状态,然后你们的奖品随机算法使用户中奖并删除记录;
    3.检测表中是否还有数据;

    也可以这样:

    1.建立一张中奖专用计数表;
    2.到点后系统进入高并发状态,然后你们的奖品随机算法使用户中奖并增加计数;

    至于优化方案(暂时能想到的,希望大神补充):

    1.存储引擎使用 MEMORY
    2.可以在程序入口处设置一个过期时间,3个奖品的话,10秒钟足够了,过期后入口关闭或跳转;

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-10 17:33:23

    最简单的方法是把1000并发用队列拉成线性的就行了,当某个请求发现库存没了,以后的所有请求全部返回秒杀失败。

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-10 17:33:23

    才1000的并发/数据,为啥要用数据库。数据库的速度还是很慢很慢的。
    服务器直接为每个请求保存一个时间戳,然后排序就好了。反正用户1-2秒之后获得结果也不会有什么特别的感觉。

    reply
    0
  • 阿神

    阿神2017-04-10 17:33:23

    将请求保存到队列,只取队列的前三个值,后面的全部返回已售完。

    reply
    0
  • 大家讲道理

    大家讲道理2017-04-10 17:33:23

    需要一个队列服务,把所有的并发秒杀用户,全部进入到队列逐条同步筛选出3个中奖用户,然后在生成订单的时候扣掉mysql里面的库存,并且响应给前端页面检测是否秒杀成功的进程即可,其他的997个用户全部响应给前端进程秒杀失败提醒

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 17:33:23

    用 mysql 内存表。先用 hash user_id等方法随机丢掉一部分请求

    然后直接 update 内存表,例:

    ``
    update award set user_id=xxx where id=1 and user_id=0
    ``

    reply
    0
  • Cancelreply