写点什么

电商秒杀系统设计

作者:intelamd
  • 2022 年 8 月 20 日
    浙江
  • 本文字数:1986 字

    阅读完需:约 7 分钟

整体分析及假设


存储架构设计

存储性能估算


存储架构设计之数据库


容量方面考虑,秒杀系统对存储系统的容量要求并不高,用户数据是存储在用户服务的 DB 中的,而实际要存储在秒杀系统中的主要有以下数据:

  1. 活动商品及库存:预计百至千级

  2. 秒杀订单:秒杀属于特惠商品,一般备货不多,预估未来三年至多百万级

  3. 支付单:支付是共享原商城的支付系统,故此处不用考虑

可以看出对数据容量要求不高,无需分片架构

吞吐量方面考虑,秒杀虽然是要求高并发的,但是通过多级缓存系统,实际到达数据库层的流量只有很少一部分,按照目前的情况(支持 1000 个充电宝),要求数据库提供 1000 左右的 TPS,单机是可以支持的。

高可用方面考虑,因为要求较高的可用性,MySQL 的主备架构无法故障自动转移,秒杀时如果遇到问题则秒杀活动会整体失败,所以需要通过故障转移来保障秒杀继续进行,这里选用了 MHA 方案来实现,方案见上图所示。


存储架构设计之缓存


根据设计,redis 中主要存放:

  1. 秒杀开始标记:用于供前端查询是否开始

  2. 可用库存数量:存储库存总数,已秒杀数,用于拦截大部分的秒杀下单流量

  3. 商品信息:用于 CDN 回源或者其他需要查询商品信息的情况

以上信息存储量要求不高,而对并发(读)、可用性要求较高。

所以通过读写分离架构来实现高并发、通过哨兵架构来实现高可用,方案如上图所示。


计算架构设计

计算性能估算


计算架构之负载均衡

负载均衡架构则保持原有系统的方案即可。

  • 入口使用 DNS 做第一层的负载均衡,如果有条件考虑 HTTP DNS;

  • 一般百万级系统架构中采用 LVS 做四层转发,Nginx 做七层转发;

  • 服务集群则采用多实例部署。

计算架构之多级缓存架构

根据之前分析,商品详情页将承载千万级的请求,而下单接口(立即抢购按钮)也将承载 23w QPS,这两个场景必须要合理的使用多级缓存架构来过滤流量。

针对以上分析,本次方案采用如下多级缓存方案:

  1. 秒杀的商品数据一般在秒杀前不会发生变化,所以 App 端会对秒杀商品数据进行客户端缓存,减少反复刷新带来无效请求;

  2. 商品详情页进行静态化处理,然后预热在 CDN 上,这样大部分刷新流量就会由 CDN 来承接;

  3. 商品详情页中的大部分数据、页面都可以通过前端或者 CDN 进行缓存,但是秒杀开始时间考虑到客户端时间校准的问题,所以需要从后端接口获取。此处采用的办法是 Redis 存储秒杀开始时间,服务端接口从缓存中获取后返回剩余时间。而客户端并非每次刷新页面都请求后端活动开始时间,可以定义两次请求间隔,未到间隔则不向服务端发送请求;

  4. 商品数据、库存数据则会缓存在分布式缓存 Redis 中,存储的结构是 itemId:{itemInfo,total,sold},itemInfo 存储的是商品信息,total 存储的是总库存数量,sold 存储的是已卖出数量。点击抢购按钮的瞬间后端接口会先查询 redis 中的库存是否足够,total-sold>0 则执行 sold 的扣减操作。这样大部分操作都会被挡在库存查询这一步遍返回,只有 1000+(本次案例)的请求会通过然后执行数据库的真正库存扣减及下单操作。因为时序问题会超过 1010 个(充电宝数)请求穿透到数据库,但是并不会太多,对数据库的压力并不会太大;

其他架构设计

高可用设计-同城双活


为了实现万无一失,我们采用同城双活方案来达到机房级的可用性,考虑点如下:

  1. 异地多活复杂度太高,需要的基础设施及业务改造较多,为了此次秒杀活动而建设异地多活架构收益成本比不高;

  2. 秒杀系统的时效性要求较高,如果做机房或者地域级的冷备方案,一旦发生故障,恢复时间较长,会直接导致本次秒杀活动的失败;

  3. 同城多活机房间的延迟基本可以忽略,机房间的服务调用可以近似视为同 IDC 内调用,所以系统适配改动较小,收益成本比较高;

  4. 对本次活动的要求是万无一失,所以为了防止机房级故障导致失败,还是需要采用多活方案来提高可用性;

  5. 秒杀活动读多写少,更适合同城双活。

所以综上所述,本次方案选用了同城多活的架构设计。


下面对同城多活的方案进行简单阐述:

  1. 在同一地域选择两个机房:可用区 1 和可用区 2,采用相同的资源配置,部署同一套系统;

  2. 流量由 DNS 进行平均分配至两个机房的入口网关;

  3. 可用区 1 可以进行任何的读写操作;

  4. 可用区 2 可以进行所有的读操作,所有的写操作则会指向可用区 1;

  5. 可用区 1 的数据库是主库,会通过复制操作复制到可用区 2 的从库中;

  6. Redis 本身采用读写分离架构,写请求发往主库,读请求发往其中一个只读库。

可扩展架构设计-微服务拆分


可扩展设计中,我们将秒杀服务独立出来,作为一个单独的服务,独享 DB 及缓存,主要是从以下几个方面考虑:

  1. 故障隔离:秒杀业务开展期间,压力较大,独立单独的服务及资源可以最大化的避免影响原有的业务,保障原有业务的稳定运行;

  2. 伸缩高效:秒杀业务活动期间瞬时流量大,而活动结束后则流量非常小,所以单独的的服务和资源方便弹性扩充和收缩,资源利用率更高;

  3. 方便业务扩展:秒杀业务相对独立,单独的服务可以保障更方便进行业务扩展升级

当然,秒杀业务只是使用独立的服务、DB、Cache 等资源,而对于服务治理等基础设施还是和商城其他服务共享的。

发布于: 刚刚阅读数: 3
用户头像

intelamd

关注

还未添加个人签名 2018.06.25 加入

还未添加个人简介

评论

发布
暂无评论
电商秒杀系统设计_intelamd_InfoQ写作社区