标签 数据比对 下的文章

一、前言

随着企业数字化转型加速推进,大数据业务规模呈现指数级增长,迭代变更越发频繁。此背景下,呈现"高频变更"与"超大规模"并存的特征,这种双重特性给大数据任务的发布变更带来了严峻挑战。

二、项目目标

离线数仓任务资产管理

增量:通过大数据变更发布流水线进行卡点,确保末端任务发布前,消费场景&风险等级完成绑定。增量任务发布消费场景绑定率100%覆盖。

存量:盘点存量资产任务,人工梳理打标,完成初始化消费场景绑定。

大数据变更发布流水线

数仓任务发布流水线管控100%覆盖,任务发布效率提升60%。

三、项目方案

数仓任务资产管理

消费场景定义

根据业务用途梳理消费端内容,根据风险高低定义风险等级P0、P1、P2,从末节点自动倒推追溯上游全链路,并全部打上风险等级P0、P1、P2标识,以相同的生产规范标准要求上下游各方协同保障。

风险等级定义

消费场景注册&绑定

  • 消费场景注册

当前数仓任务消费场景已经完成初步盘点和梳理,并且将盘点的消费场景数据初始化到平台中。随着迭代场景的新增,需要注册新的场景,从而应业务所需。

  • 存量资产任务绑定

针对当前数仓存量资产任务进行盘点,将adm、ads层表进行梳理、打标,最终初始化到平台中,完成存量资产绑定消费场景。

  • 任务消费场景应用

任务和消费场景完成绑定后,从而决定任务的应用场景、风险等级,P0、P1任务将在变更管控、线上稳定性保障等得到重保。

数仓变更管控流水线

质量定义(DQC)

在离线数据仓库(数仓)中,数据质量检查(DQC,Data Quality Check)是确保数据准确性、一致性、完整性的重要环节。数仓ETL任务在加工完成后,会执行DQC检查,从而有效、及时发现数据质量问题,便于研发人员及时修复,避免问题数据对业务造成损失。

  • DQC强规则

当强规则执行不通过后,直接失败任务,及时通知任务Owner,并拦截下游任务执行,待修复后下游链路再继续执行。(拦截任务,需要值班人员及时修复。)

  • DQC弱规则

当弱规则执行不通过后,及时通知任务Owner。任务正常执行成功,下游任务也正在运行。(不拦截任务,会通知到任务Owner。)

质量定义配置

  • 通用型DQC规则


质量定义通过可视化界面操作,让用户可以直接通过简单的勾选方式,即可生成对应的DQC规则,大大提高研发人员配置DQC的效率。

  • 自定义DQC规则

用户可以按照规则SQL补充规则逻辑,从而实现自定义验证SQL融入DQC-SQL中,达到自定义DQC规则的效果。

强弱规则配置

DQC强规则和弱规则的配置方式完全一致,通过Tab的切换,可以完成强弱规则的配置。

质量DQC试运行

所有DQC配置完成后,需要通过试运行之后才能保存上线,确保DQC配置的合理性、有效性。

告警策略

支持飞书、电话、短信、邮箱等方式告警通知。其中强规则一旦触发,必定电话告警(采取15分钟无响应即逐级上升原则)。

发布流水线管控

静态扫描

检测规则:任务依赖、建表规范、编码规范、集成规范、DQC规范等。

冒烟测试

在数仓测试环境下,完成任务冒烟测试执行,执行内容包含:ETL任务、DQC规则。

CodeReview

描述:根据业务熟悉对,由数据域数仓PM 或者 业务数仓技术负责人进行评审,给出评审结论。

内容:ETL代码、调度配置、质量定义配置、DQC-SQL等。

注意:审批人飞书会接收到来自“xx稳定中心”机器人推送的消息,点击进入审批详情完成审批即可。

数据探查

描述:针对表内所有字段进行探查和校验,主要场景:数字探查、字符探查、主键验证、无效字段验证、异常字段验证

PS:数字探查和字符探查会给出明显问题红色高亮标识。

数据比对

描述:针对生产表和测试表进行数据比对,比对场景:数据量对比、聚合指标对比、明细对比。

