日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

定位排查工作流的计算结果数据量不符合预期的方法

發布時間:2023/11/29 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 定位排查工作流的计算结果数据量不符合预期的方法 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

近期有發現一些用戶在咨詢,為什么數據從數據源出來后,經過了一些計算,結果不符合預期了。最常見的是說,為什么我的數據在Mysql里有xx條,怎么到MaxCompute里算了下結果變了。因為這是兩個不同的系統,我們又沒辦法拿兩邊的記錄直接做個full outer join看看少的是哪些數據。本文拿2個實際的例子,做了簡化方便理解,給出排查過程,希望能給大家帶來一些思路。

問題1

場景模擬

這是一個常見的場景,為什么我數據同步過來后,就直接用SQL做了count,結果就不對了。
先在mysql里創建一張用戶表,并插入一些數據:

create table myuser(uid int,name varchar(30),regTime DATETIME ); insert into myuser(uid,name,regTime) values (1,'Lilei','2017-01-22 01:02:03'); insert into myuser(uid,name,regTime) values (2,'HanMM','2017-01-22 22:22:22');

然后在MaxCompute里配置了個接受的表:

create table ods_user(uid bigint,name string,regTime datetime) partitioned by(ds string);

然后配置了一個同步任務和SQL任務用于統計結果數據條數如圖:

CREATE TABLE IF NOT EXISTS dws_usercnt (cnt BIGINT ) PARTITIONED BY (ds STRING);INSERT OVERWRITE TABLE dws_usercnt PARTITION (ds='${bdp.system.bizdate}') SELECT COUNT(*) AS cnt FROM ods_user;

最后做成工作流

任務上線后,跑了第一天,結果還是對的。

odps@ >read dws_usercnt; +------------+------------+ | cnt | ds | +------------+------------+ | 2 | 20170122 | +------------+------------+

但是第二天插入幾條新的數據后,為什么統計結果就不對了呢:

odps@ >read dws_usercnt; +------------+------------+ | cnt | ds | +------------+------------+ | 2 | 20170122 | | 6 | 20170123 | +------------+------------+

預期的是第二天的數據是4。

排查解決

我們需要先理清楚數據的走向。這個例子的思路很簡單,數據從Mysql同步到MaxCompute的表里,然后針對結果表做了匯總。走向圖為myuser(MySql)=>ods_user(MaxCompute)=>dws_usercnt(MaxCompute)。
目前我們通過在Mysql里查詢,已經確認Mysql里就是4條記錄,dws_usercnt里的結果也看到是6,那需要先定位到是ods_user里的結果是多少條,從而定位到是同步的時候出現的問題,還是同步后匯總出現的問題。
我們先看了一下ods_user,先用select count(*) from ods_user;看到為6。因為是分區表,對么個分區查一下,用select count(*) as cnt,ds from ods_user group by ds;,發現結果是

+------------+----+ | cnt | ds | +------------+----+ | 2 | 20170122 | | 4 | 20170123 | +------------+----+

然后配合同步任務的日志

我們可以看到,我們一共同步了4條數據(如果是這里對不上的話,我們需要檢查一下同步任務的where表達式對不對了)。然后最后匯總的時候,我們看下日志:

我們可以看到我們在SQL里是訪問了2個分區的數據做了匯總。

所以這個問題的原因是在同步的時候,是做了每天的全量同步,但是在SQL匯總的時候,當成是增量同步了,或者是忘記寫分區的過濾條件了,導致匯總是查詢了全部的數據。針對這個問題的解法是先要確定這個表到底是需要增量同步,還是需要全量同步。如果是需要增量同步,那需要修改同步的時候,在配置項里配置過濾條件只同步增量數據。如果是需要每天同步全量數據,那在匯總的時候,就只需要讀最后一個分區就可以了。
另外關于增量同步的配置方法,可以參考這篇文檔。

問題2

場景模擬

有一些用戶希望針對數據的某個屬性進行分區,比如希望根據學生的年級進行分區。
我們先在Mysql里創建一張學生表,插入一些數據

create table student(id int,name varchar(30),grade varchar(1)); insert into student(id,name,grade) values(1,'Lilei',1); insert into student(id,name,grade) values(2,'HanMM',2); insert into student(id,name,grade) values(3,'Jim',3);

同樣的,在MaxCompute這邊也需要配置一個ODS表和一個DWD表

create table ods_student(id bigint,name string,grade string) partitioned by(ds string) ; create table dwd_student(id bigint,name string)partitioned by(grade string) ;

然后配置一個同步任務:

和對應的SQL任務

insert overwrite table dwd_student partition(grade ) select id,name,grade from ods_student where ds = '${bdp.system.bizdate}';

同步后看到第一天的結果是對的。
后來這些學生都到了新年級了,3年級的學生畢業了

update student set grade = grade+1; delete from student where grade>3;--已經畢業的

再同步一下,不對了,數據怎么還是3條。

排查解決

我們這里測試的數據比較少,可以直接select出來一看就明白了。但是真實的業務里,我們的數據可能有數以億計,根本沒辦法肉眼看出來。所以還是以前的思路,我們先理清楚數據的走向。數據是從student(Mysql)=>ods_student(MaxCompute)=>dwd_student(MaxCompute)。
第二天,Mysql里的student表里數據其實是只有2條了。而ods_student表里的最新的分區也是2條。但是dwd_student里是3條。這說明ods=>dwd的過程中,數據出了問題。這個就是一個SQL問題了。我們用SQL

--里面的ds的值記得換掉 select ods.grade,dwd.grade,ods.cnt,dwd.cnt from (select count(*) as cnt,grade from ods_student where ds= '${bdp.system.bizdate}' group by grade) ods full outer join (select count(*) as cnt,grade from dwd_student group by grade) dwd on ods.grade = dwd.grade where coalesce(ods.cnt,0) <> coalesce(dwd.cnt,0) ;+-------+--------+------------+------------+ | grade | grade | cnt | cnt | +-------+--------+------------+------------+ | NULL | 1 | NULL | 1 | +-------+--------+------------+------------+

看到1年級,數據里ods表里沒有1年級的數據了,但是dwd里還是有1條1年級的數據。這下就很清楚了,這條數據是第一天的數據。后來升了年級后,用Insert Overwrite覆蓋寫入的時候,2年級和3年級是有新數據進來的,所以數據被覆蓋了。但是1年級因為沒有數據進來,所以也沒覆蓋。我們也可以用desc partition命令看下每個分區的創建時間和修改時間來確認這個問題。

對于這種情況,其實這種分區方法有一些問題的。建議dwd表里不要做這樣的分區。如果確實需要分區,也不要直接在歷史分區上做覆蓋寫入,可以寫到新的分區里,比如做2級分區,1級分區是日期字段,二級分區才是這樣的業務分區字段。

本文使用的產品涉及大數據計算服務(MaxCompute),地址為https://www.aliyun.com/product/odps
配合大數據開發套件 https://data.aliyun.com/product/ide 完成的。
如果有問題,可以加入我們的釘釘群來咨詢

總結

以上是生活随笔為你收集整理的定位排查工作流的计算结果数据量不符合预期的方法的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。