秒杀系统架构设计-第三章
二八原则:有针对性的处理好系统的"热点数据"
一部分商品被搭理亮用户访问的热卖商品,就是常说的"热点商品"。
热点商品种极端的例子就是秒杀商品,再很短时间内被大量用户执行访问、添加购物车、下单等操作,这些操作我们称为"热点操作"。
我们一定要关注热点,因为热点会对系统产生一系列的影响。首先,热点请求会大量占用服务器处理资源,热点请求所在的比例下,却可能占用90%的服务器资源。
什么是"热点"
热点分为热点操作和热点数据。
所谓"热点操作",例如大量的刷新页面、大量的添加购物车、双十一零点大量的下单等都属于此类操作。对系统来说,这些操作可以抽象为"读请求"和"写请求",这两种热点请求的处理方式大相径庭,读请求的优化空间要大一些,而写请求的瓶颈一般都在存储层,优化思路就是根据CAP理论做平衡。
"热点数据",就是用户的热点请求对应的数据。热点数据又分为"静态热点数据和"动态热点数据"
静态热点数据:就是能够提前预测的热点数据。例如,通过卖家报名的方式提前筛选出来,通过报名系统对这些热点商品进行达标。还可以通过大数据分析来提前发现热点商品,比如我们分析历史成交记录、用户的购物车记录,来发现哪些商品可能更热门、更好卖。
动态热点数据:就是不能被提前预测到,系统在运行过程中临时产生的热点。例如,卖家通过做广告,使商品一下子就火了。
热点操作使用户的行为,我们不好改变,但能做一些限制和保护,后面主要针对热点数据来介绍如何进行优化。
发现热点数据
我们要有一个机制提前来区分普通商品和秒杀商品
发现静态热点数据
实现方式使通过一个运营系统,把参加活动的商品进行打标,然后通过一个后台系统对这些热点商品进行预处理,如提前进行缓存。这种方式会由两个问题,一是增加卖家的使用成本,二使实时性很差。
不过,除了提前报名的方式,还可以听过买家每天访问的商品进行大数据计算,统计topN的商品,我们可以认为topN的商品就是热点商品。
发现动态热点数据
静态热点数据句实时性较差,我们可以使系统能在秒级内发现热点商品,能够动态的实时发现热点不仅对秒杀商品有价值,对其他热卖商品也同样有价值。
- 构建一个异步的系统,它可以收集交易链路上各个环节中的中间件产品热点key,如nginx、缓存、RPC服务框架这些中间
- 建立一个热点上报和可以按照需求订阅的热点服务的下发规范,主要目的是通过交易链路上各个系统(包括详情、购物车、交易、优惠、库存、物流等)访问的时间差,把上游已经发现的热点透传给下游系统,提前做好保护。比如,对于大促高峰期,详情系统是最早知道的,在同一接入层上Nginx模块统计的热点URL。
- 将上游系统手机的热点数据发送到热点服务台,然后下游系统(如交易系统)就会知道哪些商品会被频繁调用,然后做热点保护。
如下图,其中用户访问商品时经过的路径有很多,我们主要是依赖前面的导购页面(包括首页、搜索页面、商品详情、购物车等)提前识别哪些商品的访问量高,通过这些系统中的中间件来手机热点数据,并记录到日志中。
通过部署在每台机器上的Agent把日志汇总到聚合和分析集群中,然后把符合一定规则的热点数据,通过订阅分发系统在推送到相应的系统中。你可以是把热点数据填充到Cache中,或者直接推送到应用服务器的内存中,还可以对这些数据进行拦截,总之下游系统可以订阅这些数据,然后根据自己的需求决定如何处理这些数据。
根据经验需要总结几点注意事项:
- 热点服务后台抓取热点数据日志最好采用异步方式,因为“异步”一方面便于保证通用性,另一方面又不影响业务系统和中间件产品的主流程。
- 热点服务发现和中间件自身的热点保护模块并存,每个中间件和应用还需要保护自己。热点服务台提供热点数据的手机和订阅服务,便于把各个系统的热点数据透明出来。
- 热点发现要做到接近实时(3s内完成热点数据的发现),因为只有做到接近实时,动态发现才有意义,才能实时的对下游系统提供保护。
处理热点数据
处理热点数据通常有三种思路:优化,限制,隔离
优化:优化热点数据最有效的办法就是缓存热点数据,如果热点数据做了动静分离,那么可以长期缓存静态数据。但是,缓存热点数据更多的是“临时缓存”,即不管是静态数据还是动态数据,都用一个队列短暂的缓存数秒钟,由于队列长度有限,可以采用LRU淘汰算法替换。
限制:限制更多是一种保护机制,限制的办法很多,例如对被访问的商品id做一致性hash,然后根据hash做分桶,每个分桶设置一个处理队列,这样可以把热点商品限制在一个请求队列里,防止因某些热点商品占用太多服务器资源,而使其他请求始终得不到服务器的处理资源。
隔离:将热点数据隔离出来,不要让1%的请求影响到另外的99%,隔离出来后更方便对这1%的请求做针对性优化。
我们可以对以下几个层次实现隔离:
- 业务隔离。把秒杀做成一种营销活动,卖家要参加秒杀这种营销活动需要单独报名,从技术上来说,卖家报名后对我们来说就有了已知热点,因此可以提前做好预热。
- 系统隔离。系统隔离更多的是运行时的隔离,可以通过分组部署的方式和另外99%分开。秒杀可以申请单独的域名,目的也是让请求落到不同的集群中。
- 数据隔离。秒杀所调用的数据大部分都是热点数据,比如会启用单独的Cache集群或者Mysql数据库来放热点数据,目的也是不想0.01%的数据有机会影响99.99%数据
实现隔离有很多方法。比如,你可以按照用户区分,给不同的用户分配不同的cookie,在接入层,路由不同的服务的服务接口中;再比如,你还可以在接入层针对URL中不同Path来设置限流策略。服务层调用不同的服务接口,以及数据层通过给数据打标来区分等等这些措施,其目的都是把已经识别出来的热点请求和普通请求区分开。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。