欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

秒杀系统架构

程序员文章站 2024-01-22 11:06:58
...

  • 秒杀系统部署
  • 高并发项目整体架构部署(500万日活项目部署)
  • 大体先梳理项目中的技术点(结合实验楼分析项目整体架构和技术点)

1, 秒杀系统架构

1.超卖问题

  • 1000件商品
  • 第一步查询商品数量
  • 查询商品:A 读 商品 1000 B 读 商品 1000
  • 扣减库存:A : 1000-1 =999写入数据库,B:1000-1=999
  • 卖了两件商品,商品数量:999

2.乐观锁和悲观锁如何解决超卖问题的

  • 悲观锁解决的原理
    • A读商品数量是1000,如果要是悲观锁,A读完数量后商品就加锁(排它锁)了
    • B过来商品数量,A加的锁还没有释放,所以B要等待
    • 只有当A卖完商品,商品数量减一,把商品数量为 999重新写入到数据库才释放锁
    • B获得商品时商品数据量是999而不是1000
  • 乐观锁解决的原理
    • A读商品数量是1000,如果要是乐观锁这一刻乐观锁没有加锁
    • A进行商品扣减的时候会校验,现在的商品数量是否和开始数量一致
    • A扣减(排它锁)之后要不999写入到mysql中时会校验商品数量是否是1000
    • 和A刚开始读的数据一致就写入,不一致重试

2, 各层解决方案

1.网络层 CDN

  • 特点:CDN服务器不需安装部署,不是一个真实的后端服务器,仅仅缓存了前端数据
  • 作用:减轻源站的服务器压力,对于国外访问,可以更快速
  • CDN不是把我们的服务部署在全世界各地(成本太高)
  • CDN是静态资源的缓存(JS,Html、Css、图片、视频),不会变
  • 网站提供是一个后端API接口
  • 你从没过打开的商家的商品图片来美国的一台CDN服务器
  • 但是请求的API接口,后端服务可能还是部署在中国
  • 需要和数据库动态交互的,CDN没有任何作用

2.负载层(高可用)

秒杀系统架构

  • keepalive和lvs、haproxy有了解(解决高可用问题)

  • 解决了单点故障
    秒杀系统架构

3, 五百万日活整体架构

1.高并发常用的

  1. PV(访问量): 页面访问量,页面刷新一次算一次。

  2. UV(独立访客): 即Unique Visitor,一个客户端(电脑,手机)为一个访客;

  3. DAU(日活跃用户数):登录或使用了某个产品的用户数,这与流量统计工具里的访客(UV)概念相似。

  4. 峰值QPS:

原理:每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间

公式:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)

  1. QPS/TPS(每秒查询率):每秒能够查询次数(QPS/TPS= 并发数 / 平均响应时间)

并发数:并发数是指系统同时能处理的请求数量,这个也是反应了系统的负载能力。

吐吞量:吞吐量是指系统在单位时间内处理请求的数量

响应时间(RT):响应时间是指系统对请求作出响应的时间,一般取平均响应时间

2.django性能

  • 4核8G的机器,正常每秒能处理200多请求(不能超过500)
  • 每秒能处理的请求数量

4, 架构分析

1.QPS分析

四核8G机器部署django+uwsgi
开启的进程数等于或略大约核数(最多不要超过1.5倍)
线程:每个洗衣机每次最多能洗的数量

处理一个需要1s,0.2
4*2= 8/秒


processes = 4   # 开启5个进程
threads = 50    # 每个进程最多开启2个线程

200个线程,

1万 两万

8÷0.2=40 

2.SLB阿里云

  • SLB相当于一个keepalive多活集群

3.500万日活流量

  • 如果直接读mysql,流量会直接崩溃
    • 把热点数据先预加载到redis缓存中,先读缓存,如果没有就查询数据库,把查询的数据加入缓存
    • 页面静态化
  • 大量的写数据,写入mysql(流量消峰)
    • 延时,第二mysql没有办法一次处理这么多并发连接
    • 先写数据库的请求加入RabbitMQ,然后通过异步任务,一点点取出RabbitMQ的任务往mysql写入

5, 高并发架构各层能做的事情

  • 应用层
    • 浏览器本地缓存:缓存静态页面、缓存加入购物车的数据
  • 网络层
    • CDN缓存静态资源:html/css/js/图片
  • 负载层(高并发、高可用)
    • keepalive(haproxy)+nginx反向代理(腾讯云LB、阿里云的SLB)
  • 服务层
    • 动态页面静态化(比如Django的cache服务),减少查询数据库的次数
    • 借助redis缓存解决大量的mysql查询压力
    • RabbitMQ+异步解决mysql的大量写入问题
    • 限流:
      • 抢购:nginx设置了保护功能,当流量过大自动丢弃(负载层就丢弃了)(nginx过载保护
      • 同一个设备、账号、出接口ip 一秒钟最多访问次数
  • 数据库层
    • 解决超卖问题:乐观锁、悲观锁解决数据安全
    • mysql一主多从,读写分离:写主库,读从库(所有数据库的数据一样)
      • 数据一样的,那么当数据量太大的时候查询还是很慢
    • 分库(根据用户id分库)
      • 所有数据库的表结构一样,存储的数据完全不一样
      • 真实环境以用户id进行分库,每一个库的数据都很小,查询起来就快了
      • 无法解决问题:当一个数据库中表中量过大的时候,查询依然会慢
    • 分表(根据时间分表)
      • 当一个表中数据过大的时候,我们必须要对表拆分
      • 购物清单表中有两千万数据
        • 最近半年的购物数据时 一百万
        • 半年到一年的数据有五百万
        • 一年以前的数据有一千万