前言
如果大家对这方面知识不够了解往往会谈虎色变,比如我们都知道数据库的单行并发量大概300-500TPS那么怎么能支持百万级的并发呢?而恰巧本人目前参与相关业务开发对这方面知识存在涉猎,所以写下这篇万字图文讲解,如果有不对的地方请多多包涵。
秒杀场景特点
秒杀场景具有流量大、并发高、时间短、数据热点、业务复杂等特点,对系统的性能和可用性提出了很高的要求。如何设计一个能够应对百万级并发的秒杀系统,是一个值得深入探讨的问题。
前端层
前端层是秒杀系统的第一道防线,主要负责限流、降级、缓存等功能,减轻后端服务的压力。
- 静态资源缓存
- 将静态资源如JS、CSS、图片等部署到CDN,利用CDN的缓存和分发能力,减少应用服务器的压力
- 设置合理的缓存策略,如Cache-Control、Expires等,让浏览器尽可能使用缓存
- 前端限流
- 验证码过滤机器请求
- IP限制同一IP请求频率
- 前端降级&容错
- 如关闭核心功能,只保留倒计时、秒杀按钮等
DNS+CDN层
DNS和CDN可以将用户请求分发到离用户最近的服务节点,提高响应速度,减轻源站压力。
- DNS负载均衡
- 通过DNS解析将用户请求分发到不同的服务器或集群,实现负载均衡
- 可以使用权重、地理位置等策略,将请求分发到最优的服务节点
- 常见的DNS服务有:阿里云DNS、腾讯云DNS、Amazon Route 53等
- CDN加速
- CDN可以将静态资源缓存到离用户最近的边缘节点,提高访问速度,减轻源站压力
- 同时CDN也可以实现动态内容的加速,如利用CDN的节点缓存动态页面
- 常见的CDN服务有:阿里云CDN、腾讯云CDN、Amazon CloudFront等
负载均衡层
将用户请求分发到后端的多个服务器或集群,实现流量的均衡分配,提高系统的并发处理能力。
- 反向代理
- 负载均衡算法
- 会话保持
应用服务层
应用服务层是秒杀系统的核心,负责处理用户请求,实现秒杀业务逻辑。
- 集群部署
- 降级&熔断&隔离
消息队列
消息队列可以实现系统解耦、异步处理、削峰填谷等功能,是秒杀系统的重要组件。
- 异步处理
- 削峰填谷
- 消息重复消费
- 消息可靠性
除此之外在消息队列中还有以下的相关概念:
异常处理&实际效果
缓存层
缓存可以有效地减轻数据库的压力,提高系统的响应速度,是秒杀系统必不可少的组件。
多级分层架构
应用服务器->本地缓存(Caffeine)->分布式缓存(Redis)->数据库(MySQL)
缓存数据分类
针对秒杀场景中一般商品如下进行分类
缓存预热
预热规则、时机、数据
缓存更新策略
首先是Cache Aside Patten
更新策略
缓存失效分类和策略选择
数据一致性
数据库层
主要分五个方面 如下:
分库分表
垂直分库和水平分表
读写分离
读写分离,冷热数据分离
注意事项:数据/事务一致性、负载均衡等
索引优化
SQL优化
数据库层面一些索引、SQL优化就不展开详细论述了,相对来说大家可能对这块都比较熟悉。
系统可用性相关保障
分为高可用架构、降级&熔断、监控&告警
总结
现在我们在来梳理一下整个请求调用
- 100w用户点击秒杀按钮假设发送了100w请求
- 100wQPS到达前端层经过防抖、节流、限流等措施,过滤掉5w无效请求
- 95wQPS来到DNS+CDN层,通过请求分发分发给不同Nginx
- 4台Nginx 每台Nginx请求为5000qps 那么转发2W请求 93w无效请求被nginx网关过滤
- 2W请求来到应用层,一般大促场景8-12台服务器(弹性扩容)取10台 每台服务器只需要处理2000qps
- 2w请求经过应用层的处理后通过生产者发送给消息队列集群
- 假设topic主题 设置10个消费者 每个消费者QPS 10个消费者处理5000QPS 其他15000 请求进入等待队列
- 5000请求经过缓存秒返回 写到数据库层面可以是异步机制 分库分表 每张表只需要处理500TPS
总的来说,秒杀系统的请求经过了前端层、DNS和CDN层、应用层、消息队列层、缓存层、数据库层的层层过滤和处理,最终每个节点的请求量都控制在一个合理的范围内。这种分层分流的架构可以有效地应对秒杀场景下的高并发和大流量。