注意信息:对比的两张表用户无法输入,用户需要输入执行分区、主键字段、去噪字段、风险阈值(针对明细对比生效)。

发布审批

描述:发布审批节点,用户输入本次发布的基础信息,提交审批即可。

所有需求都需要数据域PM和对应数据域的责任QA进行审批。

四、总结&未来规划

实践总结

得物离线数仓发布流水线过去1年有着从0到1的建设,以及后期从1到10的优化和改进。当前流水线能力已经足以支撑数仓内部日常迭代变更需求的发布管控,为发布准出规则执行提供了巨大帮助。

发布管控对于QA来说是最重要的一个环节,所有发布都能够达到准出标准的要求,从而才能守住发布的最后一道线。

未来规划

节点能力优化

当前数仓表单分区大于3TB(十亿、百亿、千亿级别)存储数据后,数据探查、数据比对将不提供验证服务,主要源于数据量、存储过大、字段过多,对计算资源、计算存储带来巨大的消耗,严重影响其他任务的执行进度。后续通过数据抽样验证的方式从而降低资源的消耗,从而提升场景覆盖度。

流水线能力补充

数据探查未来考虑通过和历史探查结果比对参考的方式,给出诊断结果,进一步提升工具卡点能力。

往期回顾

1.AI编程实践:从Claude Code实践到团队协作的优化思考|得物技术

2.入选AAAI-PerFM|得物社区推荐之基于大语言模型的新颖性推荐算法 

3.Galaxy比数平台功能介绍及实现原理|得物技术

4.得物App智能巡检技术的探索与实践

5.深度实践:得物算法域全景可观测性从 0 到 1 的演进之路

文 /家森

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。

一、背景

得物经过10年发展,计算任务已超10万+,数据已经超200+PB,为了降低成本,计算引擎和存储资源需要从云平台迁移到得物自建平台,计算引擎从云平台Spark迁移到自建Apache Spark集群、存储从ODPS迁移到OSS。

在迁移时,最关键的一点是需要保证迁移前后数据的一致性,同时为了更加高效地完成迁移工作(目前计算任务已超10万+,手动比数已是不可能),因此比数平台便应运而生。

二、数据比对关键挑战与目标

关键挑战一:如何更快地完成全文数据比对

现状痛点:

在前期迁移过程中,迁移同学需要手动join两张表来识别不一致数据,然后逐条、逐字段进行人工比对验证。这种方式在任务量较少时尚可应付,但当任务规模达到成千上万级别时,就无法实现并发快速分析。

核心问题:

  • 效率瓶颈:每天需要完成数千任务的比对,累计待迁移任务达10万+,涉及表数十万张。
  • 扩展性不足:传统人工比对方式无法满足大规模并发处理需求。

关键挑战二:如何精准定位异常数据

现状痛点:

迁移同学在识别出不一致数据后,需要通过肉眼观察来定位具体问题,经常导致视觉疲劳和分析效率低下。

核心问题:

  • 分析困难:在比对不通过的情况下,比对人员需要人工分析失败原因。
  • 复杂度高:面对数据量庞大、加工逻辑复杂的场景,特别是在处理大JSON数据时,肉眼根本无法有效分辨差异。
  • 耗时严重:单次比对不通过场景的平均分析时间高达1.67小时/任务。

比数核心目标

基于以上挑战,数据比对系统需要实现以下核心目标:

  • 高并发处理能力:支持每天数千任务的快速比对,能够处理10万+待迁移任务和数十万张表的规模。
  • 自动化比对机制:实现全自动化的数据比对流程,减少人工干预,提升比对效率。
  • 智能差异定位:提供精准的差异定位能力,能够快速识别并高亮显示不一致的字段和数据。
  • 可视化分析界面:构建友好的可视化分析平台,支持大JSON数据的结构化展示和差异高亮。
  • 性能优化:将用户单次比对分析时间从小时级大幅缩短至分钟级别。
  • 可扩展架构:设计可水平扩展的系统架构,能够随着业务增长灵活扩容。

三、解决方案实现原理

快速完成全文数据比对方法

比数方法调研

