写点什么

毕业设计 - 电商秒杀系统

作者:
  • 2023-04-04
    广东
  • 本文字数:4278 字

    阅读完需:约 14 分钟

背景介绍


【业务背景】

你作为一个电商创业公司的架构师,负责设计 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. 用户注册与登录:用户需要注册并登录电商平台,以便购物、查看购物车、查询订单等。

  3. 商品搜索与筛选:用户可以通过关键词搜索商品,或使用分类、筛选条件等方式找到心仪的商品。

  4. 结算与下单:用户在购物车中选择需要购买的商品,填写收货地址、选择支付方式等信息,确认订单信息后下单。

  5. 支付:用户根据订单信息,通过在线支付方式(如支付宝、微信支付、银行卡等)支付订单款项。

  6. 订单处理:电商平台接收到订单后,进行订单处理,包括库存检查、订单分配等。


秒杀业务

秒杀大致流程



关键点

  1. 用户必须在 App 上才能完成秒杀活动,包括 IOS 和 Android 应用、以及小程序等。

  2. 因为电商业务本身已经做了微服务架构,为保证秒杀活动的顺利进行,同时不会冲击到正常的电商业务活动,考虑将秒杀活动单独做一个微服务,在业务上同正常的商品售卖进行隔离,同时后续的秒杀活动也能在此系统上进行。

  3. 秒杀活动的特点,就是将用户全部集中到同一个时刻,然后一起开抢某个热门商品,而热门商品的库存往往又非常少,所以持续的时间也比较短,快的话可能一两秒内就结束了。在此期间我们要对库存做针对性的设计,保证活动的准确性,确保商品不会超卖

  4. 除了保证准确性以外,稳定也非常重要;为此,我们要通过流控、削峰、限流、降级、热点和容灾等手段保证秒杀系统的高可用性

  5. 在保证了准确性和高可用的基础上,我们应该尽量实现高性能、低延迟,让秒杀活动响应更快,从而提高用户的体验性


总体架构思路


框架规模

老用户

假设电商平台的平时活跃用户比例为 20%,则可估计总的用户数为: 100 万 (日活) / 20% (活跃度) = 500 万(总用户);假设有一半用户参与秒杀活动,则秒杀用户数为:500 万(总用户) * 50%(参与用户比例) = 250 万(参与用户数)

新用户

考虑到 iphone12 有较高的吸引力,同时充电宝又较为刚需,可假设该促销活动拉新的比例为 10%,即 500 万(总用户)* 10% (拉新比例)= 50 万 (新用户注册)。

总用户数

秒杀用户数:老用户数 (250 万)+ 新用户数(50 万)= 300 万。所以考虑按照百万用户规模架构进行框架设计。


技术点实现

  1. 存储:MySQL 分库分表策略,将订单数据、用户数据、商品数据等存储在不同的数据库和表中

  2. 缓存:CDN 缓存热点数据、Redis 作为缓存存储,减轻数据库压力,提高系统性能。

  3. 负载均衡:Nginx 作为负载均衡器,将流量分发到不同的应用服务器上,同时采用 IP Hash 算法进行负载均衡,保证同一个用户的请求始终分发到同一台服务器上,避免 session 不一致问题。

  4. 高可用:MySQL 主从复制,Redis 主从复制,应用服务集群部署,秒杀活动中,保证数据和服务的高可用性是至关重要的。

  5. 可扩展:采用微服务架构,可以应对秒杀活动中的流量波动,提高系统的可扩展性

  6. 限流:采用令牌桶算法限制用户请求速率,避免系统过载

  7. ?降级:优先保证下单、结算任务,其次为登录业务,注册业务放到最后


存储架构设计


考虑到秒杀商品较少,不需要单独新建数据库,只需要将秒杀的商品进行标记即可,此处分析该电商系统的存储架构设计。

存储性能估算

注册

新用户加老用户总数为 550 万,考虑冗余,假设有 600 万用户注册信息。


电商业务的个人信息一般包括用户基本信息(包含头像)、账号信息、收货地址信息:


  • 用户基本信息:包括姓名、性别、年龄、联系方式、头像图片等。

