秒杀架构设计
[转载]个人理解,请批判接受,有误请指正。转载请注明出处: https://heyfl.gitee.io/framework-design/sec-kill-framework-design.html
常见的三类高并发场景
高并发压力主要来自,并发时出现大量锁冲突
1.细颗粒度操作-锁冲突少 如:QQ微信等即时通讯业务个人读个人自己的数据
数据结构
- 个人信息 user(uid…) 几十亿
- 个人的好友信息 friend(uid,friend_id…) 几百亿
- 个人的群 user_group(uid,group_id…) 几百亿
- 群成员 group_member(gid,uid…) 几千亿
- 个人消息(msg_id,uid…) 几千亿
- 群消息(msg_id,gid…) 几千亿
个人和群都是读写自己的数据
在高并发时(单个用户单位时间发出N个读写请求),锁冲突极小,每个【人】、【群】、【消息】只会锁住自己部分的消息
在出现IO瓶颈的时候 只需要进行水平分库 把【人】、【群】、【消息】进行切分
2.读多写少,存在少量写冲突 如:微博 自己的写为别人的读
拉模式的大概数据结构 参考:微博Feed业务架构–推拉模式
- 个人信息 user (uid…) 几十亿
- 个人的关注列表 user_follow (id,uid,follow_id…) 几百亿
- 个人发出的微博 msg (msg_id,uid…) 几百亿
大概流程:
假设用的是拉模式,多个粉丝拉取别的某位用户的发件箱时容易出现读写锁冲突
如: 在某明星粉丝刷微博时,明星消息表、评论表被快速读写,出现锁冲突,宕机
3.(同一份数据)多读多写,存在大量写冲突 如:12306秒杀业务
大概数据结构
- stock(s_id,time) //列车
- ticket(t_id,num,s_id) //列车余票
用户量大,并发很大时, 有极大的锁冲突,极容易把系统搞垮
一辆车几百万请求,有效请求200,成功请求数0,最终请求成功率≈0%
解决【多读多写,存在大量写冲突】的锁冲突问题
主要方向为降低【数据库层面的锁冲突】
(1)降低读请求:利用缓存
(2)降低写请求:上游尽量过滤无效请求
(1)降低读请求:尽可能利用缓存
- 前端: 浏览器、Nginx等静态页面缓存
- 站点层、服务层: 缓存结果、缓存数据…
(2)降低写请求:上游尽量过滤无效请求
- 前端: 通过JS做限速,减少99%请求(如:频繁点击,显示频率过快)
- 站点层: 拦截同个用户的重复请求(通过web层缓存或缓存集群 对[UID+TOKEN]进行计数&限速)
- 服务层: 通过MQ、内存队列收集请求(队列长度根据数据库抗压能力、库存数量设置)
- 数据库层: 单个主从