前言

datalake架构

离线数据 ODS -> DW -> DM

实时数据

名词解释

名词 描述
源表 数据清洗之前的原始数据表
目标表 数据清洗之后的表
单源 一个渠道的数据落到一个表里面
多源 多个渠道的数据落到一个表里面
增量更新 每次只对需要更新的时间范围进行更新
全量更新 每次更新时都需要更新整个数据集
关联逻辑 一组关联逻辑里含3部分:关联关系、过滤条件、聚合取行
宽表 宽表从字面意义上讲就是字段比较多的数据库表。通常是指业务主题相关的指标、维度、属性关联在一起的一张数据库表。
指标类型 1、基础指标:指表达业务实体原子量化属性的且不可再分的概念集合,如交易笔数、交易金额、交易用户数等。
2、复合指标:指建立在基础指标之上,通过一定运算规则形成的计算指标集合,如平均用户交易额、资产负债率等。
3、派生指标:指基础指标或复合指标与维度成员、统计属性、管理属性等相结合产生的指标,如交易金额的完成值、计划值,累计值、同比、环比、占比等。
4、标准信息:经过标准化处理的实体非量化属性信息,或分段统计信息,省份(北京、广州等)、缴费方式(缴费、充值)渠道(网厅、直充、专区)、消费金额(30元、50元、100元等)。

ETL测试

1、关联逻辑测试

1.1、内容

由数据源一个表或多个表关联并增加一些过滤条件,如果需求中要求根据业务主键分组取其中一条,那么过滤条件中需要有分组取TOP1的逻辑,如DL层根据order_no分组,biz_date倒序>fetch_time倒序>file_line_no倒序的排序规则取top 1记录,能够尽量保证所取的结果比较稳定。

关联的过程如果非常复杂,可能有多个子关联的步骤,本质上一个子关联就是上面的情况。

普通关联一般有以下3部分组成:

  • 表之间的join关系;
  • 过滤条件,如果业务隔离、无效数据隔离、重复数据取一条;
  • 基于前面两步后的取record的逻辑,业务主键相同的数据分组取TOP1。

源主表和目标表关联字段的对应关系有几类:

源主表关联字段 目标表关联字段 关系 备注
不为主键 为主键 多对1 分组取一条或者分组合并
为主键 为主键 1对1 总量保持不变
为主键 不为主键 1对多 如表拆分,ETL中暂未遇到这些情况
不为主键 不为主键 多对多 如平移的情况

1.2、方法

验证目标表的数据量,实现ETL的关联逻辑将源表关联起来,得到关联之后的数据量,跟实际ETL之后的数据量对比,预期这两个数据量是一致的。

其中对于复杂关联策略,将源表关联起来的时候可以拆成多个步骤来实现,每个步骤的测试过程需要一个中间表,这个中间表的形式可以是新建的一个普通表,或者一个临时表,或者一个视图。

测试join后分组取排序取Top1的情况是否稳定可参考大数据原则中第七个原则的case4。(以后有时间了会再写一篇文章讲讲大数据原则)

关注因关联关系而丢掉的数据量,如果数据量过大,需要相关DA关注并进一步分析是否存在潜在数据问题。

关注因过滤条件而筛掉的数据量,如果数据量过大,需要相关DA关注并进一步分析是否存在潜在数据问题。

1.3、数据质量分析

在需求分析后,对内容和测试方法有了方向后,需要对源数据进行表画像和关联表画像的分析, 评估待测数据是否有质量问题,如果有再跟ETL设计沟通是上游数据问题还是设计问题。

1.4、案例

类型 逻辑 细节 数据质量分析 备注
关联关系 A left join B on A.a = B.b A表的关联字段组合起来是否是主键,如果不是主键则B表有数据关联不上发生丢数据
过滤条件 order_no is not null
聚合取行 group by order_no order by xdate desc,ydate.asc 分组排序取Top1,按order_no分组,根据xdate降序排、ydate升序排,然后取第一条记录
多层关联逻辑 通过多组关联逻辑得到一个或多个中间结果表;再基于中间表等通过一组关联逻辑得到最终ETL的中间表 关联逻辑的解释可参看名词解释

2、转换测试

2.1、内容

