以上都是資料質量的問題。本文嘗試找到一種方法,能夠儘可能的發現數據質量問題並解決之。
談到資料質量,就必須瞭解評價資料質量的維度。DAMA UK 提出了資料質量的六個核心維度,見圖1。
注:DAMA International (國際資料管理協會)成立於1980年,是一個由技術和業務專業人員組成的國際性資料管理專業協會,作為一個非營利的機構,獨立於任何廠商,旨在世界範圍內推廣並促進資料管理領域的概念和最佳實踐,為數字經濟打下理論和實踐基礎。全球會員近萬人,在世界48個國家成立有分會。
在上面任何一個環節中,都可能出現數據質量的問題,提升資料質量需要從資料接入、資料加工、資料產出、資料應用、效果跟蹤等全流程進行把控,全域性觀很重要,不拘一點,才能看的更全面。
資料質量是資料的生命線,沒有高質量的資料,一切資料分析、資料探勘、資料應用的效果都會大打折扣,甚至出現完全錯誤的結論,或者導致資損。然而資料質量問題卻是廣泛存在的,且治理的難度很大,因為資料的生產、加工、流轉、應用涉及到業務運營、生產系統、資料系統、資料產品等上下游鏈路幾十個環節,每個環節都可能引入資料質量問題。
集團很多BU都有成體系的解決資料質量的方案,集團也有很多工具來解決資料質量問題。本文不詳細介紹此類工具的使用,主要聚焦在資料開發過程中因為資料研發同學經驗不足而導致的資料質量問題。
如圖3所示,我認為有三種方法可以在一定程度上解決資料質量的問題。
資料探查的定義一般為:資料探查是探索源資料的過程,用來理解資料結構、資料內容、資料關係以及為資料工程識別可能存在的問題。
資料探查不止用在資料質量領域,數倉開發、資料遷移等都需要對源資料進行資料探查。資料倉庫的所有資料基礎都是源資料(ODS),在開發數倉之前,需要對源資料進行探查,才能保證產出的資料倉庫的準確性。
題庫業務的資料缺少打點,資料建設主要基於業務架構的一些中間表和結果表,在開發前期,沒有意識到資料探查的重要性,導致資料的準確性有嚴重問題,資料研發出現了大量的返工現象。
dataworks提供了資料探查的功能,可以統計基本資訊、資料分佈、topN、直方圖等。但我試了幾次一直是探查中,易用性還不是太好。
本部分介紹資料探查的一些常見方法,不成體系,只是開發過程中遇到的問題,供參考。
資料總量探索是對ods的總體資料有初步認知,可以透過資料地圖的分割槽資訊確認,也可以透過寫sql計算。
資料總量探查時要探查每日增量資料總量、全量資料總量(如有需要)。
一般情況下,資料總量探查結果要與業務方或者上游資料提供方確認是否符合預期。
在做資料探查時,需要探查資料產出時間和生命週期,對後續的任務排程和補資料有一定的幫助。
資料分佈探查是資料探查中最重要的部分,可以探測不同維度下資料的分佈情況。一般情況下,有如下寫法。
SELECTresult
,COUNT(*)
FROM xxx.table_name
WHERE dt = 'xxxxx'
GROUPBYresult ;
列舉值探查是上面資料分佈探查的一種特例,探查某些維度的列舉值是否合理。一般情況下sql如下。
SELECTDISTINCTresult
FROM xxx.table_name
WHERE dt = 'xxxxx' ;
這種探查,可以探查出很多問題,比如上游生成某列舉值只有0和1,但探查的時候探查出為空等。
某些情況下,上游生成某些欄位唯一(不一定是主鍵),也需要對此類情況探查,不然做join時容易出現數據膨脹問題。探查sql一般如下。
SELECTCOUNT(item_id)
,COUNT(DISTINCT item_id)
FROM xxx.table_name
WHERE dt = 'xxxxx' ;
對於某些數值類的值,必要情況下可以做一下極值探查,比如求最大值、最小值、平均值。這樣可以儘快發現源資料中的髒資料。
對於異常值也要探查一下,比如0、null、空字串等。
通常情況下,一張表中不同欄位直接有關聯關係。比如曝光欄位和曝光時長之間有關聯關係,有曝光的一定有曝光時長,或者曝光時長大於0的情況下一定有曝光。
或者uv一定大於pv,這種方法可以對dws表進行驗證。
此種情況屬於跨表探查。不同的表在做join時,除了探查join條件是否成功,還需要探查join得到的數量是否符合預期。
在題庫業務中,出現過因為系統bug,下游表的join條件中,有3%左右的資料join不上,但因為前期沒有做此方面的資料探查,導致用了很久才發現此問題。
還有一種情況是業務上兩張表必須join上,比如消費表所有的使用者都應該出現在使用者表,或者所有內容都應該出現在內容維表等。
SELECTcount(DISTINCT a.itemid)
FROM xxx.yyy_log a
LEFTJOIN (
SELECT itemid
FROM xxx.zzzz
WHERE ds = '20210916'
) b
ON a.itemid = b.itemid
WHERE a.dt = '20210916'
AND b.itemid ISNULL ;
在某些情況下,需要從海量資料中,透過某些過濾條件撈出所需資料。比如客戶端打點的規範是一致的,不同的端的使用者日誌都在一張表中,如果只分析某種資料,需要對資料進行過濾。
此過濾條件一般由業務方同學提供,在資料探查階段要先做條件過濾,與業務方同學溝透過濾之後的資料是否符合預期。
屬於表唯一性探查。此問題與唯一值的現象類似,都是資料有重複。
不同之後在於,某些情況下,雖然資料提供方稱了某些列唯一,但在某些業務場景下,資料就是不唯一的。比如題庫的某業務中,業務方開始說不同線索得到的q_id不一致,然而q_id來自url,在業務上url確實存在重複的情況,所以q_id有重複的情況。
但在另一種資料重複的問題往往不是業務如此,而是系統bug導致的。比如某種業務中,一本書理論上處理完之後不應該再次處理,但系統的bug導致出現一本書被處理多次的情況。
對於第一種情況,我們在建模時要考慮業務複雜性;而第二種情況,我們要做的是找到有效的資料,去掉髒資料。
資料鏈路中資料漏斗是很關鍵的資料,在做初步資料探查時,也需要關注資料漏斗。每一層資料丟棄的數量(比例)都要和業務方確認。
比如某一個入庫流的處理資料數量和入庫數量對比,或者入庫數量和入索引數量等,如果比例出現了很大的問題,需要找上游業務方修正。
“刷子使用者”的發現就是一種常見的資料分佈不合理,比如某個user的一天的pv在5000以上,我們大機率懷疑是刷子使用者,要把這些使用者從統計中剔除,並要找到資料上游過濾掉類似使用者。
SELECT userid
,count(*) AS cnt
FROM xxx.yyyy_log
WHERE dt = '20210913'
GROUPBY userid
HAVING cnt > 5000 ;
上面描述了很多資料探查問題,如果認真的做了資料探查,可以避免很多資料質量問題。本部分描述在資料開發環節中開發同學因為經驗等原因導致的資料質量問題。
此問題往往發生在沒有對join條件進行唯一性檢查的情況下。因為右邊資料不唯一,發生笛卡爾積,導致資料膨脹。如果是某些超大表,除了資料結果不對之外,會產生計算和儲存的浪費。
還有一種情況,在單一分割槽中資料是唯一的,但join時沒有寫分割槽條件,導致多個分割槽同時計算,出現數據爆炸。
此問題也是常見問題,因為寫錯了on和where的順序,導致結果不符合預期。錯誤case如下。
SELECTCOUNT(*)
FROM xxx a
LEFTJOIN yyy b
ON a.id = b.item_id
WHERE a.dt = '${bizdate}'
AND b.dt = '${bizdate}' ;
在上面的sql中,因為b.dt在where條件中,那麼沒有join上的資料會被過濾掉。
3)inner join和outer join用錯問題
此問題偶發,往往是開發同學沒有理解業務或者typo,導致結果不符合預期。
寫完sql一定要檢查,如果有可能請別的同學review sql。
一般情況下,分割槽都是string資料型別,但在寫sql時,分割槽不寫引號也可以查詢出正確的資料,導致有些同學不習慣在分割槽上加引號。
但某些情況下,如果沒有加引號,查詢的資料是錯誤的。所以一定要在時間分割槽上加引號。
在開發時,偶爾會出現三個表相互依賴的問題,這種情況比較少見,而且在資料開發階段不容易發現,只有再提交任務之後才會發現。
要避免這種情況,需要明確一些開發規範。比如維表和明細表都要從ods表中查得,不能維表和明細表直接互相依賴。對於某些複雜的邏輯,可以透過中間表的形式實現重用。
在做etl時,需要把某些列舉值轉化成字串,比如1轉成是、0轉成否等。
但對於某種一直增長的列舉值,這種方法不合適,否則增加一種編碼就要改一次sql,而且容易出現sql膨脹的問題。
上面提到過join的on和where執行順序的問題,這也關係到join的效能問題。因為是先on後where,建議先把資料量縮小再做join,這也可以提升效能。
(1) 如果是對左表(a)欄位過濾資料,則可以直接寫在where後面,此時執行的順序是:先對a表的where條件過濾資料然後再join b 表;
(2) 如果是對右表(b)欄位過濾資料,則應該寫在on 條件後面或者單獨寫個子查詢巢狀進去,這樣才能實現先過濾b表資料再進行join 操作;
如果直接把b表過濾條件放在where後面,執行順序是:先對a表資料過濾,然後和b表全部資料關聯之後,在reduce 階段才會對b表過濾條件進行過濾資料,此時如果b表資料量很大的話,效率就會很低。因此對於應該在map 階段儘可能對右表進行資料過濾。
若所有表中只有一張小表,那可在最大的表透過Mapper的時候將小表完全放到記憶體中,Hive可以在map端執行連線過程,稱為map-side join,這是因為Hive可以和記憶體的小表逐一匹配,從而省略掉常規連線所需的reduce過程。即使對於很小的資料集,這個最佳化也明顯地要快於常規的連線操作。其不僅減少了reduce過程,而且有時還可以同時減少Map過程的執行步驟。參考文末連結一。
mapjoin在Map階段執行表連線,而非等到Reduce階段才執行表連線,可以縮短大量資料傳輸時間,提升系統資源利用率,從而起到最佳化作業的作用。
在對大表和一個或多個小表執行join操作時,mapjoin會將您指定的小表全部載入到執行join操作的程式的記憶體中,在Map階段完成表連線從而加快join的執行速度。
select
a.shop_name,
a.total_price,
b.total_price
fromsale_detail_sjajoinsale_detailb
ona.total_price < b.total_priceora.total_price + b.total_price < 500;
在網際網路大資料場景中,一致性維表的資料量都比較大,有的甚至到幾億甚至十億的量級,在這個資料量級下做join,會這種任務往往耗時非常長,有些任務甚至需要耗費一天的時間才能產出。
在這種情況下,為了縮短執行時間,通常可以調大join階段的instance數目,增加join階段的記憶體減少spill等,但是instance的數目不能無限增長,否則會由於shuffle規模太大造成叢集壓力過大,另外記憶體的資源也是有限的,所以調整引數也只是犧牲資源換取時間,治標不治本。
Hash clustering,簡而言之,就是將資料提前進行shuffle和排序,在使用資料的過程中,讀取資料後直接參與計算。這種模式非常適合產出後後續節點多次按照相同key進行join或者聚合的場景。
Hash clustering是內建在MaxCompute中,不用顯示的指定,很方便。
Hive/MaxCompute在執行MapReduce任務時經常會碰到資料傾斜的問題,表現為一個或者幾個reduce節點執行很慢,延長了整個任務完成的時間,這是由於某些key的條數比其他key多很多,這些Key所在的reduce節點所處理的資料量比其他節點就大很多,從而導致某幾個節點遲遲執行不完。
常見的情況比如join的分佈不均勻,group by的時候不均勻等。
提交資料任務後,如何能正確及時的監控任務也是非常重要的。在資料監控方面,集團提供了很多強大的產品來解決問題,簡單介紹如下。
摩薩德監控是對任務執行狀態的監控,包括任務執行出錯、未按規定時間執行。摩薩德是對任務的監控,因此特別適合監控資料產出的即時性。比如某些表需要在幾點產出,如果沒有產出則報警等。當前摩薩德只能在Dataworks使用。
不同於摩薩德對任務的監控,DQC監控是對錶和欄位的監控,是任務執行後觸發監控條件從而觸發報警。
資料質量中心(DQC,Data Quality Center)是集團推出的資料質量解決方案,它可以提供整個資料的生命週期內的全鏈路資料質量保障服務。透過DQC,我們能夠在資料生產加工鏈路上監控業務資料的異常性,如有問題第一時間發現,並自動阻斷異常資料對下游的影響,保障資料的準確性。
不過DQC雖然很強大,但其配置還是很繁瑣的,而且要設定波動規則,需要較長時間觀測,表和欄位多的時候配置工作特別大。有團隊研究了Auto-DQC,可以自動化監控DQC配置。
解決資料質量問題沒有銀彈,資料質量管理不單純是一個概念,也不單純是一項技術、也不單純是一個系統,更不單純是一套管理流程,資料質量管理是一個集方法論、技術、業務和管理為一體的解決方案。本文簡單總結了我們當前遇到的資料質量問題和處理方法,也希望與對資料質量敢興趣的同學多多交流。
文中部分技術和解決已經在uc和夸克業務上踐行,大幅提升了業務的資料質量,拿到較好結果。
連結一:https://developer.aliyun.com/article/67300
連結二:https://help.aliyun.com/document_detail/73785.html
https://developer.aliyun.com/article/665154
https://developer.aliyun.com/article/665246
連結四:https://developer.aliyun.com/article/60908
如何透過Knative輕鬆實現應用Serverless化交付
本課程將會為你介紹如何透過Knative輕鬆完成應用在Serverless k8s的部署,並實現應用的按比例灰度釋出和基於qps的彈性伸縮。點選閱讀原文檢視詳情。