Galaxy比数平台功能介绍及实现原理|得物技术
得物经过10年发展,计算任务已超10万+,数据已经超200+PB,为了降低成本,计算引擎和存储资源需要从云平台迁移到得物自建平台,计算引擎从云平台Spark迁移到自建Apache Spark集群、存储从ODPS迁移到OSS。 在迁移时,最关键的一点是需要保证迁移前后数据的一致性,同时为了更加高效地完成迁移工作(目前计算任务已超10万+,手动比数已是不可能),因此比数平台便应运而生。 现状痛点: 在前期迁移过程中,迁移同学需要手动join两张表来识别不一致数据,然后逐条、逐字段进行人工比对验证。这种方式在任务量较少时尚可应付,但当任务规模达到成千上万级别时,就无法实现并发快速分析。 核心问题: 现状痛点: 迁移同学在识别出不一致数据后,需要通过肉眼观察来定位具体问题,经常导致视觉疲劳和分析效率低下。 核心问题: 基于以上挑战,数据比对系统需要实现以下核心目标: 比数方法调研 待比对两表数据大小:300GB,计算资源:1000c 经过调研分析比数平台采用第二种和第三种相结合的方式进行比数。 先Union再分组数据一致性校验原理 假如我们有如下a和b两表张需要进行数据比对 表a: 针对上面的查询结果,如果数量不一致则退出比对,待修复后重新比数;数量一致则继续字段值比较。 字段值比较: 第一步:union a 和 b 第二步:sum(_t1_count),sum(_t2_count) 后分组 如果a_b_diff_20240908没有数据则两张表没有差异,比数通过,如有差异如下: 第四步:读取不一致记录表,根据主键(比如id)找出不一致字段并写到结果表中。 第五步:针对不一致字段的数据进行根因分析,如 json 、数组顺序问题、浮点数精度问题等,给出不一致具体原因。 哈希值聚合实现高效一致性校验 针对上面union后sum 再 group by 方式 在数据量大的时候还是非常耗资源和时间的,考虑到比数任务毕竟有70%都是一致的,所以我们可以先采用哈希值聚合比较两表的的值是否一致,使用这种高效的方法先把两表数据一致的任务过滤掉,剩下的再采用上面方法继续比较,因为还要找出是哪个字段哪里不一致。原理如下: 如果有记录为空说明数据一致,不为空说明数据不一致需要采用上面提到union 分组的方法去找出具体字段哪里不一样。 通过哈希值聚合,单个任务比数时间从500s降低到160s,节省大约70%的时间。 找到两张表不一致数据后需要对两张的数据进行分析确定不一致的点在哪里?这里就需要知道表的主键,根据主键逐个比对两张表的其他字段,因此系统会先进行主键的自动探查,以及无主键的兜底处理。 自动探查主键:实现原理如下 刚开始我们采用的前5个字段找主键的方式,如下: 采用上面的方法不一致任务中大约有49.6%任务自动探查主键失败:因此需重点提升主键识别能力。 针对以上主键探查成功率低的问题,后续进行了一些迭代,优化后的主键探查流程如下: 一、先采用sum(hash)高效计算方式进行探查: 1.先算出两张表每个字段的sum(hash)值 。 2.找出值相等的所有字段,本案例中为 id, name。 3.对id,name 可能是主键进一步确认,先进行行数校验,如 select count(distinct id,name) from a 的值等于select count(1) from a 则进一步校验,否则进入到第二种探查主键方式。 4.唯一性验证,如果值为0则表示探查主键成功,否则进入到第二种探查主键方式。 二、传统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 ,不相等继续往下执行,直到循环结束。 三、全字段排序模拟: 如果上面两种方式还是没有找到主键则把不一致记录表进行全字段排序然后对第一条和第二条记录挨个字段进行分析,找出不一致内容,示例如下: 如果以上自动化分析还是找不到不一致字段内容,可以人工确认表的主键后到平台手动指定主键字段,然后点击后续分析即可按指定主键去找字段不一致内容。 通过多次迭代优化找主键策略,找主键成功率从最初的50.4%提升到75%,加上全字段order by排序后最前两条数据进行分析,相当于可以把找主键的成功率提升到90%以上。 根因分析:实现原理如下 当数据不一致时,平台会根据主键找出两个表哪些字段数据不一致并进行分析,具体如下: 在启动耗时的全量比对之前,需要对任务进行前置校验,确保比对是在表结构一致、集群环境正常的情况下进行,否则一旦启动比数会占用大量计算资源,最后结果还是比数不通过,会影响比数平台整体的运行效率。因此比数平台一般会针对如下问题进行前置拦截。 更多校验点如下: 由于比数平台刚上线的时候只有计算迁移团队在使用,后面随着更多的团队开始使用,性能遇到了如下瓶颈: 1.资源不足问题: 不同业务(计算迁移、存储迁移、SDK迁移)的任务相互影响,基本比数任务与根因分析任务相互抢占资源。 2.任务编排不合理: 没有优先级导致大任务阻塞整体比数进程。 3.引擎参数设置不合理: 并行度不够、数据分块大小等高级参数。 针对以上问题比数平台进行了如下优化: 通过以上优化达到到了如下效果: 平台持续安全运行500+天,每日可完成2000+任务比对,有效比数128万+次,0误判。 接下来,平台计划在以下方面持续改进: 智能分析引擎: 针对Json复杂嵌套类型的字段接入大模型进行数据根因分析,找出不一致内容。 比对策略优化: 针对大表自动切分进行比对,降低比数过程出现因数据量大导致异常,进一步提升比对效率。 通用方案沉淀: 将典型的比对场景和解决方案能用化,应用到更多场景及团队中去。 比数平台是得物在迁移过程中,为了应对海量任务、大数据量、字段内容复杂多样、异常数据难定位等挑战,确保业务迁移后数据准确而专门提供的解决方案,未来它不单纯是一个服务计算迁移、存储迁移、SDK迁移、Spark版本升级等需要的数据比对工具,而是演进为数据平台中不可或缺的基础设施。 1.得物App智能巡检技术的探索与实践 2.深度实践:得物算法域全景可观测性从 0 到 1 的演进之路 3.前端平台大仓应用稳定性治理之路|得物技术 4.RocketMQ高性能揭秘:承载万亿级流量的架构奥秘|得物技术 5.PAG在得物社区S级活动的落地 关注得物技术,每周更新技术干货 要是觉得文章对你有帮助的话,欢迎评论转发点赞~ 未经得物技术许可严禁转载,否则依法追究法律责任。一、背景
二、数据比对关键挑战与目标
关键挑战一:如何更快地完成全文数据比对
关键挑战二:如何精准定位异常数据
比数核心目标
三、解决方案实现原理
快速完成全文数据比对方法



表b:
表行数比较:select count(1) from a ;select count(1) from 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
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
SELECT count (*),SUM(xxhash64(cloum1)^xxhash64(cloum2)^...) FROM tableA
EXCEPT
SELECT count(*),SUM(xxhash64(cloum1)^xxhash64(cloum2)^...) FROM tableB精准定位异常数据实现方法
针对表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 ,不相等继续往下执行,直到循环结束
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;slect count(*) from ((select id,name from a ) expect (select id,name from b))slect * from a_b_diff_20240908 order by id,name,age,score asc limit 10;
通过以上结果表可以得出两表的age字段不一致 ,score不一致(但按key排序后一致)。



四、比数平台功能介绍
数据比对基本流程

任务生成:三种比对模式

前置校验:提前发现问题



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

五、比数平台收益分享
六、未来演进方向
七、结语
往期回顾
文 /Galaxy平台