《淘宝大秒系统设计详解》
https://blog.csdn.net/heyc861221/article/details/80122167
要点
动静分离
数据分层校验
把大量静态不需要检验的数据放在离用户最近的地方;在前端读系统中检验一些基本信息,如用户是否具有秒杀资格、商品状态是否正常、用户答题是否正确、秒杀是否已经结束等;在写数据系统中再校验一些如是否是非法请求,营销等价物是否充足(淘金币等),写的数据一致性如检查库存是否还有等;最后在数据库层保证数据最终准确性,如库存不能减为负数。
同一商品大并发读
问题
解决方法:Localcache和数据的分层校验
虽然我们的Tair缓存机器单台也能支撑30w/s的请求,但是像大秒这种级别的热点商品还远不够,那如何彻底解决这种单点瓶颈?答案是采用应用层的Localcache,即在秒杀系统的单机上缓存商品相关的数据。
你可能会有疑问,像库存这种频繁更新数据一旦数据不一致会不会导致超卖?其实这就要用到我们前面介绍的读数据分层校验原则
了,读的场景可以允许一定的脏数据,因为这里的误判只会导致少量一些原本已经没有库存的下单请求误认为还有库存而已,等到真正写数据时再保证最终的一致性
。这样在数据的高可用性和一致性做平衡来解决这种高并发的数据读取问题。
同一数据大并发更新
问题
解决方法:把热点商品放到单独的热点库中
分离热点商品到单独的数据库还是没有解决并发锁的问题
,要解决并发锁有两层办法:
应用层做排队。按照商品维度设置队列顺序执行,这样能减少
同一台机器
对数据库同一行记录操作
的并发度,同时也能控制单个商品占用数据库连接的数量,防止热点商品占用太多数据库连接。数据库层做排队。应用层
只能做到单机排队
,但应用机器数本身很多,这种排队方式控制并发仍然有限,所以如果能在数据库层做全局排队是最理想的,淘宝的数据库团队开发了针对这种MySQL的InnoDB层上的patch,可以做到数据库层上对单行记录做到并发排队
思考
其他措施:限流和保护
其他数据热点问题:
数据访问热点。
一旦某个热点触发了一台机器的限流阀值,那么这台机器Cache的数据都将无效,进而间接导致Cache被击穿,请求落地应用层数据库出现雪崩现象。
通用解决:Cache的client端做本地Localcache,当发现热点数据时直接Cache在client里,而不要请求到Cache的Server。数据更新热点。
还有些场景,如对商品的lastmodifytime字段更新会非常频繁,在某些场景下这些多条SQL是可以合并的
,一定时间内只执行最后一条
SQL就行了,可以减少对数据库的update操作。另外热点商品的自动迁移,理论上也可以在数据路由层
来完成,利用前面介绍的热点实时发现自动将热点从普通库里迁移出来放到单独的热点库中。
《Redis热点Key发现及常见解决方案》
https://www.jianshu.com/p/c034d6027d06
- 读写分离方案
- 在 Proxy 上增加本地缓存,本地缓存采用 LRU 算法来缓存热点数据,后端 db 节点增加热点数据计算模块来返回热点数据。