字段取值逻辑

  • 通用取值逻辑,通常可以定义一些通用的UDF来处理:

    ​ 数据格式的合法性,如对于数据源中时间、数值、字符等数据的处理,是否符合数据仓库规则,是否进行统一的转换;

    ​ 空值的处理,如是否捕获字段空值,或者需要对空值进行替换为其他含义值的处理。

  • 业务取值逻辑

    ​ 值域的有效性,如是否有超出维表或者业务值域的范围;

    ​ 主键的有效性,如主键是否唯一;

    ​ 脏数据的处理,如比如不符合业务逻辑的数据。

  • 其它

    ​ 源表数据类型转换成期望的目标表数据类型;

    ​ 验证源表编码转换成期望的目标表编码;

    ​ 乱码的检查,如特殊符号或者乱码符号的护理规则;

    ​ 目标表增加字段的内容和逻辑,如增加了一些ETL时间的字段等;

    ​ 抽样测试,根据具体情况确定样本量。

2.2、方法

验证目标表数据内容的正确性。

基于1.2中的由ETL的关联关系得到的中间表,抽样或者全量数据基于中间表逐一将单个字段进行逻辑处理,得到期望结果,验证实际结果是否匹配期望结果。

2.3、数据质量分析

在需求分析后,对2.1内容和2.2测试方法有了方向后,需要对源表中数据进行字段画像的分析,评估待测数据是否有质量问题,如果有再跟ETL设计沟通是上游数据问题还是设计问题。

2.4、案例

类型 逻辑 细节 数据质量分析 备注
通用 脏数据处理 在某一层(例如落到DW时)将脏数据置为空串,或null,且在系统中保持一致
业务隔离 将不符合规则的数据过滤(如电话号码格式不正确) GRL: 在ods 加一个data_invalid_type 的分区,将合法和不合法数据存储在不同的分区中
通用 字段类型转换 字段类型转换处理,遵循两个原则,即含脏数据处理逻辑、只能大转小 通用类型的可以定义为UDF:比如在 ETL过程中会对一些敏感数据做加密,可将加密逻辑做成 UDF 函数,可以供所有的表使用
string - > date if (yyyy-MM-dd HH:mm:ss字符串)
{转date类型}
else {null}
E.g.: to_date('2019-04-19 10:29:50')
string - > timestamp if (yyyy-MM-dd HH:mm:ss字符串)
{转timestamp类型}
else {null}
timestamp - >date if (timestamp)
{转date yyyy-MM-dd HH:mm:ss类型}
else {null}
select from_unixtime(cast(timestamp时间戳/ 1000 as int), 'yyyy-MM-dd HH:mm:ss');
date(yyyy-MM-dd HH:mm:ss) - >date (yyyy-MM-dd) 时间字段截取到天 select substr(date,0,10)
date(yyyy-MMM-dd HH:mm:ss) - >date (yyyyMMMdd) 时间字段格式转换 from_unixtime(unix_timestamp(substr(date,0,10),'yyyy-MM-dd'),'yyyyMMdd')
string - > int if (数值字符串&在int类型的取值范围)
{转int类型}
else {null}
INT/INTEGER (4-byte signed integer, from -2,147,483,648 to 2,147,483,647);
Hive: Cast(字段 as int)
int - > bigint
varchar - > char
空字符 - > null select count(1) from 表 where 字段=''; 预期是0 减少数据大小,规范数据格式
通用 isnull(A,B,C)
窗口函数:
row_number() over(partition by XXX order by XXX)
用于多条记录选取其中一条的情况,如选取用户最后一次购买的产品 row_number() over(
partition by userid
order by date desc )
时间相关 计算日期差:
datediff(date1,date2)
用于计算两个日期之间的间隔 select datediff(to_date('2020-12-03'),to_date('2020-12-01'));
--2
计算月份差:months_between() 用于计算两个日期的月份间隔 一:select months_between('2020-10-10','2020-09-10');
--1
二: select months_between(to_date('2020-10-10'),to_date('2020-09-01'));
--1.29032258
取某个月份的同一天add_months() 如:取一年前的20号 select add_months('2020-12-21',-12);
--2019-12-21
计算多少天后:date_add() select date_add('2020-09-15',1);
--2020-09-16
条件函数 if(A,B,C) 如果A满足,则返回B, 否则返回C select if(1>2,1,0);
--0
case when 条件1 then 结果1
when 条件2 then 结果2
...
end
如果满足条件1 则返回结果1
如果满足条件2 则返回结果2
...
字符串函数 substr(order_code,1,2) 字符串截取 select substr('abcde',0,2) ;
--ab
length() 返回字符串的长度 select length('abcde');
--5
instr() 寻找字符串的位置,没有找到则返回0 select instr('abcde','b');
--2
split() 字符串分割 select split('EI4331_1','_')//返回数组类型
["EI4331","1"]
select split('EI4331_1','_')[0]
EI4331
regexp_replace() 字符串替换函数 select regexp_replace('abcdef','c','g');
--abgdef

