秒杀实践

本文介绍秒杀系统的优化方法,包括使用varnish、ehcache及memcached等缓存技术减轻数据库压力,采用Redis队列限制秒杀请求,以及利用异步消息提高系统性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

秒杀业务的特点:

  1. 瞬时流量大
  2. 参与用户多,可秒杀商品数量少
  3. 请求读多写少
  4. 秒杀状态转换实时性要求高

秒杀分为三个阶段:

  • 活动未开始
    仅有两种请求,一是加载活动页信息,二是查询活动状态得到未开始结果。两种请求各占一半。
  • 活动进行中
    持续非常短,用户大量发起秒杀请求,瞬时秒杀请求占比增高,能不能抗住秒杀请求就是秒杀系统是否能抗住高并发的关键。
  • 活动结束
    进入结束状态,请求情况同活动开始前。
加载活动页请求

相对静态的内容,通过varnish反向代理,以页面相关参数比如秒杀活动ID和城市ID的hash作为key,把页面缓存在varnish机器上,而秒杀活动的状态等动态信息通过ajax刷新。
达到的效果是活动期间,加载页面请求都会打到varnish机器直接返回,而不会给web和service带来任何压力。
注:Varnish是一款高性能、开源的反向代理服务器和缓存服务器

查询活动状态

秒杀状态有三种:未开始、可抢、已抢完,由两个共同因素决定:①活动开始时间 ②剩余库存

1、读取秒杀状态请求并发非常高,可以加上合适的缓存来处理。对于活动开始时间是一个较固定且不会发生变化的属性,并且同时在线的秒杀活动数目不多,可以选择用响应快的ehcache来缓存。对于库存个数,需要做到全局一致,可以用memcached来缓存。库存个数的缓存没有意义,可以缓存true or false能不能抢,仅需改变一次。
因为秒杀期间查询活动状态的请求都打在memcached上,减少写的频率可以明显减轻memcached的负担。

秒杀请求分析

写请求,不能缓存。
需要两个步骤:1、扣库存;2、反馈是否秒杀成功。
秒杀业务的一个特点是参与人数多,但是可供秒杀的商品少,也就是说只有极少部分的用户最终能够秒杀成功,让过多的sql来竞争是没有意义的,所以要限制这些参与到扣库存这一步的人数。

秒杀队列校验

可抢状态需要第三个因素决定,就是当前秒杀的排队人数。加在判断库存剩余之前,加上一层排队人数的校验, 即有库存 并且 排队人数 < 限制请求数 = 可抢,有库存 并且 排队人数 >= 限制请求数 = 抢完
流程
发起秒杀先去问排队队列是不是已满,满了直接秒杀失败,同时可以去更新之前缓存了是否可抢 true or false的缓存,直接把前台可抢的状态变为不可抢。没满继续查询库存等后续流程,开始扣库存的时候,把当前用户id入队。 这样,就限制了真正进入秒杀的人数。
重复提交
如果重复提交的量大,比如放过去的请求中有一半都是重复提交,就会造成最后没秒完的情况,怎么屏蔽重复用户呢? 就要有个地方来记参与的用户id,可以使用redis的set结构来保存,这个时候set的size代表当前排队的用户数,扣库存之前add当前用户id到set,根据add是否成功的结果,来判断是否继续处理请求。

更多的优化
1、分表。首先将库存数放到redis上,再分表,增加并发。
2、异步消息。可以将扣库存和反馈秒杀失败,改为异步。通过消息队列实现。

总结:
先用varnish挡掉了所有的读取状态请求 然后用ehcache缓存活动时间,挡掉活动未开始时查询活动状态的请求 memcached缓存是否可抢的状态,挡掉活动开始后到结束状态的活动查询请求 redis队列挡掉了活动进行中,过量的秒杀请求 到最后只留下了秒杀商品数量级的请求到数据库中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值