待比对两表数据大小:300GB,计算资源:1000c


经过调研分析比数平台采用第二种和第三种相结合的方式进行比数。

先Union再分组数据一致性校验原理

假如我们有如下a和b两表张需要进行数据比对

表a:


表b:


表行数比较:

select count(1) from a ;
select count(1) from b ;

针对上面的查询结果,如果数量不一致则退出比对,待修复后重新比数;数量一致则继续字段值比较。

字段值比较:

第一步:union a 和 b

select 1 as _t1_count, 0 as _t2_count, `id`, `name`, `age`, `score`
from a
union all
select 0 as _t1_count, 1 as _t2_count, `id`, `name`, `age`, `score`
from b

第二步:sum(_t1_count),sum(_t2_count) 后分组

select sum(_t1_count) as sum_t1_count, sum(_t2_count) as sum_t2_count, `id`, `name`, `age`, `score`
from (
select 1 as _t1_count, 0 as _t2_count, `id`, `name`, `age`, `score`
from a
union all
select 0 as _t1_count, 1 as _t2_count, `id`, `name`, `age`, `score`
from b
) as union_table
group by `id`, `name`, `age`, `score`


第三步:把不一致数据写入新的表中(即上面表中sum_t1_count和sum_t2_count不相等的数据)

drop table if exists a_b_diff_20240908;
create table a_b_diff_20240908 as select * from (
select sum(_t1_count) as sum_t1_count, sum(_t2_count) as sum_t2_count, `id`, `name`, `age`, `score`
from (
select 1 as _t1_count, 0 as _t2_count, `id`, `name`, `age`, `score`
from a
union all
select 0 as _t1_count, 1 as _t2_count, `id`, `name`, `age`, `score`
from b
) as union_table
group by `id`, `name`, `age`, `score`
having sum(_t1_count) <> sum(_t2_count)
) as tmp

如果a_b_diff_20240908没有数据则两张表没有差异,比数通过,如有差异如下:

第四步:读取不一致记录表,根据主键(比如id)找出不一致字段并写到结果表中。

第五步:针对不一致字段的数据进行根因分析,如 json 、数组顺序问题、浮点数精度问题等,给出不一致具体原因。

哈希值聚合实现高效一致性校验

针对上面union后sum 再 group by 方式 在数据量大的时候还是非常耗资源和时间的,考虑到比数任务毕竟有70%都是一致的,所以我们可以先采用哈希值聚合比较两表的的值是否一致,使用这种高效的方法先把两表数据一致的任务过滤掉,剩下的再采用上面方法继续比较,因为还要找出是哪个字段哪里不一致。原理如下:

SELECT count (*),SUM(xxhash64(cloum1)^xxhash64(cloum2)^...) FROM tableA 
EXCEPT 
SELECT count(*),SUM(xxhash64(cloum1)^xxhash64(cloum2)^...) FROM tableB

如果有记录为空说明数据一致,不为空说明数据不一致需要采用上面提到union 分组的方法去找出具体字段哪里不一样。

通过哈希值聚合,单个任务比数时间从500s降低到160s,节省大约70%的时间。

找到两张表不一致数据后需要对两张的数据进行分析确定不一致的点在哪里?这里就需要知道表的主键,根据主键逐个比对两张表的其他字段,因此系统会先进行主键的自动探查,以及无主键的兜底处理。

精准定位异常数据实现方法

自动探查主键:实现原理如下

刚开始我们采用的前5个字段找主键的方式,如下:

针对表a的前5个字段 循环比对
select count(distinct id) from a 与 select count(1) from a 比较 ,如相等主键为id ,不相等继续往下执行
select count(distinct id,name) from a 与 select count(1) from a比较,如相等主键为id,name ,不相等继续往下执行
select count(distinct id,name,age) from a 与 select count(1) from a比较,如相等主键为id,name,age ,不相等继续往下执行,直到循环结束

采用上面的方法不一致任务中大约有49.6%任务自动探查主键失败:因此需重点提升主键识别能力。

针对以上主键探查成功率低的问题,后续进行了一些迭代,优化后的主键探查流程如下:

