暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

秒杀系统的热点数据处理

Alleria Windrunner 2021-10-22
958
上一篇我们介绍完了秒杀系统的降级处理,本篇我们来看一下秒杀系统的热点数据处理。
在讲热点数据的处理之前,我们先看看高并发的常规解决思路。分布式系统设计,解决高并发问题,可能你很快会想到,如果是数据库,可以通过分库分表来应对,如果是 Redis,可以增加 Redis 集群的分片来解决,而应用层一般是无状态的设计。所以从数据库、Redis 缓存到应用服务,都是可以通过增加机器来水平扩展服务能力,解决高并发的问题。
然而,这样就能应对秒杀的挑战了吗?其实还不够,前面我有提到,秒杀的核心问题是要解决单个商品的高并发读和高并发写问题,也就是要处理好热点数据问题。
所谓热点数据,是从单个数据被访问的频次角度去看的。单位时间(1s)内,一个数据非常频繁的被访问,就可以称之为热点数据,反之可以归为一般数据或冷数据。那么单位时间内究竟多高的频次才能称为热点数据呢?实际上并没有一个明确的定义,可以根据你自己的系统吞吐能力而定。
平价茅台在进行秒杀时,只有这个 SKU 是热点,所以再怎么进行分库分表,或者增加 Redis 集群的分片数,茅台 SKU 落在的那个分片的能力实际并没有提升,总会触达上限,把 Redis 打挂,最后可能引发缓存击穿、系统雪崩。那我们应该怎么解决这个棘手的热点问题呢?
我们把这个问题分为两类:读热点问题和写热点问题。下面我们分别展开讨论。
先看下读热点如何解决,我先抛出解决该问题的思路:
  1. 增加热点数据的副本数;

  2. 让热点数据离用户越近越好。



以上是秒杀系统的部署结构图,参照解决思路,我们的第一个解决方案,就是增加 Redis 从的副本数,然后业务层(Tomcat 集群)轮询查询不同的副本,提高同一数据的 QPS。一般情况下,单个 Redis 从,可提供 8~10 万的查询,所以如果我们增加 12 个副本,就可以提供百万 QPS 的热点查询。


这个方法能解决热点问题,但成本比较高,如果你的集群分片数比较多,那分片数 * 副本数就是一笔不小的开销。
第二个解决方案,我们把热点数据再上移,在 Tomcat 集群做热点数据的本地缓存,也就是让业务层的每个实例里都有份数据副本,读请求数据的时候,无需去 Redis 获取,直接从本地缓存里取。这时候,数据的副本数和 Tomcat 实例一样多,另外请求链路减少了一层,而且也减少了对 Redis 单片 QPS 上限的依赖,具有更高的可靠性和更高的性能。


这种方式热点数据的副本数随实例的增加而增加,非常容易扩展,扛高流量。不过你要思考一个问题,本地缓存的数据延迟业务是否能够接受?
如果能接受,本地缓存的时候可以设置几分钟?如果对延迟要求比较高,可以设置 1s,这样对 Redis 而言,OPS 的压力直接降低到实例数 每秒,就不需要那么多副本了。
本地缓存的实现比较简单,可以用 HashMap、Ehcache,或者 Google 提供的 Guava 组件。
读热点还有一个比较简单粗暴的方法,那就是直接短路返回。这么说可能比较抽象,我举个例子,茅台秒杀的时候,这个 SKU 是不支持使用优惠券的,那么优惠券系统在处理的时候,可以根据配置中心的茅台 SKU 编码,直接返回空的券列表,这样基本上不怎么耗资源,效率非常高。当然了,这种方式和具体商品的活动方式有关,不具有通用性,但是在几百万的流量面前,简单有效。
介绍完读热点,接下来我们看写热点问题。我们先回忆一下,在前面讲流量管控里,我们介绍到用户点击“立即预约”的时候,会往“预约人数”这个 Redis key 上进行 ++ 操作,当几百万人同时预约的时候,这个 key 就是热点写操作了。
这个预约总人数有个特点,只是在前端给用户展示用,除此之外,没有其他用途,因此在高并发的场景下,这个人数可以不用那么及时和精确。知道了问题所在,解决方案就在眼前了,我们的思路就是先在 JVM 内存里 ++,延迟提交到 Redis,这样就可以把 Redis 的 OPS 降低几十倍。以下是示意图:


写热点还有一个场景就是库存的扣减,这里讲一下基本思路,可以通过把一个热 key 拆解成多个 key 的方式,避免热点问题。这种设计涉及到对库存进行再细分,以及子库存挪动,非常复杂,而且边界问题比较多,容易出现少卖或者超卖问题,一般不推荐这种方法。

另一个思路就是对单 SKU 的库存直接在 Redis 单分片上进行扣减,实际上,库存系统在秒杀链路的末端,通过我们之前介绍的削峰和限流,真正到库存的流量是有限的,单片的 Redis OPS 能承受得了。然后,我们可以针对单 SKU 的库存扣减进行限流,保证库存单片 Redis 的压力。这样双管齐下,单 SKU 的库存 Redis 扣减压力就是可控的了。
文章转载自Alleria Windrunner,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论