每个字段占用的字节数不同,假设姓名一般占用 2~30 字节不等,性别和年龄可以用 1~2 字节存储,联系 方式可以用 10~20 字节存储,假设每个字段平均占用 10 字节,则用户基本信息大约需要占用 40 字节。


  • 账号信息:包括用户名、密码、邮箱地址、手机号码等。

用户名、密码、邮箱地址和手机号码等字段的存储方式不同,用户名和密码可以用 20~30 字节存储,邮箱地址可以用 30~50 字节存储,手机号码可以用 10~20 字节存储,假设每个字段平均占用 30 字节,则账号信息大约需要占用 120 字节。


  • 收货地址信息:包括收货人姓名、手机号码、详细地址等。

收货地址信息:收货人姓名和详细地址等字段的存储方式不同,假设收货人姓名可以用 2~30 字节存储,详细地址可以用 50~100 字节存储,假设每个字段平均占用 30 字节,则收货地址信息大约需要占用 60 字节。


  • 头像:头像为图片,此处按 1M 字节来考虑。


个人信息存储量为:600 万 * 220 字节(单人信息文字存储量) ≈ 1.5GB

图片数据:600 万 * 1M 字节 ≈ 6TB

随着新用户的增长,存储量还会持续增加。


个人信息存储量较少,而且极少变更,考虑使用 Mysql 主备复制架构,进行存储。

图片数据存储量较大,只是单纯的文件存储,不包含关系信息,考虑使用 Hbase 集群架构,进行存储。

登录

秒杀日活为 250 万,加上又新注册的用户 50 万,总计有 300 万的登录请求。


登录记录,数据存储量较大,同样不包含关系信息,而且较其他数据也较为隔离,所以考虑使用 Hbase 集群架构进行存储,会更有效率。

商品详情

10 个种类,每个种类 20 个商品,总商品数量为:10 * 20 = 200 个商品,考虑预留量为 2 倍,总计有 200 * 2 = 400 个商品量。


商品详情页包括文字和图片,假设:

  1. 文字内容:假设商品详情页包括商品标题、描述、规格等文本信息,总共约 1000 个字。一个汉字在 UTF-8 编码中占 3 个字节,所以总共约为 3000 字节

  2. 图片内容:商品详情页通常包括多张图片,如商品主图、细节图、使用场景图等。假设平均每张图片大小为 1MB,共有 10 张图片,那么图片内容的总字节数约为 1MB * 10 = 10M。


那么每个商品详情页的文字存储量为:400 * 3000 字节 ≈ 1.2MB

图片存储量为:400 * 10MB ≈ 4GB,考虑冗余,则图片总存储量为:5GB


因为商品信息是供百万用户去读的,而且用户浏览的商品信息是一样的,考虑到 Redis sentinel 支持主从,从机可以分担一部分读取的压力,所以商品信息使用 Redis sentinel 集群架构进行存储,从而可以实现较高的性能。

订单

日活有百万,假设每两个用户有一个产生购买行为,同时假设订单信息量(不考虑图片)为 10KB,每天订单量 50 万 * 10KB 5GB

订单中的图片信息可从商品信息中获取。


因为订单量每天都会累加,同时电商后台会对订单进行分析,优化电商系统,所以考虑使用 Mysql 分库分表对订单进行存储

存储架构设计


对上述场景中的存储架构进行合并,得到:

MySQL 的主备复制和分库分表统一为 MySQL 集群


计算架构设计

性能估算

注册

考虑到有 50 万新用户注册,假设注册动作分布在白天的 8 小时内,则注册的 TPS 为:50 万 / (8 * 3600) ≈ 18 / s,TPS 较小,可以忽略。

登录

秒杀日活为 250 万,加上有新注册的用户 50 万,总计有 300 万的登录请求。假设登录请求集中在秒杀前的 1 个小时,则登录的 TPS 为:300 万 / (1 * 3600) ≈ 1000 / s。

商品详情

