1、数仓链路保障体系与数据测试方法经验 提供导读 有赞数据报表中心为商家提供了丰富的数据指标,包括30+页面,100+数据报表以及400+ 不同类型的数据指标,它们帮助商家更合理、科学地运营店铺,同时也直接提供分析决策方 法供商家使用。并且,每天在跑的底层任务和涉及的数据表已经到达千级别。面对如此庞大 的数据体系,作为测试如何制定质量保障策略呢?这篇文章将从:1.有赞数据链路、2.数 据层测试、3 ,应用层测试、4 .后续规划这四个方面展开。 一、有赞数据链路1、数据链路介绍 首先介绍有赞的数据总体架构图: 数据自身检查,是指在不和其他数据比拟的前提下,用自身数据来检查准确的情况,属于最
2、基本的一种检查。常见的自身检查包括:检查数值类指标大于0、比值类指标介于0-1范围。 这类基础规那么,同数据完整性,也可以结合“数据形态工具”辅助测试。 举个例子,比方针对订单表,支付金额必然是大于等于0,不会出现负数的情况,编写sql: select count(pay_price) from dw. dws_xx_order where par = 20211025 and pay_price<0假设结果为0,说明支付金额都是大于0,满足预期;否那么假设count结果大于3说明数据存 在问题。 4.2 表内横向数据比照表内横向比照可以理解为同一张表内,业务上相关联的两个或多个字段,他
3、们存在一定的逻 辑性关系,那么就可以用来做数据比照。
比方针对订单表,根据实际业务分析易得:针对任何一家店铺的任意一款商品,都满足订单 数 >二下单人数,编写sql:
select kdt_id, goods_id, count(order_no), count(distinct buyer_id) from dw. dws xxorderwhere par ='20211025'group by kdt_id, goods_idhaving count (order_no) 4、说明订单数》二下单人数,那么
符合预期;否那么假设查询结果的记录大于0,那么不符合预期。
4.3 表间横向数据比照表间横向比照可以理解为两张表或多张表之间,其中具有业务关联或者业务含义一致的字 段,可以用来做数据比照:
同类型表之间比照:针对hive里的支付表A和支付表B,里面都有支付金额字段,那么同 样维度下的表A.支付金额=表B.支付金额。
多套存储之间比照:比方有赞数据报表中心针对支付表,应用层存储分别用到了 mysql和 kylin,用作主备切换,那么相同维度下的kylin-表A.支付金额=mysql-表B.支付金额。
多个系统之间比照:跨系统之间,比方有赞的数据报表中心和e 5、rm系统,两个系统都有客户 指标数据,那么相同维度下的数据报表中心-表A.客户指标二erm-表B.客户指标。
我们深度剖析数据横向比照的底层逻辑,本质就是两张表的不同字段,进行逻辑运算符的比 较,也比拟容易抽象成工具。目前有赞“数据比对工具”已经落地,下面给出我的一些思路:
输入两张表,分别设置两表的主键。
输入两张表中需要比照的字段,且设置比照的运算符,比方>、二、〈。
根据设置的规那么,最终数据比照通过、不通过的记录,落地一份可视化报告,测试人员可根 据报告内容评估数据质量。
4.4 纵向数据比照纵向比照就是上下游的数据比拟,目的是确保重要字段在上下游的加工过程中没有出现问
题 6、
比方数仓dw层存在订单的明细表,数据产品dm层存在订单数的聚合表,那么二者在相同维 度下的数据统计结果,应该保持一致。
4.5 code review首先,在进行code review之前的需求评审阶段,我们先要明确数据统计的详细口径是什么, 下面举两个实际的需求例子。
需求1:(错误例如)统计时间内店铺内所有用户的支付金额。问题所在:需求描述太过于 简洁,没有阐述清楚数据统计的时间维度以及过滤条件,导致统计口径不清晰,要求产品明 确口径。
需求2:(正确例如)有赞全网商家域店铺维度的离线支付金额。支持自然日、自然周、自 然月。统计时间内,所有付款订单金额之和(剔除抽奖拼团、剔除礼 7、品卡、剔除分销供货订 单)。
明确需求之后,下面详细介绍code review的一些常见关注点:
1)关联关系&过滤条件关联表使用outer join还是join,要看数据是否需要做过滤。
关联关系on字句中,左右值类型是否一致。
关联关系如果是1: 1,那么两张表的关联键是否唯一。如果不唯一,那么关联会产生笛卡 尔导致数据膨胀。
where条件是否正确过滤,以上述需求为例子,关注sql中是否正确剔除抽奖拼团、礼品卡 和分销供货订单。
2)指标的统计口径处理数据指标的统计涉及到两个基本概念:
可累加指标:比方支付金额,浏览量等,可以通过简单数值相加来进行统计的指标,针对这 类指标 8、sql中使用的函数一般是sum。
不可累加指标:比方访客数,不能通过简单相加,而是需要先去重再求和的方式进行统计, 针对这类指标,sql中一般使用count (distinct )。
(SELECT hourly,! hq_kdt_id,
\! kdt_id,src-channel,
| acq.src,sum(pv) AS pv,
[cotint(DIST1NCT uuid) AS uuid,~)
count(DISTINCT)goods_detoil_qisDlay_uiid) AS goods.detail_.di 「um(goods_detail_displiy_pv)] 9、AS goods_detail_display_pv,countQDISTINCT displayed_aoods-cnt) AS displayed_goods_cnt, count(shared_by_display_uuid) AS shared_by_display_uuid, sumfshared_by_display_pv) AS shared«by_display_pv, count(DISTINCT one_page_uuid) AS one_page_uuid, sum(goods_impressions_pv) AS goods_impressions_pv, sum(ne 10、w_uuid_cnt) AS new_uuid_cnt
3) insert插入数据是否支持重跑。等价于看插入时是否有overwrite关键字,如果没有该关键字,重跑数据(多 次执行该工作流)时不会覆盖脏数据,而是增量往表插入数据,进而可能会导致最终数据统 计翻倍。
插入的数据顺序和被插入表结构顺序是否完全一致。我们要保证数据字段写入顺序没有出 错,否那么会导致插入值错乱。
insert overwrite]table tmp.dws_. _ :_order partition(par= *${DP_l_DAYS_AGO_Ymd}*) selecta.hras hourly 1、是否为 i 11、nsert overwrite
J${DP_L t fl _AG0_Ymd}1/daily■ -YESTERDAY_Ymd}'AS weekly 2、数据插入顺序是否和
,,${DP_一■ ._OF_MONTH」_DAYS_AGO_Ymd" AS monthly表结构顺序一致,'${DP_・•一_ _OF_QUATER_l_DAYS_AGO_Ymd}' as quaterly ,d.hq_kdt_id ,a.kdt_id
as hq_goods.id
,coalesce(b.hq_goods.id,a.goods_id)40
,a.goods_iH三、应用层测试
1、整体概览
基 12、本的前端页面+服务端接口测试,和一般业务测试关注点是一致的,不再赘述。本篇重 点展开“数据应用”测试需要额外关注的地方。
2、降级策略在页面新增数据表的时候,需求、技术评审阶段确认是否需要支持“蓝条”的功能,属于“测
试左移”。
蓝条介绍:有赞告知商家离线数据尚未产出的页面顶部蓝条,其中的“产出时间”=当前 访问时间+2小时,动态计算得到。
当数据产出延迟时,前端 怎么展示?会不会引起商 家疑问?
数据没有产出,后端返回
“未产出”状态,前端会
挂“蓝条”提示商家
数据概况
搜索 O 。9 O ▼❶实时概况模块的昨日数据将于17:00左右校准,假设需精确对林.调校准后再来瓷看 13、其他模块的昨日数据预计将于17:00左右更新.
实时概况支付金额(元)O
0.00 昨日全天00。
支付金额(元)O
0.00 昨日全天00。
访客数
0
昨日全天o
浏览量
0
昨日全天o
测试比率类指标时,关注被除数=0的特殊场景。在后端code review、测试页面功能阶段,关注该点。目前有赞针对这种情况,前端统一展示的是“-”。
比率类的数据指标,比方 访问-支付转化率,当访问 =0 ,即被除数是0时, 怎么处理?
针比照率类的指标,比方 客单价、转化率等,被除 数为0导致不可计算,后 端统一返回-999999,前3、主备策 14、略
遇到有主备切换策略时,测试过程中注意数据正常双写,且通过配置,取数时能在主备数据 源之间切换。
实时数据的存储 druid是不可修改的,那 万一有bug了,实时数据 怎么修复?
目前实时数据采用双写 druid和tidb, druid数据 有问题时,通过apoll配置 切换至支持修改的tidb, 重刷数据即可4、数据平安
关注数据查询的权限管控,重点测试横向越权、纵向越权的场景。
四、后续规划目前在实际工程的数据准确性比照中,数据比照工具因为暂不支持sql函数,所以只能代替 50%的手工测试,一些复杂的横向和纵向数据比照还是需要编写sql。后续计划支持sum、 count、max 15、min等sql函数,把工具覆盖范围提升到75%以上,大大降低数据比照的本钱。
目前“数据形态报告”、“数据比照工具”更多的运用工程测试当中,后续计划将形态检查 和数据比照做成线上巡检,将自动化和数据工具相结合,持续保障数仓表的质量。
目前针对sql code review的方式主要靠人工,我们计划把一些基础的sql检查,比方insert into检查,join on条件的唯一性检查、字段插入顺序检查等作成sql静态扫描,整合到大 数据测试服务中,并且赋能给其他'业务线。
重点质量保障
・点质量保陛
数据统一服务
自顶向下可以大致划分为应用服务层、数据网关层、应用存储层、数据仓库, 16、并且作业开发、 元数据管理等平台为数据计算、任务调度以及数据查询提供了基础能力。
以上对整体架构做了初步的介绍,对于质量把控来说,最核心的两个局部是:数据仓库以及 数据应用局部。因为这两局部属于数据链路中的核心环节,相对于其他层级而言,日常改动 也更为频繁,出现问题的风险也比拟大。
二、数据层测试1、整体概览
首先,针对数据层的质量保障,可以分成三个方面:数据及时性、完整性、准确性。
数据层测试数据及时性
数据及时性
数据完整性
数据准确性
寰行数
自身检查
code review
横向比照
表
表
纵向比照
内
间
寰级网
| 袤大小 |
分区行数
17、
数据比照
2、数据及时性数据及时性,顾名思义就是测试数据需要按时产出。及时性重点关注的三个要素是:定时调 度时间、优先级以及数据deadline。其中任务的优先级决定了它获取数据计算资源的多少, 影响了任务执行时长。数据deadline那么是数据最晚产出时间的统一标准,需要严格遵守。
这三要素中,属于“普世规那么”且在质量保障阶段需要重点关注的是:数据deadline。那 么我们基于数据deadline,针对及时性的保障策略就可分为两种:
监控离线数据任务是否执行结束。这种方式依赖于有赞作业开发平台的监控告警,假设数据任 务在deadline时间点未执行完成,那 18、么会有邮件、企微、 等告警形式,通知到相应人员。
・洞度冏期⑦:
起止时间:2021-05-13 00 00:00 CI 2036-01-01 00:00:00 U 快提设M v7点作为统一数据产出deadline, 4点+ 180分钟=7点
报警用户:
邮件x nm x xdeadline 告鳖0180
deadline 告鳖0180
告・建通:邮件x 赞信x x
「失致告・②:邮件 Wf8 x x
检查全表条数或者检查分区条数。这种方式依赖接口自动化平台,通过调用dubbo接口,判 断接口返回的数据指标是否为0,监控数据是否产出 19、
请求参数
响应断言
结果提取
响应断言:
响应断言:
$.data[0].teamTotalUv
>
0
访客数>0
0
$.data[0].teamTotalPv
>
0
浏览量>0
0
$.data[0].orderllv
>
0
下单人数>0
0
$.data[0].orderAmount
>
0
下单金额>0
0
$.data[O].payUv
>
0
支付人数>0
n
$.data[0].payA 20、mount
>
0
支付金额>0
n
@列表横式groovy
断言判断数据指标>0,假设等于0,那么表示数据未产出
其次我们可以关注失败、重试次数,当任务执行过程中出现屡次失败、重试的异常情况,可 以抛出告警让相关人员感知。这局部的告警是对deadline告警的补充,目前在有赞作业开 发平台上也有功能集成。
3、数据完整性数据完整性,顾名思义看数据是不是全,重点评估两点:数据不多、数据不少。
数据不多:一般是检查全表数据、重要枚举值,看数据有没有多余、重复或者数据主键是否 唯一。
数据不少:一般是检查全表数据、重要字段(比方主键字段、枚举值、日期等),看字段的 数值是否 21、为空、为null等。
可见数据完整性和业务本身关联度没有那么密切,更多的是数仓表的通用内容校验。所以从一些基础维度,我们可以将测试重点拆成表级别、字段级别两个方向。
表级别完整性:
全表维度,通过查看全表的总行数/表大小,假设出现表总行数/总大小不变或下降,说明表数 据可能出现了问题。
分区维度,通过查看当日分区表的数据行数/大小,假设和之前分区相比差异太大(偏大或偏 小),说明表数据可能出现了问题。
目前有赞元数据管理平台已集成相关数据视图:
字段含义
历史趋势
数据质量
变更记录
数据本钱
质量提升
形态报告
30
30
天更新时刻:
每日首次更新
22、
总行数
增量行数
字段级别完整性:
唯一性判断:保证主键或某些字段的唯一性,防止数据重复导致和其他表join之后数据翻 倍,导致最终统计数据偏大。
比方判断。ds层订单表中的订单号是否唯一,编写sql:
select count (order_no), count (distinct order_no) from ods. xx_order 假设两者相等,那么说明order_no值是表内唯一的;否那么说明order_no表内不唯一,表数据存 在问题。
非空判断:保证重要字段非空,防止空数据造成和表join之后数据丧失,导致最终统计数 据偏少。
比方判断ods层订单表中的订单号是 23、否出现null,编写sql:
select count (*) from ods. xx_order where order_no is null
假设结果等于0,那么说明order_no不存在null;假设结果大于0,那么说明order_no存在null 值,表数据存在问题。
枚举类型判断:保证枚举字段值都在预期范围之内,防止业务脏数据,导致最终统计结果出 现遗漏/多余的数据类型。
比方判断ods层订单表中的shop_type字段中所有枚举值是否符合预期,编写sql:
select shop type from ods. xx_order group by shop type
分 24、析查询结果是否满足预期,确保不会出现遗漏/多余的枚举类型。
数据有效性判断:判断数据格式是否满足预期,防止字段的数据格式不正确导致数据统计的 错误以及缺失。常见的有日期格式yyyymmdd。
一旦出现数据完整性问题,对数据质量的影响很大。所以完整性策略更适用于。ds层,因为 我们更期望从源头发现并解决数据不合理问题,及时止损,防止脏数据进入下游之后,数据 污染扩大。
另外,我们看到完整性校验内容逻辑简单,且比拟固定,稍微进行简单的抽象就能将其模板 化。那么作为测试,我们更倾向于将数据完整性校验做成工具。目前有赞“数据形态工具” 已经落地,下面给出我的一些思路:
1.
针对所有表来说, 25、普世性的规那么,比方表主键的唯一性。
2.
针对不同类型比方数值、String.枚举、日期格式类型,列举出常见的数据判断规那么。
3.
给每项规那么进行等级划分,比方表的主键不唯一,记为critical。String类型字段的空值 比例大于70%,记为warn ingo
4.
根据表数据是否满足上述这些规那么,最终落地一份可视化报告,测试人员可根据报告内容评 估数据质量。
报告解读
通用规那么总数/失败
规那么详情.根据主键计算数据不唯一,可能存在重复数据,请检查主键和数据
1 .数值字段% ds_id]有null值.数值字段怙ute_type]有null值
26、2 .枚举字段[ate_type]的枚举值只有1种,枚举值为[null].数值字段[a r*u jcycle]有null值
3 .枚举字段[a r" n「cycle]的枚举值只有1种,枚举值为[null].数值字段[s,t .tic〔scope]有null值
critical 40/17
4 .枚举字段口 -…-Lscope]的枚举值只有1种,枚举值为[null].枚举字段[|订的枚举值只有1种,枚举值为⑺
5 .字段[cart.)unt]值都是0.数值字段[c it_buyer_id]有null值
6 .字段[o( . "Jnt]值都是0.数值字段(、r_buyer_id]有nul 27、l值
7 .数值字段卜•及_amount]有null值.字段[pay. : int]值都是0
8 .数值字段口 /_buyer_id]有 null 值.数值字段y_amoum]有null值
warning9/0校验失败的数据已在报告中分别以红、橙颜色标出,请关注。
规那么详细请戳,欢迎大家反应补充。
4、数据准确性数据准确性,顾名思义数据要“准确”。“准确”这个概念比拟抽象,因为我们很难通过一
个强逻辑性的判断,来说明数据有多准,大局部都存在于感性的认知中。所以准确性测试也是在数据质量保障过程中思维相对发散的一个方向。经过总结,我们可以从字段自身检查、
数据横向比照、纵向比照、code review等方面,去把控数据的准确性,这些测试点和业务的关联也比拟密切。
4.1自身检查






