秒杀系统高并发优化
高并发发生在什么地方
- 详情页
- 获取系统时间
- 地址暴露接口
- 执行秒杀操作
CDN(详情页解析后的页面及各种js静态资源)
CDN(Content Delivery Network 内容分发网络),加速用户获取数据(静态资源)的系统,部署在离用户最近的网络节点上(网络提供商的服务器)。命中CDN后不需要访问后端服务器。CDN服务由互联网公司自己搭建或租用。
获取系统时间
- 需要优化吗?
- 不涉及访问后台数据库
- 由服务器每次新建一个Date()对象直接返回,并不消耗什么性能
- 所以不用优化
地址暴露接口
- 动态数据,需要访问数据库,无法使用CDN缓存
- 适合服务端缓存:redis,memcached等
- 先访问数据库把对应id的地址计算完缓存到redis中
- 然后客户端访问就可直接进入缓存查找,无需访问数据库
- 一致性维护成本低
- 对地址统一维护
- 超时穿透/主动更新
秒杀操作优化
- 无法使用CDN缓存
- 后端缓存困难:库存问题(要保证一致性,事务)
具体方案(大公司):
- 执行秒杀
- 原子计数器减一(使用redis/NoSQL集群)
- 记录行为消息(分布式消息队列MQ message queue)
- 后端服务器消费消息并落地(落地到MySQL)
优点:
- 生存者消费者模式,可以抗住非常高的并发
缺点:
- 运维成本和稳定性:NoSQL,MQ等
- 开发成本:数据一致性,回滚方案等
- 幂等性难保证:重复秒杀问题
- 再建一个缓存集群记录
低成本方案(MySql):
- 性能瓶颈
- MySql事务,行级锁的存在(并行变串行)
- 事务在java后台执行,释放行级锁时间变长
- update,insert,commit/rollback分开,中间存在网络延迟甚至GC
- 优化方向
- 减少行级锁持有时间
- 把客户端逻辑放在MySQL服务器上,避免事务受网络延迟和GC
- 定制SQL(修改底层源码,新增update auto commit的功能)
- 使用存储过程:整个事务在MySQL完成
- 减小网络延迟(web服务器与mysql同城机房)
- 减少GC频率(JVM调优)
- 减少行级锁持有时间
优化总结
- 前端控制:到时暴露接口,按钮防重复
- 动静态数据分离:CDN缓存,后端缓存
- 事务竞争优化:减少事务锁时间