3、更新策略测试

3.1、内容

数据迁移到数仓的过程,通常步骤如下:

​ Step 1:初始化数仓,即将历史全量数据迁移到数据仓库;

​ Step 2:定时启动迁移动作。

定时启动迁移动作将新生成的数据或者变化的任何数据更新到数据仓库的过程,就需要考虑更新逻辑或者叫更新策略。

注意,每个目标表都有Step 1和Step 2所用到的两种更新策略,如果开发实现是不同的,那么要分开测试。

3.2、方法

验证目标表数据量和数据内容的正确性。

3.2.1、单源增量更新

目标表仅单一源数据,如Tmall数据。

Pre-Condition:源表的关联、转换逻辑是正确的,这里单独测单源更新策略。

Step 1:构造源表测试数据;

Step 2:执行ETL,得到实际落地目标表的数据;

Step 3:构造源表中满足更新策略的数据;

Step 4:执行ETL,验证目标表中落地数据量和内容的正确性。

3.2.2、多源增量更新-全表删除插入方式

目标表有多个源数据,如Tmall、JD、Offline数据。

Pre-Condition:源1、源2单独的关联、转换逻辑是正确的,这里单独测不同源之间的更新策略。

Step 1:构造源1测试数据;

Step 2:执行ETL,得到实际落地目标表的数据;

Step 3:构造源2中满足更新策略的数据;

Step 4:执行ETL,得到实际落地目标表的数据;

Step 5:根据关联、转换逻辑,设计sql得到源2单独落地的目标数据;

Step 6:用Step 5中数据根据更新策略覆盖Step 2中落地目标表的数据,得到Step 4期望的目标表数据;

Step 7:对比Step 4和Step 6,验证实际落地数据量和内容是否正确。

3.2.3、增量更新-时间戳方式

测试结果是否遗漏数据,如果为时间戳方式,要尤其注意时间戳是否带时分秒

增量规则是否正确,对于源表做好足够的数据探查,明白源表中的数据的增量是怎么回事,必要时需要讨论,然后根据业务规则做增量规则方案。

3.2.4、全量更新-全量加载方式

同关联和转换部分的方法,所以本质上全量更新策略不需要单独测试。

3.2.5、测试执行的小TIPS

分来源的表,建议开发每准备启动ETL Job处理下一个来源前备份一次数据;

构造数据时,准备全面的数据,避免来回上传集群重跑数据,占资源,浪费时间。

3.2.6、增量/全量的适用场景
  1. 全量同步主要是对数据量少的表,比喻电商项目中的商品表、用户表、商户表、地区表、订单状态等实体和维度表,这类数据量少,可以使用全量同步。优点在于简单快捷.
  2. 增量同步主要是针对数据量庞大的大的场景,比喻订单表,每天产生的订单表数据量庞大,如果使用全量同步,数据占用磁盘的将会非常恐怖,所以一般会采用增量同步的方式。这种方式逻辑较复杂,速度较慢,且要求源表主键能够匹配识别。

4、调度策略测试

4.1、内容

整个ETL处理的过程有多个数据层,假如将每一层的处理到每个目标表的过程定义一个的Job,那么会有很多Job,同一层的Job可能会存在依赖关系,层与层之间肯定会存在依赖关系。因此,快速见效的ETL处理流程将是一个比较复杂的过程,为了对复杂的ETL处理过程更好的调度,更充分得利用系统资源,从而要考虑和设计最优的调度策略。

