Maxcompute数据上云一致性比对

news2024/11/22 16:09:36

我写过很多如何去对数、如何批量对数的技术文档,最近项目遇到这个问题,我才发现在官方博客上还没有发布过这个课题的文章。这就像灯下黑,太长用到的知识点,反而没有意识到其重要性。

注:这里对数的场景就是指在阿里云平台使用 dataworks 等大数据开发工具集成业务系统数据库( oracle 等)数据上云到 maxcompute 的场景,所以,示例的SQL也是针对 maxcompute

先说说一般业务上怎么对数的,我们做了一个报表,出了一个数据“某个产品卖了30个”。这个不只是在大数据平台上有这个数据,在业务系统也有这个数据,这些统计动作在业务系统通过程序和人工也会有一份,一般做好报表后会先对这个数据。

所以,第一线反馈回来的数据就是这个汇总数据不一致的问题。然而这个结果是非常概括的,因为就像我感觉这个月工资少发了5毛一样,如果我不看我的工资条我其实不知道自己是不是少发了。工资条不只是一个汇总数据,里面有我税前工资、奖金(浮动)、社保、扣税等一系列的明细数据,这些数据让我去判断我是不是少了5毛,而加工过的数据是复杂的。

说到这里,我其实就像表达一个事情,对数是要对明细数据。这是一切计算后事实的基础,可以拿出来作证的。

所以,两边都查一下这个汇总值使用的表的对应的记录,比如说查询“今天这个产品ID的售卖记录”。结果就发现业务系统有31笔,而大数据平台有30笔。

即便到了这里,其实我们仍然不知道期间发生了什么,为什么会丢失数据。另外我们还不知道其他商品ID的数据是不是也有丢失的,还有其他的表的数据是不是也会发生类似的情况。

1. 明细数据比对

既然最终都是对明细数据,那么我是不是可以直接比对明细数据呢?回答是:正确。

一般发生这种情况,首先要比对业务系统和大数据平台两个表的数据。

在这里插入图片描述

1-再利用全量集成工具,从业务系统的数据库全量抽取一遍数据到大数据平台。比对数据一定要把数据放到一起,隔空比对是不存在的。因为大数据平台的容量是数百倍于业务系统的,所以,一般都在大数据平台比对。(这里有一个悖论,如果集成工具本身就有缺陷,导致抽取过程中就丢数据,岂不是永远没办法比对了。所以,如果对这个工具也不确定就得从数据库导出数据到文件,然后再加载到某个数据库上去比对。在这里,通过我对离线集成这个产品的常年使用经验,这个工具是非常可靠的,还未遇到过这个问题。)

在这里插入图片描述

2-根据主键关联,比对2个表中的主键的差异。如果是上面提到的记录丢失的问题,这一步做完就很容易比对出来了。这里还会发现一个问题,就是业务系统的表是不断变化的,所以,这时与大数据平台的表对比会有差异。这个差异的核心原因是:大数据平台的表是业务系统表在每日的日末(00:00:00)的一个时点数据,而业务系统的数据是一直在变化的。所以,即便有差异超出预期也不要惊慌。如果是使用实时同步可以从归档日志中获取到这期间数据的每一条变化,可以追溯变化原因。如果没有实时同步,也可以通过表中与时间相关字段去判断数据是否被更新掉。要是什么都没有(这种情况也是存在的),那就去骂骂设计表的业务系统开发(没错,是他们的锅),也可以跟业务去详细了解一下,这行记录是不是今天做的,而不是昨天。

在这里插入图片描述

3-还有一种情况,就是主键一致,数据内容(主键之外的字段)不一致。这种情况,还是需要考虑数据变化的情况,可以从日志、时间字段、业务等几个角度去比对。如果发现数据确实不符合预期,就需要查询同步工具的问题。

2 . 比对SQL分析

在上面的章节,我描述了比对今天新抽取的全量表和上日在maxcompute上使用前日全量和上日增量合并的上日全量的环节。比对两张表集合是否一致的SQL方法其实比较简单,大家第一时间就会想到集合操作。在oracle里面有Minus、except,同样在maxcompute里面也有。但是为了便于分析问题,我还是自己写了一个SQL。示例SQL(maxcompute sql)如下:

–限定日期分区,比对上日

select count(t1.BATCH_NUMBER) as cnt_left

,count(t2.BATCH_NUMBER) as cnt_right

,count(concat(t1.BATCH_NUMBER,t2.BATCH_NUMBER)) as pk_inner

