模块九作业
设计电商秒杀系统
【业务背景】
你作为一个电商创业公司的架构师,负责设计 6.18 大促秒杀系统的设计,你们的业务模式如下:
1. 你们挑选选品各大电商平台上畅销和好评的商品进行销售,每个品类不超过 20 个商品,目前做了 10 个品类;
2. 本次 6.18 秒杀选择了 1000 个充电宝,10 台 iPhone 12 作为秒杀商品;
3. 正常的日活大约 100 万用户;
4. 老板要求万无一失。
【技术背景】
1. 技术团队以 Java 为主,已经落地了微服务架构;
2. 主要渠道是自有的 App(包括 iOS 和 Android)和微信小程序,为了促进用户转化为 App 用户,只有下载 App 才能参加秒杀活动;
3. 目前只有单机房。
【毕设要求】
1. 设计完整的架构,例如存储、负载均衡、缓存、高可用、可扩展等;
2. 大约 10 页以内的 PPT,每页 PPT 说明一项设计,包括架构设计和设计理由,无需详细解释备选方案。
【提示】
1. 分析考虑要全面,但并不意味着架构设计要面面俱到,如果分析后认为某些设计点可以不做,就在作业最后统一说明原因即可;
2. 如果没有思路,请对照模块 9 的 IM 案例;
3. 如果有的信息觉得不够全或者不够细,可以做出一定的假设,但不能天马行空,需要对照已有的业务背景和技术背景进行合理推断。
用户量预估
日活约 100 万用户
用户行为建模
【登录】
由于 APP 使用 token 进行认证,假设每个用户每天都要打开一次 APP,而 token 的过期时间为 7 天,登录的次数就是 100 万 / 7 ≈ 15 万,考虑到购物一般是在晚上 18-22 点,因此登录 TPS 要求为:15 万/(4 * 3600) ≈ 10/s。
登录会产生一条登录记录,因此每天有 15 万条登录记录要存储,登录记录保存 6 个月,总的数据条数为:15 万 * 6 * 30 ≈ 3000 万条,每条记录包含用户 ID(4 字节)、登录时间(4 字节)、登录 IP(4 字节),存储总大小为 3000 万条 * 12 ≈ 360M。
【购物】
销售 10 个品类,每个品类不超过 20 个商品,一共 200 种商品,假设每个商品的库存为 1 万,再加上秒杀的 2 种商品,商品的种类就是 200+2 = 202,假设商品的介绍平均大小为 1M,存储大小为 202*1M ≈ 200M,商品的数量就是 200*1 万+1000+10 ≈ 200 万条,假设每个商品都能卖出去,每条购买记录 1K,则存储总大小为 200 万条*1K= 2G。
考虑到购物一般是在晚上 18-22 点,假设每个用户购买 1 件商品,因此购物 TPS 要求为:100 万/(4 * 3600) ≈ 70/s。
假设没有进行商品预热的用户,是不能参与秒杀的,而且仅有 1%的用户参与秒杀活动,因此秒杀 TPS 要求为:1 万/s。
性能需求估算
【登录】
登录 TPS:10/s,可以忽略不计;
登录记录:数据 3000 万条,存储 360M;
【购物】
购物 TPS:70/s;
秒杀 TPS:10000/s;
购买记录:数据 200 万条,存储 2G;
存储
秒杀的商品的数量需提前缓存到 redis 中。
负载均衡
用户量百万,应该要用多级负载均衡架构,覆盖 DNS -> Nginx -> 网关的多级负载均衡。
秒杀是一个典型的写操作,可以用负载均衡。
缓存
秒杀商品的数量提前缓存到 redis 中,通过缓存来避免对数据库的冲击。
高可用
APP 端发起秒杀后,随机延迟 0-10 秒,并禁止重提,请求到服务器的 TPS 降为 10000/s,在服务网关上,针对单个商品 TPS 超过 1000(只有 1000 个充电宝)后的请求直接拒绝,然后分流到 2 台服务器上,如果缓存中还有可秒杀的数量,可以秒杀处理逻辑;当然如果数量更多或者场景更复杂,可以缓存秒杀成功的用户,然后异步保存;更多的话就需要异步处理,先把请求缓存到队列中,然后让 app 定时获取排队结果,然后访问实际的业务。
可扩展
其他说明
由于本次只涉及到秒杀,实际中商品的种类和数量较多,可能会导致数据库读性能超过预期,数据库需要从主备调整到主从;同样为了缓存的高可用,也可以把缓存从主备调整到哨兵模式。
评论