一、先采用sum(hash)高效计算方式进行探查:

1.先算出两张表每个字段的sum(hash)值  。

select sum(hash(id)),sum(hash(name)),sum(hash(age)),sum(hash(score)) from a 
union all 
select sum(hash(id)),sum(hash(name)),sum(hash(age)),sum(hash(score)) from b;

2.找出值相等的所有字段,本案例中为 id, name。

3.对id,name 可能是主键进一步确认,先进行行数校验,如 select count(distinct id,name) from a 的值等于select count(1) from a 则进一步校验,否则进入到第二种探查主键方式。

4.唯一性验证,如果值为0则表示探查主键成功,否则进入到第二种探查主键方式。

slect count(*) from ((select id,name from a ) expect (select id,name from b))

二、传统distinct方式探查:

针对表a的前N(所有字段数/2或者前N、后N等)个字段 循环比对:

1.select count(distinct id) from a与select count(1) from a比较 ,如相等主键为id ,不相等继续往下执行。

2.select count(distinct id,name) from a 与 select count(1) from a比较,如相等主键为id,name ,不相等继续往下执行。

3.select count(distinct id,name,age) from a 与 select count(1) from a比较,如相等主键为id,name,age ,不相等继续往下执行,直到循环结束。

三、全字段排序模拟:

如果上面两种方式还是没有找到主键则把不一致记录表进行全字段排序然后对第一条和第二条记录挨个字段进行分析,找出不一致内容,示例如下:

slect * from a_b_diff_20240908 order by id,name,age,score asc limit 10;


通过以上结果表可以得出两表的age字段不一致 ,score不一致(但按key排序后一致)。

如果以上自动化分析还是找不到不一致字段内容,可以人工确认表的主键后到平台手动指定主键字段,然后点击后续分析即可按指定主键去找字段不一致内容。

通过多次迭代优化找主键策略,找主键成功率从最初的50.4%提升到75%,加上全字段order by排序后最前两条数据进行分析,相当于可以把找主键的成功率提升到90%以上。

根因分析:实现原理如下

当数据不一致时,平台会根据主键找出两个表哪些字段数据不一致并进行分析,具体如下:

  • 精准定位: 明确指出哪条记录、哪个字段存在差异,并展示具体的源数据和目标数据值。
  • 智能根因分析: 内置了多种差异模式识别规则,能够自动分析并提示不一致的可能原因,例如:
  • 精度问题:如浮点数计算1.0000000001与1.0的差异。
  • JSON序列化差异:如{"a":1, "b":2}与{"b":2, "a":1},在语义一致的情况下,因键值对顺序不同而被标记为差异。同时系统会提示排序后一致。
  • 空值处理差异:如NULL值与空字符串""的差异判定。
  • 日期时区转换问题:时间戳在不同时区下表示不同。

  • 比对结果统计: 提供总数据量、一致数据量、不一致数据量及不一致率百分比,为项目决策提供清晰的量化依据。
  • 比数人员根据平台分析的差异原因,决定是否手动标记通过或进行任务修复。
  • 效果展示:

四、比数平台功能介绍

数据比对基本流程

任务生成:三种比对模式

  • 两表比对: 最直接的比对方式。用户只需指定源表与目标表,平台即可启动全量数据比对。它适用于临时比对的场景。
  • 任务节点比对: 一个任务可能输出多个表,逐一配置这些表的比对任务繁琐且易遗漏,任务节点比对模式完美解决了这一问题。用户只需提供任务节点ID,平台便会自动解析该节点对应的SQL代码,提取出所有输出表,并自动生成比对任务,极大地提升任务迁移比对效率。
  • SQL查询比对: 业务在进行SDK迁移只关心某些查询在迁移后数据是否一样,因此需要对用户提交的所有查询SQL进行比对,平台会分别在ODPS和Spark引擎上执行该查询,将结果集导出到两张临时表,再生成比对任务。

前置校验:提前发现问题