,count(case when t1.BATCH_NUMBER is not null and t2.BATCH_NUMBER is null then 1 end) as pk_left

,count(case when t2.BATCH_NUMBER is not null and t1.BATCH_NUMBER is null then 1 end) as pk_right

,count(case when nvl(t1.rec_id ,‘’) = nvl(t2.rec_id ,‘’) then 1 end) as col_diff_rec_id

,count(case when nvl(t2.rec_creator ,‘’) = nvl(t1.rec_creator ,‘’) then 1 end) as col_diff_rec_creator

,count(case when nvl(t2.rec_create_time,‘’) = nvl(t1.rec_create_time,‘’) then 1 end) as col_diff_rec_create_time

from ods_dev.o_rz_lms_im_timck01 t1 – 开发环境重新初始化的今天数据

full join ods.o_rz_lms_im_timck01 t2 – 生产环节昨日临时增量合并的数据

on t1.BATCH_NUMBER =t2.BATCH_NUMBER

and t1.IN_STOCK_TIME =t2.IN_STOCK_TIME

and t1.OP_NO =t2.OP_NO

and t1.STOCK_CODE =t2.STOCK_CODE

and t1.YP_ID =t2.YP_ID

and t2.ds=‘20230426’

where t1.ds=‘20230426’

;

–cnt_left 9205131 说明:左表有记录数 9205131

–cnt_right 9203971 说明:右表有记录数 9203971

–pk_inner 9203971 说明:主键关联一致记录数 9203971

–pk_left 1160 说明:左表比右表多记录数 1160

–pk_right 0 说明:右表比左表多有记录数 0

–col_diff_rec_id 9203971 说明:字段一致记录数与主键一致相同,说明关联上的两个表该字段一致

–col_diff_rec_creator 9203971 说明:同上

–col_diff_rec_create_time 9203971 说明:同上

在上面的例子中,左表是今天重新初始化的数据,右表是在maxcompute上merge的上日全量数据。在比对之前,我们其实就应该了解这两个表的数据必然是不一致的。虽然是同一张表,但是时点是不一致的。

不一致包括几种:

1-t1表中存在的主键,在t2表中不存在;

2-t2表中存在的主键,在t1表中不存在;

3-t1和t2表中都存在的主键,但是主键之外的字段值不一致;

4-t1和t2表中都存在的主键,但是主键之外的字段值一致;

除去第4中情况,其他3种状态都是两个表的值不一致,都需要进一步核查。如果是正常情况下,第1种情况是在今天零点以后新insert到业务库中的数据,第2种情况是今天零点以后delete的业务库中的数据,第3种情况是今天零点之后update的数据,第4种情况是业务表中今天零点之后未被更新的数据。

了解这些状况后,我们就可以依据可循去识别

3 . D ataworks 实时同步日志表

如果同步才有的是DataWorks的离线同步,其实观测以上数据变化是有些困难的。如果我们采用实时同步,数据库数据的变化是都会保留下来的。上一章节中提到的变化,都可以从日志中观测到。下面SQL,就是我查询这个变化使用的SQL,查询(dataworks实时数据同步日志表)示例SQL如下:

select from_unixtime(cast(substr(to_char(execute_time),1,10) as bigint)) as yy

,get_json_object(cast(data_columns as string),“$.rec_id”) item0

,x.*

from ods.o_rz_lms_odps_first_log x – 实时同步数据源 o_rz_lms 的日志表

where year=‘2023’ and month=‘04’ and day>=‘10’ --数据区间限制

–and hour =‘18’

and dest_table_name=‘o_rz_lms_im_timck01’ --数据表限制

– 以下为主键字段

and get_json_object(cast(data_columns as string),“$.yp_id”) =‘L1’

and get_json_object(cast(data_columns as string),“$.batch_number”) =‘Y1’

and get_json_object(cast(data_columns as string),“$.in_stock_time”) =‘2’

and get_json_object(cast(data_columns as string),“$.op_no”) =‘9’

and get_json_object(cast(data_columns as string),“$.stock_code”) =‘R’

–and operation_type=‘D’

order by execute_time desc

limit 1000

;

在这里插入图片描述

execute_time 数据操作时间

operation_type 操作类型 增删改UDI

sequence_id 序列号,不会重复

before_image 修改前数据

after_image 修改后数据

dest_table_name 操作的表名

data_columns 操作的数据内容JSON

