秒杀系统设计整理

 
 
 
 

一个秒杀系统的设计,涵盖若干要素。比如:

  • 读写请求分离;
  • 流量筛选;
  • 读缓存;
  • 写批量;
  • 写串行;
  • 预处理;
  • 前端界面操作优化;
  • dns优化;
  • 自我保护;

每一个要素,都是解决一个具体的问题场景。

读写请求分离:

秒杀一般分为2个阶段,秒杀准备阶段,秒杀阶段。

在秒杀准备阶段,一般流量会逐渐上升,用户会不断的查询秒杀商品等待开始。

在这个阶段,按资源类型的区别,分为静态资源&动态接口。静态资源提前走cdn部署或者类似小程序这种直接打包在终端本地,可以忽略这部分请求的压力。动态接口需要做好数据的读缓存,有效期可以相对放长一些,可以防止查询流量进入db。

在秒杀阶段,一般写入流量会多于查询流量。

在这个阶段的写请求,一般会经历如下步骤:

  • 秒杀写请求经过限流器,筛除部分重复请求;
  • 对请求进行预处理,检查前置条件,秒杀目标现状等。此时秒杀目标现状数据可以不要求实时精确,拦截掉部分流量即可;
  • 合格的用户请求下,秒杀目标有容量的情况下,筛出来合格的请求进入排队队列,同时,将请求线程挂起等待消费者唤醒,队列消费者进行批量并发的消费,成功则继续循环,不成功则全量返回失败;

读请求,则直接从缓存读即可,少部分mis的再请求db。

流量筛选:

秒杀品一般性价比比较高,容易招来黑产刷单。为了尽量避免被褥羊毛,一般会在网关侧实时清洗流量,比如按IP,uid等维度识别时间跨度内的访问频率,命中规则的放入黑名单直接拒绝流量进入秒杀系统。如果刷单严重,会在秒杀系统中留存账号请求记录,导入实时计算引擎结合风控模型分析后,进一步按用户行为分析筛除羊毛党,一般到这一步基本的羊毛党都能识别出来。

读缓存:

读请求走缓存,一般的问题在于缓存的命中率。比如,秒杀开始前的读请求,查询商品详情的数据需要缓存时间较长,到达秒杀时刻时,要及时更新状态等。这种情况下一般是在缓存数据中存储上了生效时间,代码中只是在获取到后进行一次判断。

在写请求成功后,一般要更新缓存的数据。在并发密集的情况下,一般走异步队列批量进行。缩减主流程涉及环节。

写批量:

在合适的写请求进入队列后,为了提升消费者的处理效率,可以看条件批量提取数据,提升消费者的处理能力。比如抢券场景下,产品可能设计成用户可以多次领取多张,多种券,大部分用户的领券,动作、时机、内容高度相似,完全具备整合批量执行的能力。这种情况下,消费端批量消费写请求,可以降低对DB的压力,减少请求的等待时间,提升QPS。

一种实现方案如下图所示:

写串行:

针对热点key的写操作,是多个实例下多个线程竞争一个行锁。此时系统竞争的激烈程度与性能是成反比的。为了降低这种无意义的损耗,可以基于热点key做本地锁。限制一个实例同一时刻仅有一个线程可以参与去竞争行锁,其余的全部返还失败。即实例级别串行执行。

预处理:

在前端业务系统调用写操作API前,可以再进行一次预检查,尽量提前发现不满足条件的写请求,避免将压力传导到下层环节。

前端界面优化:

这部分优化得看产品设计。有些秒杀品仅允许购买一次,但是有些允许购买多次。限制条件往往丰富且多维。比如:最近购买次数少于2次;最多允许购买2份等。这种情况下的秒杀,前端界面只能跟随后端的逻辑来判断是否允许按钮点击与否。后端可以通过redis的bitmap,以商品维度打标进行维护,这个数据不保证精确性,仅维持大部分情况下正确(即可以不考虑分布式一致性,基本正确就可以),能筛掉冗余流量就达到目的。简单起见,秒杀品只能下单一次,提交订单后,前端页面自行按钮置灰。如果提交失败,可以通过刷新页面重新获取后端的判断,然后再根据这个判断控制显示。

dns优化:

dns是为了寻找域名对应真实ip用的,一般业务域名为了防攻击会经过一层高防,然后再由高防转slb进行流量分发。高防的成本相对较高,可以尝试结合客户端本地dns,走httpdns的模式,后端聚合若干个小容量的slb进行流量的客户端负载均衡,可以在一定程度上避免高防成本过快增长。

自我保护:

系统必须能支持幂等逻辑。不能因为高频并发产生超卖,超发的情况。比如多个同样的请求一起发起,不能成功多次,只能允许成功一个。这种情况下,可以分几个阶段来做处理。第一个阶段,通过在redis中记录成功数量拦截掉持续不断的冗余流量;第二阶段,通过数据库层面的一致性,确保逻辑幂等。数据库幂等,一般的方式是依赖数据库的唯一键来做。但是,单纯的依赖数据库的唯一键,容易产生数据库死锁,同时,还存在对于数据库锁的竞争。为了优化这个问题,可以依赖redis做分布式锁逻辑,将数据库记录的唯一索引,转换成redis的key值进行处理。

 

一个典型的处理过程如下图所示:

 

参考资料:

https://www.6aiq.com/article/1564638780024?p=1&m=0

https://juejin.im/post/6844904000337379341

posted @ 2020-07-14 14:35  飞昂之雪  阅读(205)  评论(0编辑  收藏  举报