秒杀中超卖问题及各层解决方案

1.1 秒杀系统架构

秒杀技术特点

读多写少

举例:

淘宝商场在双十一活动时,可能有几千万人在浏览同一个商品,而在这个时间点里读的是特别多,但是真正买到商品的人特别少

高并发

举例:

可能同一时间有很多人都在抢购同一件商品,然后不管抢到抢不到都会发送请求给后端,给后端服务器造成压力,这就是高并发

资源冲突

举例:

比如有1000件商品,然后有多个人对数据库进行写的操作,也就是减1操作,有没有可能最后卖出了1002件商品,这是不可能的

在python2中,使用多线程进行count操作,如
count=1000,
用100个线程每次进行减1操作      count-=1    
然后减1000次,它可能是1或者是2
因为它有些减的操作被覆盖了

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,如果要是乐观锁,B过来还是可以读1000,此时没有加锁
    • A进行商品扣减的时候会校验,现在的商品数量是否和开始数量一致
    • A扣减(排它锁)之后要不999写入到mysql中时会校验商品数量是否是1000
    • 和A刚开始读的数据一致就写入,不一致重试

1.2 各层解决方案

应用层(localstorge存的数据)

打开浏览器,浏览器里会有缓存,缓存的可能就是静态页面,还有一些按钮控制相关的东西,而我们打开浏览器买东西所访问的静态页面,访问的并不是源站,而是cdn

1.网络层 CDN

  • 特点:cdn服务器不需要安装部署,不是一个真实的后端服务器,仅仅缓存了前端数据

  • 作用:减轻源站的服务器压力,对于国外访问,可以更快速

  • CDN不是把我们的服务部署在全世界各地(成本太高)

  • CDN是静态资源的缓存(JS,Html、Css、图片、视频),不会变

  • 网站提供是一个后端API接口

  • 你从美国打开的商家的商品图片来美国的一台CDN服务器

  • 但是请求的API接口,后端服务可能还是部署在中国

  • 需要和数据库动态交互的,CDN没有任何作用

2.负载层(高可用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hpFfb6s2-1582374354690)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1581938282959.png)]

Nginx负载均衡存在问题(单点故障):

代理的服务器如果死了一半,那么他还剩下另外一半服务器能用,但是如果主服务器死了,那么其他代理服务器也就没用了
负载层不会直接到达Nginx,能保持高并发,不能保活

比如有一个主Nginx服务器,他如果不使用负载均衡的话,他就只有一台服务器,而如果使用负载均衡,就可以把请求代理分发给多台服务器。

不用负载均衡存在问题:多个用户同时访问主Nginx时,他不一定能处理那么多的并发量

Nginx反向代理就是主Nginx不去处理,而是把流量分发给其他机器
  • **nginx负责均衡:**https://www.cnblogs.com/xiaonq/p/10468998.html

  • 问题:只能解决高并发,不能解决高可用

如果给主Nginx加一台机器,能不能解决高可用?
不能,因为他们的ip不一样。两台Nginx是没有办法使用一个虚ip的

而keepalive可以做到,是因为keepalive-master、keepalive-slave虽然名字不一样,但是他们的ip一样
```
客户端——>互联网——>keepalive-master——>后端——>数据库——>请求返回给客户端
  • keepalive和lvs、haproxy有了解(解决高可用问题,单点故障)

  • keepalive:https://www.cnblogs.com/xiaonq/p/11694253.html

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Dykpt2HI-1582374354691)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1581939171194.png)]

keepalive双活机制:
两台keepalive服务器(或者多台,只有master干活)同时监听一个虚拟IP,同一时间只有keepalive-master集群能够进行服务代理,当keepalive-master宕机,keepalive-slave会立刻顶替master执行集群代理服务
keepalive软件有两种功能:监控检查、VRRP冗余协议.

keepalieve会从以下三层来检查集群中的服务是否正常:
1)layer3:通过ICMP协议ping测试
2)layer4:比如web服务,keepalived检查80端口是否启动
3)layer7:根据用户的设定检查服务器程序运行是否正常
keepalived--VRRP冗余协议原理:
    vrrp是虚拟路由冗余协议,就是当出现单点故障问题通过竞选方式决定vip走向的一种机制.
    
1. Keepalived高可用是通过vrrp协议通信的,vrrp是通过竞选机制决定主备
2. Keepalived 主的服务器会一直发送 VRRP广播包,告诉备它还活着
3. 当备机监听不到主发送的广播包时,就人为主机不可用,所有备机通过配置文件中的优先级选举新的主机
4. 新的主机就会启动相关服务接管资源,保证业务的连续性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mxuPj6S5-1582374354692)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1581940598364.png)]

高并发介绍

概念

1. PV(访问量): 页面访问量,页面刷新一次算一次。
2. UV(独立访客): 即Unique Visitor,一个客户端(电脑,手机)为一个访客;理论以终端辨别
3. DAU(日活跃用户数):登录或使用了某个产品的用户数,这与流量统计工具里的访客(UV)概念相似。
4. 峰值QPS:
qps衡量一个公司架构的最低并发量
	原理:每天80%的访问集中在20%的时间里,这20%时间叫做峰值时间
    公式:( 总PV数 * 80% ) / ( 每天秒数 * 20% ) = 峰值时间每秒请求数(QPS)
5. QPS/TPS(每秒查询率):每秒能够查询次数(QPS/TPS= 并发数 / 平均响应时间)
	并发数:并发数是指系统同时能处理的请求数量,这个也是反应了系统的负载能力。
    吐吞量:吞吐量是指系统在单位时间内处理请求的数量
    响应时间(RT):响应时间是指系统对请求作出响应的时间,一般取平均响应时间

django性能

跟带宽,服务器性能有关,比如4核8G机器正常每秒可以处理500上下的并发量

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

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

猜你喜欢

转载自blog.csdn.net/lxp_mocheng/article/details/104449875