业务系统优化过程

2018/04/04 系统优化

项目背景

  1. 公司在淘宝有旗舰店(以下简称『淘宝店』)
  2. 公司有自己的官网网上商城(以下简称『官网』)
  3. 淘宝店跟官网数据不能实时互通,只能是 T+1 日将淘宝订单数据导入官网,供用户查询
  4. 淘宝店平时日订单数在一千万笔内,订单数据会在下午一点左右给到官网
  5. 每年『双十一』期间,日订单数在一亿左右。订单数据会在次日下午五点左右给到官网
  6. 为了数据能够及时导入,需要对双十一的订单数据单独优化

日常数据导入介绍

  1. 淘宝店的数据大体分为四个模块
    • 买家数据。该数据里只有新买家的信息,老买家默认已经导入到官网系统
    • 订单数据。该数据是核心交易信息,谁在何时买了什么
    • 费用数据。该数据是收款和退款信息,收到哪个用户多少钱,退了哪个用户多少钱
    • 退货数据。该数据是退货的详细信息,哪个用户申请了退货,退货进度到哪儿了
  2. 四个模块中,买家数据跟退货数据比较少,订单和费用的数据比较多
  3. 日常导入 TPS = 700
  4. 处理流程图 image

优化过程

加机器

优化问题,首先想到的就是加机器。『加人』对于项目来说虽然不是银弹,『加机器』理论上来说却是的。
但是不能一开始就寄希望于加机器,原因有两点:

  1. 数据库连接数是一定的,应用机器数量就有了上限
  2. 加机器有效之后,开发人员会失去优化代码动力。如果上线当天出现别的问题,没有快速有效的解决方案

查找性能优化点

使用 AOP 设置切面,统计调优相关所有方法的执行频率和执行时间

优化业务流程

  1. 找到执行频率高或者执行时间长的代码
  2. 看能否业务流程上优化
    • 因为历史原因,淘宝店数据跟官网数据走的同一个流程,所以为了适配两者逻辑,代码都纠缠到一起。要拆开
    • 相同判断在多个 service 做了,service 互相调用就会重复校验
    • 不同产品校验逻辑不同,拆开分别校验
    • 梳理业务流程,该删删该减减
  3. 逻辑下放,将部分校验逻辑从数据处理引擎迁移到入库系统中,减小入库系统负载

本地缓存

应用机器内存使用率不高,有些高频数据小量数据可以使用本地缓存

  1. 增值税缓存

    计算增值税 BigDecimal,效率不高。考虑到淘宝店产品不多,没有必要每次都计算一次增值税。把每个产品的增值税缓存

  2. 产品信息缓存

    订单、费用、退货模块都会去查询产品相关信息,产品信息可以缓存

异步线程池

应用机器 CPU 使用率也不高,可以考虑使用异步线程池接收数据引擎过来的请求

  • 数据引擎跟入库系统使用的是 HSF 同步调用的方式,以便获取数据入库的实时处理结果
  • 每台机器的 HSF 连接数是固定的,如果数据处理速度不高,会导致 HSF 连接打满,进而数据引擎被阻塞,无法发挥最大作用

考虑到双十一期间数据处理都是受到监控,因此在数据过来时,使用线程池异步处理,既可以规避 HSF 连接不够的问题,又能提高机器的 CPU 使用率
线程池方案:

  1. 核心线程:150
  2. 最大线程:150
  3. 队列长度:3W
  4. 拒绝策略:同步(CallerRunsPolicy)

完善监控

  1. 采集每台机器的内存、CPU信息
  2. 采集每台机器的线程数和队列阻塞情况
  3. 根据机器的状况实时调整线程数

分布式缓存

  1. 有些订单之间会有关联,子订单入库时会去查找父订单,为减小查询次数,父订单入库时异步存入缓存
  2. 费用数据入库前会查询订单数据,为减小查询次数,将订单数据异步存入缓存

热点数据

淘宝店数据进来时,按模块划分为 4 个数据文件,但是同一个文件中数据是无序的。
数据刚开始入库时,因为缓存中并没有数据,所以处理很慢,容易将线程队列打满,继而将 HSF 连接池打满。
可以在书库入库前,做一次清理,将热点数据(比如父订单)先以一个较小的并发执行,等待跑完后再用较大的并发集中跑剩下数据

Search

    欢迎关注我的微信公众号

    Bishion

    Table of Contents