用户在进行商品秒杀的时候,会有频繁刷新商品详情页的操作,此处假设有 20%的用户在秒杀前的半分钟内平均刷新 5 次,则查询详情页的 QPS 为:300 万 * 20% * 5(次)/ (30)= 10 万 / s, 考虑 50%的预留量,则查询商品的 QPS 为: 15 万 / s。


抢购

在秒杀的过程中,系统一般会先查一下库存是否足够,如果足够才允许下单,写数据库。如果不够,则直接返回该商品已经抢完。由于大量用户抢少量商品,只有极少部分用户能够抢成功,所以绝大部分用户在秒杀时,库存其实是不足的,系统会直接返回该商品已经抢完。


此功能也是系统中并发量最大的操作,所有秒杀用户可能集中在几秒中内,发出抢购请求,如果此时所有请求(几百万)都直接访问数据库或缓存,会给数据库或缓冲带来极大的压力和挑战,所以考虑采用削峰和限流的方式对流量进行筛选。



假设通过削峰和限流之后,流量剩余 20%,同时,点击抢购动作在 2 秒内完成,则查询库存的 QPS 为:300 万 * 20% / 2 = 30 万 / s。


下单

秒杀商品有 1000 个充电宝,10 台 iPhone 12 ,共计 1010 件商品,所以真正能形成有效订单量为 1010。

考虑下单成功的客户不一定在有效期内支付,或者其他原因,导致订单取消等问题,此处考虑 2 倍冗余,即 2000 订单量,假设所有商品在 1s 内抢完,则下单的 TPS 为:2000 / 1 = 2000 / s。

支付

只有下单成功后才会进行付款,同时,支付主要依赖于第三方支付平台,此处不进行考虑

负载均衡



性能量级的大头为浏览商品和抢购,考虑到浏览商品和抢购的性能量级均已达到 10 万量级,尤其抢购的量级已经达到 30 万,所以负载均衡决定采用 LVS,LVS 的性能量级为:10 万~100 万。


单机房内负载均衡架构为:



缓存架构

由于是创业型公司,不考虑使用 CDN,成本太高。


同时由于应用内缓存实现起来复杂度较高,比如要保证应用内缓存和分布式缓存的一致性,也要考虑应用内缓存之间的一致性,实现和维护的复杂度对于创业公司来说太高,所以不考虑使用应用内缓存。


使用 3 级缓存架构:



说明:

  1. 秒杀商品的文本和图片信息可以在活动前下发到 App 缓存。

  2. WEB 容器缓存主要是在 Apache、Tomcat、Nginx 等容器进行缓存,主要存储静态资源。

  3. 商品信息、库存信息、订单信息等,放到 Redis 缓存中。


可扩展架构

微服务拆分思路:

  1. 按性能拆分:将访问量比较大的业务拆分出来,商品服务

  2. 按重要程度拆分:将重要程度高的业务拆分出来,订单服务和库存服务。

  3. 用户服务(会员服务)单独拆分成一个会员服务

  4. 其他服务汇总成综合服务

  5. 考虑到支付服务调用第三方支付系统,此处不再单独拆分。


微服务拆分:



高可用架构

由于只有单机房,可用性取决该机房的稳定性,只能做到同城单中心,后续随着业务量的增长、营收的增长为了保证业务的高可用和稳定性,可以采用同城多机房,或异地多活的高可用架构。


补充

关于限流

采用令牌桶算法限制用户请求速率,避免系统过载为不同类型的请求设置不同的限流阈值,确保关键请求的优先处理原因:限流可以保证系统的稳定运行,避免因流量过大导致的服务崩溃。


演化

由于业务背景和技术背景的限制,目前尚未考虑实施这些设计点。在未来业务发展和技术演进的过程中,可根据需要进行相应的优化和改进,可以考虑以下优化建议:


  1. 引入 CDN,加速静态资源的加载速度,提高用户体验

  2. 部署多机房,提高系统的容灾能力

  3. 采用分布式锁,保证分布式环境下的数据一致性


发布于: 2023-04-04阅读数: 6
用户头像

关注

还未添加个人签名 2018-06-01 加入

还未添加个人简介

评论

发布
暂无评论
毕业设计 - 电商秒杀系统_架构实战营_源_InfoQ写作社区