开篇介绍
本篇将分享,算法测试同学在数据质量和接口语义监控领域,遇到的问题与挑战。他们如何通过搭建功能业务监控平台,来建立数据质量与接口语义监控的能力,最终取得了哪些实践结果?其他业务线的开发&测试同学,如何来共享共建数据质量与接口语义监控的能力?
背景介绍
业务特点
对数据质量强依赖
算法业务的一大特点是对数据质量有强依赖,业界有一句话就体现了这一点:“数据和特征决定了机器学习的上限,而模型和算法只是逼近这个上限而已”。
比如,下图的算法模型上线流程图中可以看出,在模型训练阶段,需要借助大量的离线数据&特征数据,对模型进行训练,如果数据质量出现偏差,则训练出来的模型,在线上预测中,必然会出现结果失真的问题。而在模型线上预测的过程中,同样依赖实时和离线的数据&特征来作为预测的依据,如果有数据质量问题,则预测结果同样无法满足业务要求。
再比如,下图的哈啰地图数据ETL过程图,从图中可以看出,哈啰地图数据,需要经过采集(采购数据),清洗(初筛和精筛的过程),融合(多份数据聚合),加载(将数据存储到ES中),最后通过SOA服务,对外提供地图数据的查询能力。在这一系列复杂的ETL处理过程中,任何一个环节出现数据质量问题,都会导致线上业务数据异常。
对外部服务强依赖
算法业务的另一个特点是对外部服务强依赖,从下图智能客服系统架构图中可以看出,该系统对内,依赖营销平台,交易平台,支付平台,账户平台和风控中心。对外,依赖语音转换服务(智能IVR服务),热线服务(合力),支付宝。任何一个依赖服务出现异常,都会对智能客服系统的业务流程造成影响。
问题介绍
换电调度
场景
场景一:换电运维同学反馈,站点存在大量的缺电车辆,但是换电调度算法,并没有推送换电任务出来;
场景二:换电运维同学反馈,接收到换电任务,到站点后发现,车辆并不缺电;
数据处理流程
在进行问题原因分析之前,我们先了解下,实时数仓的数据处理流程。如下图所示,各种数据,如app埋点,binlog,IOT数据,通过接入系统发送kafka消息给数仓的Flink服务进行数据处理,最终数据存储到ES中,供各个业务方调用。
原因分析
结合上图的数据处理流程图,对问题场景进行分析,原因如下:
原因一:由于数仓Flink消息处理压力过大,导致消息消费堆积,产生数据更新延迟的问题,最终使得业务方无法获得最新的车辆电量数据,因此才出现站点有大量的缺电车,却没有换电任务推送的情况。
原因二:由于数仓Flink根据不同的电池类型,如一代车591,二代车371,三代车668,有桩车663等,来区分处理电量数据,而由于376开头的车辆不在代码处理逻辑列表中,导致该类车型的电量默认为0。因此才出现,算法判断376的车辆缺电,推送换电任务给运维同学,而实际站点上376的车辆并不缺电的情况。
线下测试难点
我认为,这些场景,在线下测试的难点主要在成本高:
- 需要有专门的性能测试;
- 测试场景异常庞大,比如车辆数据涉及到10个消息Topic,每个Topic内又有各种子字段和子逻辑,测试场景组合后非常庞大。同时消息字段会灵活调整,需要随时跟踪变化进行测试;
- 测试环境数据不完整,导致无法在测试环境模拟足够丰富的测试数据验证Flink的各种场景
站点数据更新
场景
运维反馈站点数据更新不及时,比如站点名称,经纬度,容量等基础信息出现错误
数据处理流程
站点数据的更新流程,如下图所示,站点的区域治理和标签管理数据,分别通过APP和PC两个途径,更新到绿洲的服务中,绿洲再通过发送MQ消息,将数据更新内容同步给其他外部处理的服务,如电池服务。电池服务消费MQ消息进行二次处理,将数据更新到本地后,即可对业务方提供SOA调用服务。在这个流程中,MQ消息推送&消费环节,电池服务数据二次处理环节,都可能导致数据异常。
原因分析
结合上图的数据处理流程,导致该问题场景的原因主要是MQ消息未正常推送导致的数据差异。如:
原因一:当APP端更新站点时,同时调用更新标签和更新站点的接口,当更新标签接口先调用,则会导致服务不发送MQ消息,从而导致电池服务无法接收到数据变更的通知,因此出现运维反馈站点数据未更新的问题。(该问题已修复)
原因二:是流程问题,之前的老流程是1. 更新mongoDB,2. 查询mongoDB数据是否更新成功,3. 发送MQ通知。该流程的问题是,mongoDB存在主从设计,数据写入主节点后,再完成从节点的数据同步,存在时间差。当出现数据写主节点完成,在从节点查询不到更新的数据时,会导致MQ消息不发送,从而出现数据延迟的情况。因此将数据处理流程变更为:1. 更新mongoDB,2.发送MQ通知。(该问题已修复)
线下测试难点
这个场景,在线下测试的难点主要在异常场景难覆盖全面,对测试人员的能力和经验要求较高。
数据一致性
场景
资产的测试同学反馈,如何保障数据同步过程中的一致性和时效性?
数据同步流程
资产数据的同步流程,如下图所示,资产数据落库(DB)后,需要实时将更新的数据,同步到ES中,由ES对外提供SOA的查询服务。在这个同步流程中,1. 我们如何确保每日万级,百万级的数据变更,都能够被正确的由DB同步到ES中?2. 如何实时监控同步服务的可靠性?在同步服务出现问题的时候,能够快速告警,及时止损?
依赖服务可靠性
场景
客服同学偶尔会投诉,无法看到用户录音转换的文字或转换的文字不正确
服务依赖
从ASR服务的依赖架构图可知,ASR对平安的语音转文本服务,是服务系统的内部调用,并非通过接口访问的方式获取,因此我们无法通过接口状态码和接口响应时长等方式来监控。同时业务场景中,本身就存在语音无法转换成文字的正常场景,因此也无法直接通过判断接口响应的内容为空这种方式来直接判断服务是否不可用。因此需要引入语义分析的方式:“通过特定的输入设计,对响应的结果做验证”,才能有效的判断服务的可用性。
结论
基于数据质量与外部服务对算法业务的重要性,以及上述问题暴露的场景,迫使我们需要建设数据质量监控和接口语义监控的能力。
下图是线上监控系统的分层图,从QA层面,主要侧重于与业务场景强相关,关注业务逻辑正确性的监控维度,这个维度统称为功能业务监控。
解决方案
监控目的
线上监控,普遍具备两个目的:
- 提升线上问题感知能力,快速发现并定位到问题
- 用最少到成本将线上问题的影响降到最低 我们同时也希望能够完成数据质量监控和接口语义监控1.0版本的实现,与公司其他监控方式形成互补。
监控对象与场景
数据质量监控
监控对象
在数据质量监控领域,监控对象主要涉及到以下三层维度,第一层是库表维度,依靠公司的DQC平台,来保障数据调度任务执行完成之后,落到库表上的数据质量。第二层是数据存储介质层,第三层是应用服务层,这两层的数据质量,我们主要是基于多个不同数据源,进行业务逻辑正确性比对,来发现数据质量问题。
监控场景
我们以哈啰地图数据质量监控场景作为例子,来介绍以上三种不同的层面,如何设计监控场景进行覆盖。
首先,如下图所示,我们可以将数据质量监控分成单数据源的质量分析和多数据源的对比分析。
对于单数据源的质量分析,我们侧重在库表维度,针对字段级(字段非空,字段唯一,字段值的取值范围,字段格式&精度等),表级(数据量波动)。两大方面进行质量保障。
对于多数据源的对比分析,我们从数据一致性的角度出发,分析不同数据源的相同数据在剥离逻辑差异后的数据一致性。
其次,可以从下图的哈啰地图数据质量监控场景中,了解到,以上两种数据分析方式,是如何在哈啰地图数据质量测试中落地的。
接口语义监控
监控对象
接口语义的监控对象,可以从服务类型分类的角度进行区分,涵盖了Web服务、RPC服务、消息服务、存储服务等。
监控场景
从服务可用性监控的角度出发,监控场景主要分为三种:
- 服务可用性,主要监控服务是否存活,返回的状态码是否正常;
- 响应时间,主要监控服务调用的完整响应时长,如果响应时长超过阈值,则触发告警;
- 语义正确性,主要监控服务响应的内容或字段,如:a. 是否满足特定规则,比如监控返回的价格字段,格式是否正确(数字格式,精度长度等)。b. 监控关键字段是否有效,比如我们的服务强依赖外部服务的某个字段数据,一旦外部服务升级导致我们依赖的关键字段出现变化,如逻辑调整,顺序调整等,我们均需要快速感知,并及时应对处置。
我们接口语义监控,就是保障第三个场景。其他两个场景,则依托公司的监控平台进行覆盖。与公司平台形成了很好的互补协作。
监控平台设计思路
功能模块
功能业务监控平台的设计,主要可以分为四个模块和一个平台化。其中四个模块指:
- 数据&服务模块:主要负责支持读取不同的数据监控对象,支持请求不同的服务类型;
- 规则策略模块:要求能够支持自定义的异常监控规则,自定义的告警策略,任意周期的监控策略,自定义告警等级与屏蔽规则等;
- 告警反馈模块:主要实现告警通道管理(个人,群组,邮件等),告警治理流程,对接改进工单系统,实现监控告警改进落地的闭环;
- 基础功能模块:主要包括用户&权限管理,任务配置管理,报警组&报警信息管理,数据大盘,报表展示等基础功能实现;
而平台化,指依托平台化建设实现监控平台的易用性,灵活性和统一接入能力;
系统分层设计
基于上述四个模块和一个平台化的设计原则,我们实现落地下图的系统分层设计
实践效果
算法测试平台介绍
我们最终搭建了AI测试平台,在该平台上,落地了数据质量监控和接口语义监控能力,主要规划开发了以下五个功能特性:
- 数据大盘:主要用于展示三个主要信息:a. 任务团队分布;b. 任务执行关键数据指标(累计&当日);c. 核心或异常的任务报表结果动态展示。希望在数据大盘上,能够一眼就看到所有核心信息;
- 任务管理:主要用于任务管理相关的操作,如任务筛选,创建,编辑,触发,执行日志获取,执行状态展示等;
- 监控报表:主要用于体现所有任务的监控数据,如任务信息介绍,监控数据多种形态展示,异常值高亮提醒等;
- 告警治理:主要用于所有告警问题的汇总,实现告警处理完整流程的处置,如通知,问题确认,改进工单提交,改进落地过程跟踪。最终实现监控闭环;
- 数据订正:主要用于对监控发现的异常数据,提供数据订正修复的能力,同时由于数据订正具有高风险的特点,需要具备权限管理和数据回退等功能;
案例分享
数据质量监控
简介
截止2021年2月底,数据质量监控平台,共接入8个数据监控任务,分别来自算法平台,供应链和电池服务。我们累计发现问题18个,其中61%是线下测试发现的问题,39%是线上监控发现的问题。
案例分享
在上文的问题介绍一节,已经详细的介绍了问题场景,数据处理流程和问题原因。这里主要介绍如何做数据对比和发现的问题分析
换电调度
数据比对方式
针对实时数仓的数据处理流程可知,数据源是kafka上报的埋点消息。对外服务方式是提供es查询。而在公司内部,也有其他团队使用相同的数据源对外提供服务,比如车服团队的OssMap服务。因此,我们采用比对实时数仓的ES查询数据和车服OssMap的SOA接口数据(将其作为参照物),来验证实时数仓的数据质量。
在这里,有同学可能会好奇,数仓的ES数据和OssMap的数据,可以直接对比吗?
答案是,不能。这里主要存在两个差异点:1. 时效性问题;2. 数据处理逻辑差异问题;
时效性问题:主要体现在,虽然数据源头,来自相同的kafka topic,但是两个服务对消息数据的处理效率是不一样的,而对于实时性要求比较高的字段,比如车辆进出站状态,车辆电量电压这类数据,必然会由于服务间的数据处理效率差异而出现一定程度的误差值。
数据处理逻辑差异问题:主要体现在,不同的服务,对于同一个消息内容,会有不一样的处理方式。比如车辆标签ALERT_OVER(超出服务区),在数仓的ES中是返回8,而在车服OssMap服务中则是返回101。
那如何解决这两个差异点呢?
答案是,对于时效性问题,我们采用动态配置容忍值策略来兼容误差问题,比如,我们配置电量容忍值为2,表示允许同一辆车的电量,在两个服务返回的数据差不大于2。即
if (Math.abs(车辆A的数仓电量 - 车辆A的OssMap电量) > 2) {
触发告警;
}
else {
认为两个服务的电量匹配,不告警;
}
而对于数据处理逻辑差异问题,我们则采用转换映射的方式来将两个服务返回的数据口径拉齐。比如车辆标签,我们以车服的标签格式为基准,将数仓的标签转换成车服的标签格式后,再做比对。
问题分析
对于换电调度的数据质量监控场景,我们累计发现8个BUG,其中线下测试发现问题4个,线上监控发现问题2个。
根据问题类型进行分类,可以分为两类,一类是数据处理逻辑问题4个,占比67%,一类是非功能问题2个,占比33%。
非功能问题:
- 容量问题:指服务查询ES需设置返回最大size大小,开发同学设置太小,导致返回的站点助力车数量少于实际情况;
- 性能问题:指上文提到的Flink消息消费压力过大,导致消息堆积,数据更新延时的问题;
数据处理逻辑问题:
- 过滤条件错误,比如车辆进出站需要过滤metric:"Bike.In.Site"但是isinsite=0的车辆;查询ES需要过滤StationGuid存在但CityGuid不存在的车辆等逻辑;
- 需求遗漏,指遗漏某些数据统计字段,遗漏某些统计规则等;
站点数据更新
数据比对方式
根据站点数据更新的数据处理流程,我们了解到,站点数据更新,是先更新绿洲服务后,再通过MQ消息通知电池服务进行数据更新,最后由电池服务对外提供服务。因此,绿洲服务和电池服务的数据,理论上是保持一致的。所以,我们将绿洲服务和电池服务的数据进行数据口径对齐后,就可以直接进行数据比对,从而监控数据质量。
问题分析
对于站点数据更新的数据质量监控场景,包含上述的电池服务数据比对任务和算法平台内部的站点数据比对任务,我们累计发现11个问题,其中线下测试发现7个问题,线上监控发现4个问题。
根据问题类型进行分类,可以分为两类,数据处理逻辑问题7个,占比64%,非功能问题4个,占比36%。
非功能问题:
- 消息消费&推送问题,如存在消息消费失败的情况;存在上文提到APP更新机制导致消息推送失败的情况;
- 并发问题,如算法平台内部的站点数据是保存在Redis中,但由于没有采用并发锁的机制,因此出现更新时,数据相互覆盖的情况;
- 数据更新同步问题,如当城市新增站点时,数仓的redis更新了站点信息(每天离线刷新),但未更新城市信息。导致智能调度的数据中心去查询时(带站点和城市id查询)查不到站点车辆数据;
数据处理逻辑问题:
- 取值错误,这是比较常见的问题,从错误的字段获取数据的情况;
- 数据处理逻辑错误,比如要过滤过期的脏数据,但逻辑存在BUG,将其他基础数据一并过滤的情况;
- 需求遗漏,指遗漏某些数据统计字段,遗漏某些统计规则等;
数据一致性
数据比对方式
从资产数据流转的过程可见,我们主要需要保障资产DB和ES集群两个数据源的一致性,确保数据同步任务高度可靠性。那么
- 对于每日万级,百万级的数据变更,我们如何确保所有数据都被正确同步呢? 答:我们通过定时从资产DB内查询所有update数据,再和ES内的数据做一一比对,从而确保所有同步数据的一致性;
- 如何实时监测同步服务的可靠性呢? 答:我们通过高频(分钟级别)+ 轻量(仅检查一条最新的update数据)的方式,实时对比DB和ES内的数据是否一致,从而反推同步服务的可靠性;
接口语义监控
简介
截止2021年2月底,接口语义监控平台,共接入2个数据监控任务,分别来自算法平台和供应链。我们累计发现问题1个线上问题。
案例分享
在上文的问题介绍一节,已经详细的介绍了问题场景和服务依赖架构。这里主要介绍如何做接口语义监控和发现的问题分析。
客服语音转换
接口语义监控方式
对于这种需要对接口进行语义监控的场景,我们采取主动探测+语义分析的方式来做:
主动探测,指高频(分钟级别)的对平安语音转文本服务,进行主动的请求调用;
语义分析,指提前准备好输入的语音文件,如内容为“你好”的语音文件,调用语音转换服务,对齐响应的内容进行分析判断,只有当响应的文字为“你好”时,表示监测通过,否则则告警反馈。
问题分析
截止2021年3月,我们累计发现3次平安语音转文本服务不可用的情况。原因均是由于客服系统依赖的热线服务(合力)变更后,推送过多无效录音导致ASR服务不可用。
平台接入方式
介绍到这里,有类似数据质量监控和接口语义监控需求的同学会问,我们该如何接入平台?如何获取这些监控能力呢?
关于平台的接入方式,我们首先将角色区分为两个,一个是需求方,即有监控需求,希望借助平台的能力,快速在线上落地数据质量和接口语义的监控任务的同学。另一个是平台方,即监控平台的维护人员(可直接联系算法测试团队)。
对于需求方而言,只需要四步骤,即可实现监控任务上线:
- 需求对接:提前准备好需求对接文档后,与平台方沟通需求;
- 监控规则脚本编写:根据监控脚本python工程模版,编写多数据源的比对规则(完全自主,无限制条件)
- 脚本验证:gitlab提交监控规则脚本后,即可在测试环境,进行数据比对测试,验证监控规则脚本;
- 监控任务上线:线下测试完成后,即可上线监控任务,在平台上关注监控任务执行情况,通过告警通道接收告警反馈;
未来规划
后续,我们将从以下3个维度建设功能业务监控平台:
现有能力完善:
截止到2021年2月底,我们已经初步完成数据大盘,任务管理,监控报表三大功能特性的能力建设,我们计划在持续完善现有三大功能特性的基础上,开展告警治理和数据订正两个功能特性的建设落地。同时,随着后续接入监控需求的多样性和复杂性,我们将同步提升平台本身的可靠性和告警有效性。
业务能力拓展:
我们同时期望,在夯实数据质量监控和接口语义监控能力的基础上,能够借助当前专项能力的提升,不断延伸拓展功能业务监控其他维度的能力建设,比如页面元素监控,智能客服团队当前在落地兼容性UI自动化测试专项,我们在思考,是否能将APP UI自动化测试 + 真机平台 + 监控平台 三种能力相结合,输出页面元素监控能力?
同样,基于业务测试的痛点,我们是否能够借助业务流程监控来快速发现线上业务流程问题,降低低级故障的发生率?
共建共创:
通过技术建设,让人人都能做好软件测试,是我们的梦想,我们会为之不断努力。梦想很大,路程很远,我们诚邀所有感兴趣的同学,和我们一起共建共创,共同建设功能业务监控能力。
同时,我们也会积极做好推广服务工作,期望平台能力能够更好的赋能开发和测试同学。