DataWorks的实时同步的数据源每隔一段时间就会实时写入到一张以“数据源名+_odps_first_log”命名的表中,表有年、月、日、时四级分区。该表的主键并不是数据操作时间,而是序列号“execute_time”,所以,一行数据主键的更新顺序是按照“execute_time”更新。

一行数据更新是有前后两个状态的,所以有“before_image 修改前数据、after_image 修改后数据”这两个字段来标识前后状态。

数据是在字段“data_columns”中,以JSON格式存储。为了识别其中的某一行数据,我使用函数解析了对应的字段,以此来确定自己要的数据。

4 . 持续的质量保障

到这里,我并未讲如何去处理数据不一致的情况。如果确实发现数据不一致,可用的处理方式就是重新初始化全量数据。在这里要强调一点,如果离线全量集成工具是可信的,全量初始化的数据就不会丢。但是如果这种方式不可信,则就要更换方法。

在很多情况下,源端做一些业务变更也会偶发数据异常。在数据丢失原因未查明的情况下,需要经常的去做数据一致性的比对,做到防患于未然。所以,日常监控数据数据一致性也是非常重要的。

【MaxCompute 已发布免费试用计划,为数仓建设提速】新用户可 0 元领取 5000CU*小时计算资源与 100GB 存储,有效期 3 个月。 立即领取>>

欢迎各位开发者加入大数据计算 MaxCompute 社区, https://developer.aliyun.com/group/maxcompute

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/618630.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

docker 装机/卸载 Mysql

1、首先,需要安装Docker。可以使用以下命令安装: > yum install docker 2、安装完成后,启动Docker服务: > systemctl start docker3、CentOS7环境下的Docker使用 docker快速部署mysql数据库并初始化 docker快速部署mysq…

Power BI API调用注意事项 (By Power Automate)

注:本文最初发布于https://d-bi.gitee.io和medium, 2023年6月迁移至CSDN 前述 本站关于实现Power BI REST API的博文已有许多,包括: Power BI REST API有多强大?PBI开发者必读Power BI REST API实战教程:PowerQuery为…

基于SSM的便利店系统

✌全网粉丝20W,csdn特邀作者、博客专家、CSDN新星计划导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取项目下载方式🍅 一、项目背景介绍: 基于SSH的便利店系统是…

Java中方法的重载与重写

文章目录 前言方法重载方法重写 前言 提示:这里可以添加本文要记录的大概内容: 方法的重载与重写容易混,所以单独拿出来比较 提示:以下是本篇文章正文内容,下面案例可供参考 方法重载 在同一个类中,允…

springcloud-alibaba (06)RocketMQ控制台安装与启动

RocketMQ控制台 ✨让你的消息传输更高效✨ 如果你是一名开发者,或者是对消息传输有需求的企业用户,那么你肯定不陌生于 RocketMQ,它是一个高可用、高可靠、高性能、分布式消息中间件。但是有时候,在 Windows 上安装和启动 Rocke…

生产环境可用的 Seata-go 1.2.0 来啦!!!

文|刘月财(GitHub ID:luky116) 360 服务端开发专家 Seata-go 项目负责人 本文 2752 字 阅读 7 分钟 发布概览 Seata-go 1.2.0 版本支持 XA 模式。XA 协议是由 X/Open 组织提出的分布式事务处理规范,其优点是对业务代码无侵入。当前…

小巧长续航的主动降噪耳机,更轻更好用,QCY ArcBuds上手

我平时听歌、玩游戏的时候喜欢戴上一副蓝牙耳机,这种耳机选择很多,这几年进步还很快,市面上有很多价格合理、音质出色的选择。我目前用的是一款QCY ArcBuds,这款耳机支持主动降噪,户外使用体验不错,而且它做…

Dockerfile实现LNMP

systemctl stop firewalld systemctl disable firewalld setenforce 0 docker network create --subnet172.18.0.0/16 --opt "com.docker.network.bridge.name""docker1" mynetwork #部署nginx(容器IP 为 172.18.0.10) mkdir /o…

一文讲解 基于C++手写Rpc项目

目录 github 预备知识 集群和分布式 单机聊天服务器 集群聊天服务器 分布式聊天服务器 从集群式 到 分布式聊天服务器 看来只有好处 ,但代价是什么? rpc 的 通信原理 remote procedure call 分布式通信 手写的rpc部分 protobuf>json 好处? 介绍protobuf protob…

RabbitMQ - 死信队列