根据更新策略的更新周期可以确定调度策略的周期,预期是保持一致的。

验证调度策略依赖关系是否合理,最终落地数据的完整性、正确性。

验证job的上下游配置正确。

4.2、方法

测试方法同关联、转换、更新策略。

5、性能测试

5.1、内容

基于某环境参数和数据量,统计单个任务或任务树的执行时间以及资源占用情况,以确认改进的性能和可扩展性,可贯穿整个测试周期。

对于任务树的性能,确保数据在规定和预计的时间内被加载到相应的位置。

性能指标,在指定数据量的情况下,一般从第一个job开始到最后一个job执行结束所花费的时间跨度越短、资源利用率越在70%左右越好。

5.2、方法

统计不同数据量下每个Job执行的时间;

统计不同数据量下全部Job执行的时间;

统计不同数据量下系统资源利用率。

6、测试用例

目前项目的测试用例一般覆盖以下几个部分:

  • 关联;
  • 转换;
  • 调度策略;
  • 更新策略。

具体的项目测试用例根据项目的测试范围来决定测试用例覆盖的内容。

关于转换逻辑部分的编写说明:

1、if else的情况:

  • 条件逻辑对比总数【测试用例里体现一个,实际可抽样两个写进测试用例】;
  • 每个条件逻辑抽样对比所有字段;

2、枚举类型:

  • distinct目标表字段,验证结果是否在枚举范围内;
  • 枚举类型对比总数【测试用例里体现一个,实际可抽样两个写进测试用例】;
  • 部分枚举类型抽样对比所有字段;
  • 源数据不再此枚举范围内的,验证全部留空

3、isnull(A,B,C)

同如下逻辑:

if A is not null and A <> ''

取A;

else if B is not null and B <> ''

取B;

else if C is not null and C <> ''

取C;

else

取NULL

注意:数据库字段长度的空字符串值全都重置为null

验证方式:

确定表之间的关联逻辑;

查询A非null和‘’,验证取A

查询A是null且B非null,验证取B;

查询A是‘’且B非null,验证取B;

查询A是null且B是null且C非null,验证取C;

7、可能遇到的挑战

ETL设计复杂,设计人员没有花足够的精力去优化,导致开发和测试人员分析困难;

需要足够的敏感性去分析ETL设计是否合理,如果关联部分分组取TOP1是否稳定合理,转换逻辑中的枚举状态是否覆盖源数据所有值;

ETL关联、转换、更新策略、调度策略的复杂性是非常巨大的。

ETL数仓测试的更多相关文章

  1. HAWQ取代传统数仓实践(十六)——事实表技术之迟到的事实

    一.迟到的事实简介 数据仓库通常建立于一种理想的假设情况下,这就是数据仓库的度量(事实记录)与度量的环境(维度记录)同时出现在数据仓库中.当同时拥有事实记录和正确的当前维度行时,就能够从容地首先维护维 ...

  2. 基于Hive进行数仓建设的资源元数据信息统计:Hive篇

    在数据仓库建设中,元数据管理是非常重要的环节之一.根据Kimball的数据仓库理论,可以将元数据分为这三类: 技术元数据,如表的存储结构结构.文件的路径 业务元数据,如血缘关系.业务的归属 过程元数据 ...

  3. 技术专家说 | 如何基于 Spark 和 Z-Order 实现企业级离线数仓降本提效?

    [点击了解更多大数据知识] 市场的变幻,政策的完善,技术的革新--种种因素让我们面对太多的挑战,这仍需我们不断探索.克服. 今年,网易数帆将持续推出新栏目「金融专家说」「技术专家说」「产品专家说」等, ...

  4. 数仓1.1 分层| ODS& DWD层

    数仓分层 ODS:Operation Data Store原始数据 DWD(数据清洗/DWI) data warehouse detail数据明细详情,去除空值,脏数据,超过极限范围的明细解析具体表 ...

  5. HAWQ取代传统数仓实践(十九)——OLAP

    一.OLAP简介 1. 概念 OLAP是英文是On-Line Analytical Processing的缩写,意为联机分析处理.此概念最早由关系数据库之父E.F.Codd于1993年提出.OLAP允 ...

  6. HAWQ取代传统数仓实践(十三)——事实表技术之周期快照

    一.周期快照简介 周期快照事实表中的每行汇总了发生在某一标准周期,如一天.一周或一月的多个度量.其粒度是周期性的时间段,而不是单个事务.周期快照事实表通常包含许多数据的总计,因为任何与事实表时间范围一 ...

  7. 基于MaxCompute的数仓数据质量管理

    声明 本文中介绍的非功能性规范均为建议性规范,产品功能无强制,仅供指导. 参考文献 <大数据之路——阿里巴巴大数据实践>——阿里巴巴数据技术及产品部 著. 背景及目的 数据对一个企业来说已 ...

  8. 基于Hive进行数仓建设的资源元数据信息统计:Spark篇

    在数据仓库建设中,元数据管理是非常重要的环节之一.根据Kimball的数据仓库理论,可以将元数据分为这三类: 技术元数据,如表的存储结构结构.文件的路径 业务元数据,如血缘关系.业务的归属 过程元数据 ...

  9. 传统 BI 如何转大数据数仓

    前几天建了一个数据仓库方向的小群,收集了大家的一些问题,其中有个问题,一哥很想去谈一谈--现在做传统数仓,如何快速转到大数据数据呢?其实一哥知道的很多同事都是从传统数据仓库转到大数据的,今天就结合身边 ...