在启动耗时的全量比对之前,需要对任务进行前置校验,确保比对是在表结构一致、集群环境正常的情况下进行,否则一旦启动比数会占用大量计算资源,最后结果还是比数不通过,会影响比数平台整体的运行效率。因此比数平台一般会针对如下问题进行前置拦截。

  • 元数据一致性校验: 比对双方的字段名、字段类型、字段顺序、字段个数是否一致。
  • 函数缺失校验: 针对Spark引擎,校验SQL中使用的函数是否存在、是否能被正确识别,避免因函数不支持而导致的比对失败。
  • 语法问题校验: 分析SQL语句的语法结构,确保其在目标引擎中能够被顺利解析,避免使用了某些特定写法会导致数据出现不一致情况,提前发现语法层面问题,并对任务进行改写。

更多校验点如下:




通过增加以上前置校验拦截,比数任务数从每天3000+下降到1500+, 减少50% 的无效比数,其中UDF缺失最多,有效拦截任务1238,缺少函数87个(帮比数同学快速定位,一次性解决函数缺失问题,避免多次找引擎同学陆陆续续添加,节省双方时间成本)。

破解比数瓶颈:资源分配与任务调度优化

由于比数平台刚上线的时候只有计算迁移团队在使用,后面随着更多的团队开始使用,性能遇到了如下瓶颈:

1.资源不足问题: 不同业务(计算迁移、存储迁移、SDK迁移)的任务相互影响,基本比数任务与根因分析任务相互抢占资源。

2.任务编排不合理: 没有优先级导致大任务阻塞整体比数进程。

3.引擎参数设置不合理: 并行度不够、数据分块大小等高级参数。

针对以上问题比数平台进行了如下优化:

  • 按不同业务拆分成多个队列来运行,保证各个业务之间的比数任务可以同时进行,不会相互影响。
  • 根因分析使用单独的队列,与数据比对任务的队列分开,避免相互抢占资源发生“死锁”。
  • 相同业务内部按批次分时段、分优先级运行,保障重要任务优先进行比对。
  • 针对Spark引擎默认调优了公共参数、并支持用户自主设置其他高级参数。

通过以上优化达到到了如下效果:

  • 比数任务从每天22点完成提前至18点前,同时支持比数同学自主控制高优任务优先执行,方便比数同学及时处理不一致任务。
  • 通过优化资源队列使用方式,使系统找不到主键辅助用户自主找主键接口响应时间从58.5秒降到 26.2秒。

五、比数平台收益分享

平台持续安全运行500+天,每日可完成2000+任务比对,有效比数128万+次,0误判。

  • 助力计算迁移团队节省45+人日/月,完成数据分析、离线数仓空间任务的比对、交割。
  • 助力存储迁移团队完成20%+存储数据的迁移。
  • 助力引擎团队完成800+批次任务的回归验证,确保每一次引擎发布的安全及高效。
  • 助力SDK迁移团队完成80%+应用的迁移。

六、未来演进方向

接下来,平台计划在以下方面持续改进:

智能分析引擎: 针对Json复杂嵌套类型的字段接入大模型进行数据根因分析,找出不一致内容。

比对策略优化: 针对大表自动切分进行比对,降低比数过程出现因数据量大导致异常,进一步提升比对效率。

通用方案沉淀: 将典型的比对场景和解决方案能用化,应用到更多场景及团队中去。

七、结语

比数平台是得物在迁移过程中,为了应对海量任务、大数据量、字段内容复杂多样、异常数据难定位等挑战,确保业务迁移后数据准确而专门提供的解决方案,未来它不单纯是一个服务计算迁移、存储迁移、SDK迁移、Spark版本升级等需要的数据比对工具,而是演进为数据平台中不可或缺的基础设施。

往期回顾

1.得物App智能巡检技术的探索与实践

2.深度实践:得物算法域全景可观测性从 0 到 1 的演进之路 

3.前端平台大仓应用稳定性治理之路|得物技术

4.RocketMQ高性能揭秘:承载万亿级流量的架构奥秘|得物技术

5.PAG在得物社区S级活动的落地

文 /Galaxy平台

关注得物技术,每周更新技术干货

要是觉得文章对你有帮助的话,欢迎评论转发点赞~

未经得物技术许可严禁转载,否则依法追究法律责任。