RabbitMQ - 死信队列 死信的概念死信的来源死信实战死信之TTl死信之最大长度死信之消息被拒 死信的概念 先从概念解释上搞清楚这个定义,死信,顾名思义就是无法被消费的消息,字面意思可以这样理 解,一般来说,producer …

【进程间通信:管道】

目录 1 进程间通信介绍 1.1 进程间通信目的 1.2 进程间通信发展 1.3 进程间通信分类 2 管道 2.1 什么是管道 2.2 匿名管道 2.2.1 匿名管道的使用 2.2.2 使用匿名管道创建进程池 2.3 管道读写规则 2.4 匿名管道特点 2.5 命名管道 2.5.1 概念 2.5.2 使用 1 进程间通…

Learning C++ No.28 【C++11语法实战】

引言: 北京时间:2023/6/5/9:25,今天8点45分起床,一种怎么都睡不够的感觉,特别是周末,但是如果按照我以前的睡觉时间来看,妥妥的是多睡了好久好久,并且昨天也睡了一天,哈…

C#,码海拾贝(32)——计算“实对称三对角阵的全部特征值与特征向量的”之C#源代码

using System; namespace Zhou.CSharp.Algorithm { /// <summary> /// 矩阵类 /// 作者&#xff1a;周长发 /// 改进&#xff1a;深度混淆 /// https://blog.csdn.net/beijinghorn /// </summary> public partial class Matrix {…

第⑩讲:Ceph集群CephFS文件存储核心概念及部署使用

文章目录 1.CephFS文件存储核心概念1.1.CephFS文件存储简介1.2.CephFS文件存储架构1.3.CephFS文件系统的应用场景与特性 2.在Ceph集群中部署MDS组件3.在Ceph集群中创建一个CephFS文件存储系统3.1.为CephFS文件存储系统创建Pool资源池3.2.创建CephFS文件系统3.3.再次观察Ceph集群…

chatgpt赋能python:从后到前查找Python字符串

从后到前查找Python字符串 Python是一种流行的编程语言&#xff0c;广泛用于Web开发、数据科学和算法设计等领域。其中&#xff0c;字符串是Python编程中的重要概念之一&#xff0c;它不仅可以表示文本&#xff0c;还可以进行各种处理。本篇文章将介绍Python字符串从后到前的查…

chatgpt赋能python:Python如何运行最方便

Python 如何运行最方便 Python 是一种高级编程语言&#xff0c;被广泛使用于各类领域。由于其简单易学&#xff0c;可读性高&#xff0c;适用于不同平台的特性&#xff0c;Python 已成为计算领域、Web 开发、数据分析等领域的首选语言之一。如果您正在学习 Python 或需要对其进…

【SQL】Oracle数据库安装并实现远程访问

文章目录 前言1. 数据库搭建2. 内网穿透2.1 安装cpolar内网穿透2.2 创建隧道映射 3. 公网远程访问4. 配置固定TCP端口地址4.1 保留一个固定的公网TCP端口地址4.2 配置固定公网TCP端口地址4.3 测试使用固定TCP端口地址远程Oracle 前言 Oracle&#xff0c;是甲骨文公司的一款关系…

RTL8380MI/RTL8382MI管理型交换机系统软件操作指南六:RSTP/快速生成树协议

对RSTP/快速生成树协议进行详细的描述&#xff0c;主要包括以下内容&#xff1a;STP概述、RSTP介绍、全局配置、端口配置、RSTP信息、端口信息. 1.1 STP概述 STP&#xff08;Spanning Tree Protocol&#xff09;是生成树协议的英文缩写。STP协议中定义了根桥&#xff08;RootB…

报表生成器FastReport .Net用户指南:显示数据列、HTML标签

FastReport .Net是一款全功能的Windows Forms、ASP.NET和MVC报表分析解决方案&#xff0c;使用FastReport .NET可以创建独立于应用程序的.NET报表&#xff0c;同时FastReport .Net支持中文、英语等14种语言&#xff0c;可以让你的产品保证真正的国际性。 FastReport.NET官方版…

『 前端三剑客 』:HTML常用标签

HTML中常用标签 HTML中常用标签一 . 认识HTML标签二 . HTML标签介绍三 . 案例应用 一 . 认识HTML标签 在HTML中标签是以成对的结构出现的,在HTML当中代码是通过标签来组织的 , 下面通过见得的Hello World的展现来显示歘HTML 标签的结构 <html><head></head>…