随机推荐

  1. 「10.28」Dove 打扑克(链表)·Cicada 与排序(概率)·Cicada 拿衣服(各种数据结构)

    A. Dove 打扑克 考场思考半天线段树树状数组,没有什么想法 打完暴力后突然想到此题用链表实现会很快. 因为只有$n$堆,所以设最多有$x$个不同的堆数,那么$x\times (x-1)/2==n ...

  2. 如何设置Python环境变量

    大家好,我是Yivies.相信很多python的初学者们在进行一顿下一步下一步的安装之后,在windows command命令行输入python的时候会出现这样的情况: 可我们希望它是这样子的: 其实 ...

  3. 痞子衡嵌入式:超级下载算法RT-UFL v1.0发布,附J-Link下安装教程

    痞子衡主导的"学术"项目 <RT-UFL - 一个适用全平台i.MXRT的超级下载算法设计> 历时 8 个月终于迎来了 v1.0 版发布,因为是第一个正式版,为了保证质 ...

  4. c#将图片Image转换为内存流MemoryStream

    HttpWebResponse resp = (HttpWebResponse)wRequest.GetResponse(); Stream stream = resp.GetResponseStre ...

  5. 单链表(LinkedList)

    与数组相似,链表也是一种线性数据结构.这里有一个例子:   正如你所看到的,链表中的每个元素实际上是一个单独的对象,而所有对象都通过每个元素中的引用字段链接在一起.   链表有两种类型:单链表和双链表 ...

  6. Oracle查询wm_concat返回[oracle.sql.CLOB@7D6414ed]之坑!

    在orcale中使用wm_concat函数将字段分组连接. 在linux环境下需要将wm_concat(字段)进行to_char(wm_concat(字段))处理.

  7. Java核心反射机制

    Java核心反射机制: 基本反射: 反射是一种动态类的处理机制,通过Class类来实现反射机制: Class类的基本信息: Module java.base Package java.lang Cla ...

  8. POJ 1873 The Fortified Forest 凸包 二进制枚举

    n最大15,二进制枚举不会超时.枚举不被砍掉的树,然后求凸包 #include<stdio.h> #include<math.h> #include<algorithm& ...

  9. LAMP——搭建基于Apache、wordpress、nfs、mysql、DNS的系统

    一.部署架构 二.部署过程 1.在10.0.0.8和10.0.0.18服务器上安装apache服务 [17:10:06 root@centos8 ~]#yum -y install httpd 安装p ...

  10. 被swoole坑哭的PHP程序员 (转)

    本文主要记录一下学习swoole的过程.填过的坑以及swoole究竟有多么强大! 首先说一下对swoole的理解:披着PHP外衣的C程序.很多PHPer朋友看到swoole提供的强大功能.外界对其的崇 ...