1.1【业务背景】
你作为一个电商创业公司的架构师,负责设计 6.18 大促秒杀系统的设计,你们的业务模式如下:
你们挑选各大电商平台上畅销和好评的商品进行销售,每个品类不超过 20 个商品,目前做了 10 个品类;
本次 6.18 秒杀选择了 1000 个充电宝,10 台 iPhone 12 作为秒杀商品;
正常的日活大约 100 万用户;
老板要求万无一失。
1.2【技术背景】
技术团队以 Java 为主,已经落地了微服务架构;
主要渠道是自有的 App(包括 iOS 和 Android)和微信小程序,为了促进用户转化为 App 用户,只有下载 App 才能参加秒杀活动;
目前只有单机房。
1.只有下载 App 才能参加秒杀活动。
2.秒杀页面对畅销和好评的商品进行推荐销售。
3.订单需 30 分钟内支付。
4.支付依赖第三方支付平台。
2.1.独立部署
避免对其他业务产生影响,秒杀系统和 Redis 集群独立部署,使用独立的域名。
2.2.减少到后端服务器的请求数
系统做动静分离,静态资源上传到 CDN。
利用 APP 缓冲。
2.3.流量消峰
秒杀时通过答题,防止秒杀器和延长用户提交请求的时间。
2.4.限流
APP 端随机丢弃部分请求,只有 20%请求进入后端服务。
如用户秒杀成功,APP 端将不可再参与秒杀活动。
后端服务随机丢弃部分请求,只有 20%请求最后能访问 redis 集群中的库存数据进行秒杀,可在后端系统配置请求通过率并实时生效。
2.5.库存减扣
秒杀商品件数缓存到 redis 集群中,每一种商品都创建一个 list,该商品的秒杀件数有多少,list 中的元素就有多少个,每次下单就从 list 中弹出一个元素,防止超卖。
秒杀成功的用户放入 SET 中,防止多次抢购。
3.1 存储性能估算
下载
iOS 安装包 50M,Android 安装包 60M,APP 安装包已上传 CDN。
注册
因为 6.18 大促的前期宣传,注册数每天增加 3 万,但数据量没有质的飞越,可以忽略不计。
登录
正常日活用户 100 万,6.18 大促登录数据是每天 200 万。
浏览商品
2 件秒杀商品,200 件推荐商品。静态资源需要提前推送 CDN,秒杀商品件数缓存到 redis 集群中。
秒杀
6.18 大促登录数据是每天 200 万,假设有 60%的用户参加秒杀,每个用户参加 2 次秒杀答题,题库数据量为:200 万 * 60% *2 = 240 万。需要题库数缓存到 CDN 中。
充电宝和 iPhone 12 合计 1010 台 ,1010 条下单记录。
支付
支付和订单处理,数据量不大,沿用原有 Mysql 主备。
避免对其他业务产生影响,Redis 集群独立部署。
4.1 计算性能估算
下载
6.18 大促登录数据是每天 200 万,假设有 60%的用户参加秒杀,同时其中 40%用户需要下载 APP,下载多发生在秒杀前 8 小时内。
下载量:200 万 * 60% *40% =48 万。
下载量 QPS:48 万 / (8 * 60 * 60) ≈ 16.8 次/秒
因下载是非核心业务,这里先假设原来的 CDN 可以满足需求。
注册
每日新注册用户不到 3 万,可以忽略。
登录
6.18 大促登录数据是每天 200 万,假设登录时间集中在早晚 4 小时,登录 TPS 均值:200 万 / 14400 = 140。
浏览商品
6.18 大促登录数据是每天 200 万,假设有 60%的用户参加秒杀,秒杀前 5 分钟开始进入商品浏览页面,查看秒杀商品和推荐商品,假设每人查看 10 个商品。
查询数量为:200 万 * 60% *10 = 1200 万查询。
查询 QPS 为: 1200 万 / (5 *60) = 4 万/秒
秒杀
6.18 大促登录数据是每天 200 万,假设有 60%的用户参加秒杀,20%请求进入后端服务,因为有答题,秒杀 2 秒完成,因此秒杀 QPS 均值:200 万 * 60% *20% / 2 = 12 万。
因为后端服务保留 20%的请求,因此访问 redis 集群中秒杀件数的 TPS 均值:12 万 *20% =2.4 万。
1010 条下单记录,2 秒内完成(假设秒杀持续了 2 秒),下单 TPS 均值:1010 /5 =505。
支付
支付预计在 1 分钟内完成,TPS 为:1010 /60 ≈ 16.9 ,可以忽略不计。
4.2 计算架构之负载均衡
5.2 、内部服务间通过消息队列进行调用
为了避免下单、支付等服务产生数据库死锁,给每种商品建立一个消息队列,消峰、解耦的同时避免数据库资源的竞争。