有赞业务对帐平台的探索与实践

1、引子

根据CAP原理,分布式系统没法在保证了可用性(Availability)和分区容忍性(Partition)以后,继续保证一致性(Consistency)。咱们认为,只要存在网络调用,就会存在调用失败的可能,系统之间必然存在着长或短的不一致状态。在服务化流行的今天,怎样及时发现系统服务间的不一致状态,以及怎样去量化衡量一个系统的数据一致性,成为每一个分布式环境下的开发者须要考虑并解决的问题。spring

2、背景

以交易链路为例,存在着以下一些潜在的不一致场景:服务器

  • 订单支付成功了,可是订单状态却仍是“待付款”
  • 物流已经发货了,可是订单上面仍是“待发货”
  • 银行退款已经到帐了,可是订单上面仍是“退款中”
  • 订单发货已经超过7天了,可是却没有自动完成

上述每一个业务场景,均可能产生用户反馈,给用户带来困扰。业务对帐平台的核心目的,就是及时发现相似问题,并及时修复。使问题在反馈前即被提早处理。网络

3、挑战

那么一个业务对帐平台,会面临着哪些挑战?架构

图片描述

咱们对于一个业务对帐平台的核心诉求,主要包括要方便业务系统快速接入,要能处理业务方海量的数据,并保证必定的实时性。这会深入影响业务对帐平台的系统设计。并发

4、架构

从局部到总体,本文先从解决上面三个问题的角度,来看有赞业务对帐平台的局部设计,再来看总体系统结构。异步

4.1 易于接入

咱们认为全部的对帐流程,均可以分解为“数据加载”、“转换解析”、“对比”、“结果处理”这 4 步。为了适应多样化的业务场景,其中的每一步都须要作到可编排,放置各类差别化的执行组件。在每个流程节点,须要经过规则能够自由选择嵌入哪一个组件。其次,须要把数据从原始格式,转换到对帐的标准格式(基于标准格式,就能作标准的通用对比器)。总结起来,咱们认为对帐引擎须要具有如下的能力:分布式

  • 流程编排能力
  • 规则能力
  • 插件化接入能力

目前业务对帐平台的对帐引擎结构以下:高并发

图片描述

其中的 ResourceLoader 、 Parser 、 Checker 、 ResultHandler 均为标准接口,全部实现了对应接口的 spring bean ,都能被编排到对帐流程之中,包括业务方本身实现的 plugin。这样就实现了插件化和可编排。每一个流程节点的功能以下:工具

  • ResourceLoader :基于各类数据源(DB、FILE、RPC、REST等)提供加载器工厂,加载各个数据源的原始数据。加载的方式支持驱动加载、并行加载、多方加载等方式。业务方也能够本身实现加载器,利用流程编排能力嵌入到对帐流程中。
  • Parser :对已加载的原始数据进行建模,转换为对帐标准模型。利用规则引擎,提供脚本化(Groovy)的转换方式。
  • Checker :按照配置对指定字段、按指定规则进行比较,并产生对帐结果。支持 findFirst(找出第一个不一致)、full(找出全部不一致)等对比策略。
  • ResultHandler :使用指定的handler对结果进行处理,常见的处理器包括持久化、发送报警邮件、甚至直接修复数据等等。

经过统一的 facade,将整个对帐流程进行串联。在执行不一样节点时,根据配置选择不一样的默认组件或者插件来执行。能够在管理后台,对每一个流程节点进行编排:大数据

图片描述

4.2 高吞吐量

一些离线定时对帐场景,单次对帐的数据量可能达到百万级,甚至千万级。这对对帐平台的吞吐量形成了挑战。咱们面对海量数据问题的一般解决思路,就是“拆”。分布式任务拆分+单机内任务拆分,将数据块变小。同时,也能够利用一些大数据的工具来帮咱们减轻负担。

图片描述

目前的对帐有 2 种模式:一种常规模式,是经过数据平台(包含了全部要进行对帐的原始主键数据,如订单号)将数据 push 到对帐中心的 DB ,而后订单中心集群经过分片策略,并按分页分批加载,加载数据进行对比。另外一种,则是当数据量超过千万时,利用数据平台的 spark 引擎从 hive 表中获取数据,而后投递到 nsq(自研消息队列)。nsq 会选择其中一个 consumer 进行投递(不会投递到多个consumer)。这样千万级的数据会变成消息被分散的对帐服务器执行。

对帐任务通常会选择在业务量较小的凌晨进行,是由于在对帐过程当中会须要经过反查业务接口,来获取实时数据。而更好的状况是,对帐时能去除对业务接口的反查。所以,会须要对业务数据进行准实时同步,提早进入对帐中心的 DB 集群。

图片描述

主要思路是基于业务 DB 的 binlog 日志或者业务系统自身的消息,进行数据同步。后续流程则相似。

4.3 高实时性

一些特定的业务场景,好比买家已经付款成功了,可是因为银行第三方的支付状态回调延迟,致使订单状态仍是待付款。这种状况,买家会比较焦急,可能产生投诉。面对这样一些场景,就须要进行实时对帐,也能够叫作秒级对帐。

秒级对帐每每基于业务消息进行触发,须要在事件触发后的短期内执行完对帐任务。且事件消息的触发,每每具备高并发的特色,所以须要相应的架构来进行支持。

图片描述

设计中主要加入了 EventPool 来缓冲处理高并发的事件消息,并加入限流、取样、路由、处理的 pipeline。同时在进入事件处理线程池以前,须要进入阻塞队列,避免大量的请求直接耗尽线程资源,同时实现事件处理的异步化。处理线程批量定时从阻塞队列获取任务来执行。同时,利用延迟阻塞队列,还能够实现延迟对帐的特性。(咱们认为出现不一致的状况时,若是当即去进行对比,每每仍是不一致的。因此就须要根据状况,在事件发生后的一段时间内,再触发对比)

4.4 总体设计

上面介绍了业务对帐平台的各个局部设计,下面来看下总体结构。

图片描述

总体上主要采用调度层+对帐引擎(core+plugin)+基础设施的分层架构。调度层主要负责任务触发、任务拆分、调度;对帐引擎则负责执行可编排的对帐流程;基础设置层则提供规则引擎、流程引擎、泛化调用、监控等基础能力。

5、健康度

对帐中心能够拿到业务系统及其所在整个链路的数据一致性信息。基于此,对帐平台具有了给予业务系统和链路健康度反馈的能力。

图片描述

6、共建

前面有提到,对帐的流程被拆分为四个固定的流程节点,且有四个对应的标准接口。经过流程引擎和规则引擎的能力,能够根据 spring bean name,来将系统默认组件或者插件编排到对帐流程之中。基于这种开放性的设计,业务对帐平台支持与业务团队进行共建。

首先,对帐平台提供标准接口的 API jar 包,业务方经过引入 jar,实现相关接口,并将 impl 打包。这样,对帐平台经过 spi 的方式,能够引入业务方的插件包,并加载到对帐中心的 JVM 中执行。

7、将来

业务对帐平台,是面向业务场景创建,但同时属于数据密集型应用。平台上线以来,已经接入公司各团队数十个对帐任务,天天处理千万级的数据。展望将来,业务对帐平台的使命会从主要进行离线数据分析处理,演进到利用应用系统的健康度数据帮助系统进行实时调整的方向。在分布式环境下,没有人能回避数据一致性问题,咱们对此充满着敬畏。欢迎联系 zhangchaoyue@youzan.com,交流心得。

图片描述

相关文章
相关标签/搜索