• 《架构即未来 现代企业可扩展的Web架构流程和组织》


     

      

     

     

     

     

     

     

     

     

     

      

     

     

     

      

     

     

     

     

     

     

     

     

    AKF扩展立方体(Scalability Cube),是《架构即未来》一书中提出的可扩展模型,这个立方体有三个轴线,每个轴线描述扩展性的一个维度,他们分别是产品、流程和团队:

    X轴 —— 代表无差别的克隆服务和数据,工作可以很均匀的分散在不同的服务实例上;

    Y轴 —— 关注应用中职责的划分,比如数据类型,交易执行类型的划分;

    Z轴 —— 关注服务和数据的优先级划分,如分地域划分。

     
    AKF扩展立方体

    三个维度扩展的对比

    通过这三个维度上的扩展,可以快速提高产品的扩展能力,适应不同场景下产品的快速增长。不同维度上的扩展,有着不同的优缺点:

    1.X轴扩展

    优点:成本最低,实施简单;

    缺点:受指令集多少和数据集大小的约束。当单个产品或应用过大时,服务响应变慢,无法通过X轴的水平扩展提高速度;

    场景:发展初期,业务复杂度低,需要增加系统容量。

    2.Y轴扩展

    优点:可以解决指令集和数据集的约束,解决代码复杂度问题,可以实现隔离故障,可以提高响应时间,可以使团队聚焦更利于团队成长;

    缺点:成本相对较高;

    场景:业务复杂,数据量大,代码耦合度高,团队规模大。

    3.Z轴扩展

    优点:能解决数据集的约束,降低故障风险,实现渐进交付,可以带来最大的扩展性。

    缺点:成本最昂贵,且不一定能解决指令集的问题;

    场景:用户指数级快速增长。


    如何将理论付诸实践?

    1.为扩展分割应用

    X轴:从单体系统或服务,水平克隆出许多系统,通过负载均衡平均分配请求;

    Y轴 :面向服务分割,基于功能或者服务分割,例如电商网站可以将登陆、搜索、下单等服务进行Y轴的拆分,每一组服务再进行X轴的扩展;

    Z轴 :面向查找分割,基于用户、请求或者数据分割,例如可以将不同产品的SKU分到不同的搜索服务,可以将用户哈希到不同的服务等。

    2.为扩展分割数据库 

    X轴:从单库,水平克隆为多个库上读,一个库写,通过数据库的自我复制实现,要允许一定的读写时延;

    Y轴 :根据不同的信息类型,分割为不同的数据库,即分库,例如产品库,用户库等;

    Z轴 :按照一定算法,进行分片,例如将搜索按照MapReduce的原理进行分片,把SKU的数据按照不同的哈希值进行分片存储,每个分片再进行X轴冗余。

    3.为扩展而缓存

    在理想情况下,处理大流量最好的方法是通过高速缓存来避免处理它。从架构层面看,我们能控制的主要有以下三个层次的缓存:

    对象缓存:对象缓存用来存储应用的对象以供重复使用,一般在系统内部,通过使用应用缓存可以帮助数据库和应用层卸载负载。

    应用缓存:应用缓存包括代理缓存和反向代理缓存,一个在用户端,一个在服务端,目标是提高性能或减少资源的使用量。

    内容交付网络缓存:CDN的总原则是将内容推送到尽可能接近用户终端的地方,通过不同地区使用不同ISP的网关缓存,达到更快的响应时间和对源服务的更少请求。

    4.位扩展而异步

    同步改异步:同步调用,由于调用间的同步依赖关系,有可能会导致雪崩效应,出现一系列的连锁故障,进而导致整个系统出现问题,所以在进行系统设计时,要尽可能的考虑异步调用方式,邮件系统就是一个非常好的异步调用例子。

    应用无状态:当进行AKF扩展立方体的任何一个轴上的扩展时,都要首先解决应用的状态问题,即会话的管理,可以通过避免、集中和分散的方式进行解决。


    AKF扩展立方体是一套通用的扩展性理论,它不仅可以应用到系统的架构扩展上,也可以应用到人员的组织架构扩展上甚至其他相关的工业领域。

    当然并不是所有公司都需要同时在XYZ三个方向上进行扩展,并且每个方向上的扩展都有它的利弊,我们不可避免的要进行适当的权衡。最重要的,我们应当首先理解这套理论背后所体现出来的扩展哲学。

    就像书里所描述的,这不仅涉及到科学,还涉及到艺术!



    作者:张文昭
    链接:https://www.jianshu.com/p/d08d0c14810f
    来源:简书
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
     

    本文节选自《高扩展性网站的 50 条原则》

    本文提出的三个简单原则几乎可以帮你扩展任何东西。虽然扩展系统和平台的方法有很多种,但有了这三个原则,那么在你前进的道路上,就没有什么与扩展相关的障碍了。

    通过克隆进行扩展——通过克隆或复制数据和服务,可以轻松地扩展事务。

    通过拆分不同的东西进行扩展——用名词和动词标识数据和服务,从而进行划分。如果拆分正确,那么事务和数据集都能得到有效扩展。

    通过拆分相近的东西进行扩展——通常拆分的是数据集。把客户划分到专用的独立的数据片或泳道,可以对事务和数据进行扩展。

     
    我们在面试过程中经常会问面试者怎么让我们的应用能够负载更多的请求,能够抗住高并发的请求。其中很多面试者能够离散的回答出很多点,但是很少有人能够用系统的理论去回答这个问题。本文主要是结合AKF理论来讲下我们的应用如何拆分和扩展更加能够理论的去回答这个的问题。

    概念介绍

    AKF 扩展立方体(AKF Scale Cube)是一个描述从单体应用到一个分布式可扩展架构的模型概念

    X轴 Y轴 Z轴 含义

    • X轴:服务和数据的水平复制和克隆
    • Y轴:功能分解和细分(或微服务)业务拆分
    • Z轴:沿客户边界的服务和数据分区-分片/窗格

     

     

    单体应用的问题

    单体应用的问题很明显,单点的节点如果发生异常、更新、down机都将导致整个应用不可用,系统的整体可用性依赖于单点应用的可用性,系统必将非常脆弱。

     

    X轴扩展 - 横向复制

    单点应用的解决方案就是通过X轴来扩展
    服务和数据的水平复制和克隆

    X轴扩展描述了比较简单的扩展方式,又称水平扩展,通过复制节点,实现多个节点同时提供服务,从而大大提高系统的总体容量、解决单点问题等。
    水平扩展是比较理想的扩展方式,一般来说开发难度不大,但增加部署复杂度。这种扩展最为典型的例子

    • web服务的多负载部署,部署多节点,配合nginx来实现反向代理
    • 多级缓存机制 本地内存、文件缓存、分布式缓存(redis、memcached)
    • 数据库的主从复制和读写分离。

    如图中所示常见的X轴扩展的方法

     

     

    Y轴扩展 - 拆分不同的东西

    原来的业务系统可能是一个大而全的单体应用,我们可能把系统里所有的业务逻辑都写在一个大而全的业务数据库中,数据库包括了订单、用户、促销活动、商品、支付等等复杂的业务逻辑。我们经过X轴的拆分,其实可以扩展了系统的服务能力了,也不用担心热点数据访问负担,也不用担心单机机器宕机,但是还存在很多的问题。

    订单创建、商品库存的扣减、支付扣款等数据库的事务逻辑可能很长,那么必然存在数据的事务并发能力带来极大的降低。数据库很可能成为瓶颈,业务日益增长的开发复杂度,这个时候可以通过Y轴来扩展

     

     

    有好几种解耦拆分方式。

    • 一种是按照动词分割
    • 一种是按照名词分割

    以电商网站为例:
    按照动词分割就是按照操作分割

    • 应用1只负责购买流程
    • 应用2只负责售后流程
    • 应用3只负责广告投放流程

    按照名词分割就是按照对象类型分割

    • 应用1只负责商品信息
    • 应用2只负责用户信息
    • 应用3只负责订单信息

    两种扩展经常是同时使用的。微服务化就是Y轴扩展的一个重要方式。

    Y轴扩展从业务层面来考虑扩展方式,因此又称为业务扩展或资源扩展,这点基本上就等同于微服务化。系统从业务层面拆分为多个子系统,各子系统由单独的团队负责整个生命周期的维护,单独部署运行,子系统间具备故障隔离的能力。

    除了业务方式拆分还可以有其他方式来拆分

    Z轴扩展 - 拆分相近的东西

    Z轴扩展一般用来扩展数据库。(数据库分片)在做某些查询的时候,查询指令被送给每一个分片,然后分别查询,最终获得的结果聚合之后返回。

    常见的分片的方式

    • 业务数据按月分表
    • 客户表按照customer_id 用户ID的模数或散列表进行划分

    Y轴用于解决不相似事物的拆分(通常通过名词或动词拆分),而Z轴用于解决“相似”事物的分割。

    数据的拆分需要对业务领域有较高的认识才好处理,拆分的代价相当高,需要引入一系列支持拆分的底层框架,像 sharding-jdbc、mycat 等,在数据层面需要配置相应的分片逻辑。正确的拆分对提高系统的容量有很大的帮助,失败的拆分可能会造成热点集中,得不偿失。

     

    发布于 05-18
     
     

    下面列举一下按三个轴划分的例子

      X轴一般就是负载均衡,比如用F5等硬件设备进行端口轮训负载。

      Y轴主要体现在我们按业务拆分服务,比如登录服务,订单服务等

      Z轴主要是对一些有特殊要求的业务执行单独流程处理,比如按地区提供对应地区客户的服务,根据不同地区不同客户群的生活习惯等进行差异化服务。 

     
    可扩展架构的方法论——AKF 扩展立方体_屑狐狸 - CSDN 博客_akf 扩展立方体
    AKF扩展立方体(Scalability Cube),是《架构即未来》一书中提出的可扩展模型,这个立方体有三个轴线,每个轴线描述扩展性的一个维度,他们分别是产品、流程和团队:
    
    X轴 —— 代表无差别的克隆服务和数据,工作可以很均匀的分散在不同的服务实例上;
    
    Y轴 —— 关注应用中职责的划分,比如数据类型,交易执行类型的划分;
    
    Z轴 —— 关注服务和数据的优先级划分,如分地域划分。

    三个维度扩展的对比

    通过这三个维度上的扩展,可以快速提高产品的扩展能力,适应不同场景下产品的快速增长。不同维度上的扩展,有着不同的优缺点:

    • X 轴扩展

      优点:成本最低,实施简单;
      
       缺点:受指令集多少和数据集大小的约束。当单个产品或应用过大时,服务响应变慢,无法通过X轴的水平扩展提高速度;
      
       场景:发展初期,业务复杂度低,需要增加系统容量。
    • Y 轴扩展

      优点:可以解决指令集和数据集的约束,解决代码复杂度问题,可以实现隔离故障,可以提高响应时间,可以使团队聚焦更利于团队成长;
      
       缺点:成本相对较高;
      
       场景:业务复杂,数据量大,代码耦合度高,团队规模大。
    • Z 轴扩展

      优点:能解决数据集的约束,降低故障风险,实现渐进交付,可以带来最大的扩展性。
      
       缺点:成本最昂贵,且不一定能解决指令集的问题;
      
       场景:用户指数级快速增长。

    如何将理论付诸实践?

    • 为扩展分割应用

      X轴:从单体系统或服务,水平克隆出许多系统,通过负载均衡平均分配请求;
      
       Y轴 :面向服务分割,基于功能或者服务分割,例如电商网站可以将登陆、搜索、下单等服务进行Y轴的拆分,每一组服务再进行X轴的扩展;
      
       Z轴 :面向查找分割,基于用户、请求或者数据分割,例如可以将不同产品的SKU分到不同的搜索服务,可以将用户哈希到不同的服务等。
    • 为扩展分割数据库

      X轴:从单库,水平克隆为多个库上读,一个库写,通过数据库的自我复制实现,要允许一定的读写时延;
      
       Y轴 :根据不同的信息类型,分割为不同的数据库,即分库,例如产品库,用户库等;
      
       Z轴 :按照一定算法,进行分片,例如将搜索按照MapReduce的原理进行分片,把SKU的数据按照不同的哈希值进行分片存储,每个分片再进行X轴冗余。
    • 为扩展而缓存

      在理想情况下,处理大流量最好的方法是通过高速缓存来避免处理它。从架构层面看,我们能控制的主要有以下三个层次的缓存:
       
       对象缓存:对象缓存用来存储应用的对象以供重复使用,一般在系统内部,通过使用应用缓存可以帮助数据库和应用层卸载负载。
       
       应用缓存:应用缓存包括代理缓存和反向代理缓存,一个在用户端,一个在服务端,目标是提高性能或减少资源的使用量。
       
       内容交付网络缓存:CDN的总原则是将内容推送到尽可能接近用户终端的地方,通过不同地区使用不同ISP的网关缓存,达到更快的响应时间和对源服务的更少请求。
    • 位扩展而异步

      同步改异步:同步调用,由于调用间的同步依赖关系,有可能会导致雪崩效应,出现一系列的连锁故障,进而导致整个系统出现问题,所以在进行系统设计时,要尽可能的考虑异步调用方式,邮件系统就是一个非常好的异步调用例子。
       
       应用无状态:当进行AKF扩展立方体的任何一个轴上的扩展时,都要首先解决应用的状态问题,即会话的管理,可以通过避免、集中和分散的方式进行解决。
       
       AKF扩展立方体是一套通用的扩展性理论,它不仅可以应用到系统的架构扩展上,也可以应用到人员的组织架构扩展上甚至其他相关的工业领域。
      
       当然并不是所有公司都需要同时在XYZ三个方向上进行扩展,并且每个方向上的扩展都有它的利弊,我们不可避免的要进行适当的权衡。最重要的,我们应当首先理解这套理论背后所体现出来的扩展哲学。
      
       就像书里所描述的,这不仅涉及到科学,还涉及到艺术!
     

    AKF 扩展立方体

    AKF 扩展立方体(AKF Scale Cube)是一个描述从单体应用到可扩展架构的模型,见 (https://akfpartners.com/growth-blog/scale-cube)[https://akfpartners.com/growth-blog/scale-cube]。这个模型在 Scalability Rules (架构真经)一书中进行了描述。

    AKF 扩展立方体把单体应用扩展到可扩展架构的方式的过程划分为3个正交维度:

    x 轴:水平复制
    y 轴:业务拆分
    z 轴:数据分片
    

    这 3 个维度描述了从单体到可扩展架构的方法,在实践中有比较大的作用,x、y、z组合而成的向量大小正是系统的扩展性。

    x 轴扩展

    x 轴扩展描述了比较简单的扩展方式,又称水平扩展,通过复制节点,实现多个节点同时提供服务,从而大大提高系统的总体容量、解决单点问题等。

    水平扩展是比较理想的扩展方式,一般来说开发难度不大,但增加部署复杂度。这种扩展最为典型的例子是数据库的主从复制和读写分离。

    典型的 web 应用读写比例非常悬殊,通常是 10:1100:1 甚至是 1000:1 ,因此需要更多的资源来支持读操作。同时,从数据的时效性上看,大部分数据并不需要非常高的实时性,3、5s 的少量的延迟往往是可被接受的。从数据的访问频率上看,基本上数据会遵守局部性法则(8020 法则),即大部分访问都是访问热点数据。从这些业务上的特点出发,往往有 2 类的手段来进行数据层面上的优化:加缓存、复制节点读写分离。

    加缓存是非常有效的优化手段。数据库本身也带有缓存,像 mysql 的 innodb_buffer_pool ,用提高响应速度,除此之外,还可以:

    本地内存、文件缓存,如 ehcache
    中央缓存,如 redis / memcached
    

    既然有缓存,就有缓存的有效性、有效时间,就会有缓存相关的问题,包括:

    缓存穿透,用不存在的 id 访问系统,达成攻击
    缓存击穿,特别的热的某个数据失效,所有的流量瞬间到了后端
    缓存雪崩,某个时间缓存批量失效,所有流量到后端
    

    读写分离通过加强基础设施的容量进行扩展。大部分的数据库,mysql、oracle、sqlserver 会支持某种主从备份(甚至是双主),这使得在基础设施层面能实施非常有效的扩展。以 mysql 为例,可把事务型的sql 放到主库执行,简单查询型的 sql 分布到多个从库读取数据,这一下子就把原来的负载分配到了几个数据库实例来承担,容量放大 n 倍。这种方式需要实现上做一些改动,在数据库访问层上需要支持某种形式的 sql 路由,而这些在成熟的 orm 、sqlmap 框架都已经提供,可看对应的 mybaits、hibernate 等文档。

    当然 x 轴扩展不单只是加缓存或读写分离,像 dns 负载均衡、多接入服务器等都是 x 轴扩展方法。

    y 轴扩展

    y 轴扩展从业务层面来考虑扩展方式,因此又称为业务扩展或资源扩展,这点基本上就等同于微服务化。系统从业务层面拆分为多个子系统,各子系统由单独的团队负责整个生命周期的维护,单独部署运行,子系统间具备故障隔离的能力。

    拆分的方式有水平的拆分和垂直拆分。垂直拆分是把接入、前端、安全、监控等不同技术层面的组件进行拆分,让各组件更加专注于自己的工作,体现在结构图上就是在垂直方向上进行了划分;水平拆分是按照不同的业务线,各业务线拆分开来,结构图上是按照水平方向上进行划分。y 轴的扩展更多是水平拆分这种方式。

    每个子系统拥有自己的运行资源,可以有针对性地采用更加激进的优化手段。像与文档相关的子系统,可以减少使用关系式数据库,转而采用对分布式支持更好的文档型数据库,进行热点预测,对热点数据提前进行预处理等等。

    拆分子系统后,通常数据库要进行拆分(分库)。分库带来了事务处理能力的直接提升,对于高事务型应用,可在数据库层面用一些比较高的配置,非事务型应用使用低点的配置,使得整体的运行成本更加合理,让好钢用到刀刃处。

    需要注意的是,分库将无可避免地导致需要使用分布式事务。典型的分布式事务模式,目前常见的有数据库自带的 XA,java 中的 JTA,TCC,支持长时间业务的 Saga 等。这里给一个警告,尽可能避免分布式事务,目前并没有 100% 可靠而又高效的分布式事务解决方案。因此在进行 y 轴扩展拆分时,一个很有效的方法是事务应该尽量集中在子系统中,只有必须无可避免的时候才采用分布式事务,同时对分布式事务必须使用先写 undo_log 日志,以便在必要时进行自动甚至人工恢复。

    拆分后同时带来了跨业务集成的问题。在《微服务设计》书中提到有两种风格的集成方式:请求响应、事件。请求响应有 RPC、REST方式,事件式可用各种消息队列(kafka、rabbitmq、activemq)等进行事件消息传递(openstack 里面的集成方式比较有意思,采用事件队列来进行 RPC)。

    y 轴扩展需要比 x 轴扩展花费更多的精力,从开发、运维甚至组织架构都需要做出相应的调整。大家熟知的康威定律,系统的架构反映了组织的沟通结构,以技术至上的角度来实现 y 轴扩展,到头来只会让业务层面无法适应新系统而导致效率低下。

    z 轴扩展

    z 轴扩展是基于数据集本身的特性来进行扩展的方式,也即数据分片,在实践中,就是分表了。

    对于关系型数据库而言,拆分数据意味着需要进行反模式的设计,依赖于数据库自身机制的完整性约束(主键、外键、域、唯一性)的设计也需要拆开。

    数据的拆分需要对业务领域有较高的认识才好处理,拆分的代价相当高,需要引入一系列支持拆分的底层框架,像 sharding-jdbc、mycat 等,在数据层面需要配置相应的分片逻辑。正确的拆分对提高系统的容量有很大的帮助,失败的拆分可能会造成热点集中,得不偿失。

    数据拆分可以和业务扩展共同使用,让业务跑在部分的数据上,实现故障隔离。在升级时,先对小范围进行升级,在出错时小范围的数据更加容易修复,待验证之后再进行整个系统层面的升级,这种控制范围的灰度发布在实践中非常实用,在各种云平台、 k8s 上都可以实现。

    最后...

    所有的扩展都会带了复杂度、成本提升的代价,要视业务的真正需要来进行扩展设计,避免过度的扩展

    通常来说,在设计阶段要设计 10 到 100 倍左右的逻辑容量,因为在后期修改设计会带来很高的难度,所以要提前设计好冗余容量。在实现阶段,通常要按照 5 到 10 倍左右的容量进行实现,实现阶段需要付出一定的成本,没有必要为非常长远的将来实现,可以随业务的进展而逐步实现设计时最大容量。部署阶段,以 2 到 5 倍的容量进行部署,可以应付一段时间内的容量增长,但如果是预期的增长非常大,就要采用更加灵活的云部署手段,并为突发峰值做好预案准备。

     

    《THE ART OF SCALABILITY》中描述了一个非常有用的扩展模型:扩展立方(也叫AKF扩展立方)。
    这个模型把应用比作立方体,为了支持应用的发展和演进,我们可以通过x,y,z三个方向对它进行扩展。

    X轴扩展

    在负载均衡之后运行应用的多个拷贝。这是最简单最常用的扩展方式。

    缺陷:

    • 每个拷贝需要访问所有的数据,对缓存机制要求很高,数据库很可能成为瓶颈。
    • 不会减少日益增长的开发复杂度。

    Y轴扩展

    把整个应用切分为不同的服务,每个服务负责一个或少量几个关系相近的函数。

    有好几种解耦拆分方式。一种是按照动词分割,一种是按照名词分割。

    以购物网站为例:按照动词分割就是按照操作分割,服务1只负责购买流程,服务2只负责售后流程,服务3只负责广告投放流程;
    按照名词分割就是按照对象类型分割,服务1只负责商品信息;服务2只负责用户信息。

    两种扩展经常是同时使用的!

    微服务化就是Y轴扩展的一个重要方式。

    Z轴扩展

    Z轴扩展和X轴扩展很像,但是在Z轴扩展中,每个服务只跑特定的一部分代码或数据集。

    Z轴扩展一般用来扩展数据库。(数据库分片)
    在做某些查询的时候,查询指令被送给每一个分片,然后分别查询,最终获得的结果聚合之后返回。
    做写入的时候,只需要按照分片键,找到对应的实例进行写入即可。

    Z轴扩展的优势:

    • 每个服务器只处理一部分数据
    • 优化了缓存的利用率,减少内存使用和I/O
    • 增强了事务的扩展性
    • 故障隔离

    劣势:

    • 增加了整体的复杂度。
    • 需要实现分片机制。万一有重新分片的需求的话,令人头大。
    • 增加复杂度的同事,并没有降低开发的复杂度,这个需要Y轴扩展配合解决。

    参考:
    The Scale Cube | Microservice Architecture

     
     

    有赞订单搜索AKF架构演进之路

    文 | 王爷 on 交易

    一、前情提要

    时节如流,两年前的今天写了有赞订单管理的三生三世与十面埋伏,转眼两年过去了,这套架构发展的如何,遇到了什么新的挑战和收获,今天主要来一起整理回顾下有赞订单搜索AKF架构演进之路。

    之前将散落在 DB 多个分片中的数据在 ES 做了一次聚合,带来了巨大的好处,同步任务少,维护成本低。尤其是订单迁移这一块,之前由于是分片设计,所以当订单触发迁移时候,需要将数据插入新分片,确认无误后还需要删除老分片数据,流程繁琐易错,统一收拢后对于 ES 来说,各个端订单迁移,都只是一次更新操作,无比简单。补充介绍下订单迁移:

    • 买家订单迁移 针对新用户转变为关注用户,从系统 mock 的 buyerId 到真正分配的 buyerId 订单的迁移。
    • 卖家订单迁移 针对店铺模型升级,比如从微商城到零售连锁,原门店独立需要迁移订单。

    二、新的挑战

    然而随着业务的不断发展,聚合后的索引也开始暴露各种问题。

    • 数据量增长比预期要快很多,亿级别的索引,慢查也开始出现,像一个庞然大物蠢蠢欲动。
    • 为了满足商家的一些个性搜索需求,很多搜索需求都属于极少数会查询到的,但是都会被加到同一个主索引中,使得主索引字段不断增多。

    三、应对

    3.1 合久必分

    为了解决以上挑战,踏上了可扩展性架构拆分之路。简单介绍下有赞订单搜索的几个维度:

    • B 端商家单店搜索(商家管理单店订单)
    • B 端商家总店跨分店搜索(连锁总店管理分店订单)
    • C 端买家跨店铺搜索(买家管理跨店所有订单)

    由于既要 ToB 又要 ToC ,而 B 端零售连锁商家的引入,增加了不少复杂度,因为有总店 MU 来管理多个 BU 单元,需要跨多个店铺查询。无论怎么分片,单一维度都必然存在跨分片搜索的场景。计划优先按数据冷热分离来拆分,而如何区分和定义这个冷热数据?最近一天,一月,一段时间的搜索,都比较范,缺乏数据支撑。

    念念不忘,必有回响。

    3.1.1 热状态索引

    于是观察了下我们的监控,发现了奇妙的规律。所有搜索场景中,常见的按支付方式,物流类型,商品名称,订单类型等搜索占比很少,而按订单状态搜索占比最多,约 53% ,也就是一半多的搜索流量全部来自于订单状态检索。

    而细化了下这 53% 的订单状态搜索中,其中 3% 左右搜索终态订单(已完成,已关闭),其中 50% 所有流量全部都是搜热状态订单(待付款,待发货,待成团,待接单,已发货),-_- 忽略比较乱的枚举,历史多个版本统计合一。

    不禁让人兴奋,为什么?因为无论订单量如何激增,处于热状态的订单数不会持续暴增,因为所有订单都会陆续流转到终态,比如超时 30 分钟未付款,订单从待支付变成已关闭状态,比如订单发货 7 天后,从已发货状态变成已完成。统计了下,热状态订单总量在千万级别,且一直比较平稳的进行流转。

    也就是说我们用这个千万级小索引,就承接了整个订单搜索一半左右的流量。无论是统计,总店查询,各种跨分片维度查询,都可以支持。因为它是一个热状态订单数据全集,包含所有分片场景,无比兴奋。目前该索引已在线上平稳运行近一年。

    3.1.2 时间分片索引

    那么对于那些终态订单,数据量随着订单状态流转会变得越来越大,如何扩展,时间分片是个不错的选择,有赞订单搜索早期最早做的切分就是按下单时间分片,之前业务数据量小,每半年一个,到后来发展改成了每 3 个月一个,到现在即使每一个月一个索引都显得有些庞大。具体还是要结合搜索场景,理论上终态订单检索的量比较小,也可以换个思维从产品层面有个引导,比如默认只展示最近半年订单,也是一种思路。

    3.2 扩展依据

    3.2.1 AKF 扩展立方体

    在《架构即未来》与《架构真经》中都反复提到这个立方体,结合我们的实际情况,确实受益匪浅,给了我们指引的方法论。

    X 轴 : 关注水平的数据和服务克隆,比如主备集群,数据完全一样复制。克隆多个系统(加机器)负载均衡分配请求。

    • 优点:成本最低,实施简单
    • 缺点:当个产品过大时,服务响应变慢
    • 场景:发展初期,业务复杂度低,需要增加系统容量

    Y 轴 : 关注应用中职责的划分,比如数据业务维度拆分。比如交易库,商品库,会员库拆分。

    • 优点:故障隔离,提高响应时间,更聚焦
    • 缺点:成本相对较高
    • 场景:业务复杂,数据量大,代码耦合度高,团队规模大

    Z 轴 : 关注服务和数据的优先级划分,数据用户维度拆分。比如常见的按用户维度买卖家切分数据分片。

    • 优点:降低故障风险,影响范围可控,可以带来更大的扩展性
    • 缺点:成本最高
    • 场景:用户指数级快速增长

    上面介绍的热状态订单拆分其实就是朝 Y 轴方向扩展,当然 AKF 可扩展立方体的精髓就在于不要一直只在一个轴方向上扩展,要根据不同的业务场景,数据规模,做到有针对性的扩展,理论上 XYZ 轴可以做到某种程度的无限扩展。目前有赞订单搜索的总体索引架构如下,涵盖 3 个轴方向。

    3.3 现状

     

    四、收获

    上面简单介绍了下有赞订单搜索 AKF 扩展之路,下面再简单聊下过程中的几个意外收获,受益良多,可以给类似业务同学一个可以尝试的参考。

    4.1 可扩展性索引字段设计

    之前迁移到 ES 里就是看中 ES 的多索引检索能力,然而多变的产品需求通过不断加字段的模式,也会使索引变得越来越大,不好维护,有没有一种可扩展性的方式,来以不变或者以小变应对需求的万变呢。答案是肯定的,list< String > 字段设计,比如目前开放了搜索扩展点给有赞云,商家可以自定义的建立自己的检索字段,K 和 V 都有商家自己把控,如何做到代码可配置化,业务代码无感知呢,按照我们的约定需要检索的字段进入 list< k_v > 格式,即可做到。关于细节订单管理系列博文之可配置化订单搜索博文中会详细进一步介绍。

    4.2 轻量级统计

    统计一直是各大公司比较重要的一块,有赞也是,几乎有订单的地方都会看到各种订单数统计,早期统计场景比较简单,比如统计待发货,已发货,退款订单等都可以通过一个 sql 或者一个脚本任务就可以统计出来,但是随着有赞业务发展的越来越快,比如统计一个加入担保交易+已经完成7天内+发生退款的订单数,普通的统计模式通过更改统计 sql ,再刷个离线数据也是能做到的,但是周期往往较长,而且不够灵活,一旦有部分统计失败报错的,排查问题很困难,只能再全量重新统计。而这里我们采用了另一种视角,用搜索来做统计,依赖于ES搜索默认返回的 total 作为统计值,可以无缝利用现有数据做任意维度任意组合的任意统计,随时提需求,即用即拿,非常轻量。关于细节也会在订单管理系列博文之配置化订单统计博文中会做详细进一步介绍。

     

     

      

     

     

     

     

     

     

     

     

     

     

     

     

      

     

     

     

     

     

     

     

     

     

     

     

     

  • 相关阅读:
    Sketch 画原型比 Axure 好用吗?为什么?
    ps高级磨皮的7个步骤
    算法竞赛入门经典_第二章:循环结构程序设计_上机练习_MyAnswer
    文件操作 & 重定向
    阶乘之和 & 程序运行时间 & 算法分析
    《数据结构与算法分析:C语言描述_原书第二版》CH3表、栈和队列_reading notes
    TIJ——Chapter Two:Everything Is an Object
    LeetCode Reverse Linked List
    LeetCode Contains Duplicate
    LeetCode Contains Duplicate II
  • 原文地址:https://www.cnblogs.com/cx2016/p/13285336.html
Copyright © 2020-2023  润新知