騰訊數據治理技術實踐
一、數據治理簡介
首先介紹一下數據治理相關理論知識和概念,以便大家對數據治理有一定了解和認識。
1、什么是數據治理
個人理解的數據治理是整個數據相關組織架構以及各種活動能力的集合,因此,數據治理并不是單一組織或者系統能夠完成的事情。數據治理和數據管理是分不開的,數據治理的職能是指導其他數據管理職能的執行,數據治理是在高層上執行的數據管理。
2、數據治理目的
數據治理的目的有很多,比如數據共享、提升數據資產價值、提升數據質量等等,從下圖中的某機構調查結果可以看到,提升數據質量是數據治理的最大動機。除此之外,國家對數據相關法律規定,各個公司也有相關的規范要求,數據合規也是數據治理需要考慮的問題。
3、數據治理面臨的困難
數據治理面臨著諸多挑戰:比如數據多樣化缺乏統一標準、多種異構類型的數據源、數據鏈路長、數據合規保障、數據價值如何評估等等。
4、數據治理方法
了解了數據治理面臨的問題后,該如何解決這些問題?我們的方法就是知治管(先知后治再管)。
先知就是要知道治理的數據對象,知道數據的形式,存儲位置等;后治是使用相關技術進行治理比如規范化、標準化等處理;再管就是盡力去提升新數據的質量,這樣才算是真正把整個數據治理按體系做好。數據治理其實是一個閉環的體系,所以還需要將數據治理反饋到整個數據管理流程上。
5、數據治理過程
數據治理由圖示的四個步驟構成:
一是現在盤點,理清楚數據現狀,確定歸屬和職能。
二是數倉建設,這里的數倉包含了傳統意義上的數倉和元數據數倉,對這些數據進行統一采集和保存。
三是質量檢測,確定評估標準,輸出數據質量報告。
四是持續改進,根據數據質量報告推動數據持續改進,比如建立數據地圖、分析血緣關系、持續監控數據質量、優化數據使用流程。將數據的產生和治理相結合結合,形成閉環,從而保證數據的采集和數據治理變得更好。
二、騰訊數據治理體系簡介
這部分主要介紹騰訊內部數據治理體系的建設思路和策略。
1、組織管理體系
在騰訊內部,我們建立了統一組織,規劃和協調整個公司的數據治理、數據安全工作,以 OTeam 形式規劃和實施整個相關領域的平臺建設和規范協同;建立企業級標準,規范測評體系;構建平臺協同,建設開箱即用的一站式數據治理工具平臺;形成社區運營,通過分享或宣傳的方式,讓大家意識到數據治理以及數據質量的重要性。
2、騰訊數據治理業務框架
騰訊這樣量級的公司,動輒幾千萬上億甚至百億級別的數據,數據的采集和存儲都是很大的問題。在上億量級的數據治理建設過程中,我們一步步實踐,踩過很多坑。通過制定數據治理標準,搭建了以資產創建、資產評估、資產運營、資產管控四部分構成的數據治理平臺,構建全域元數據服務,形成了元數據采集、存儲、數倉、數據血緣的整個數據生命周期鏈路,結合底層采用多種存儲方式,逐步建設了一個可以管理和區分優質資產與數據垃圾、相對較好的元數據管理體系平臺。
3、元數據管理
我們從如何采、怎么存、引導治出發,來思考和逐步完善元數據的管理。
4、數據資產管理
我們建立區分優質資產,減少垃圾數據的數據資產管理平臺,由四個部分組成:
首先是確定數據歸屬,如果數據歸屬都沒明確,則數據治理工作是很難展開,像騰訊這樣級別的大公司,經過多次組織架構的變更,數據歸屬問題尤其凸顯,比如說經過組織調整,單個 BG 的數據拆成了多個 BG 的數據導致,數據管理問題在組織架構變遷變得非常混亂,因此確定歸屬關系是數據治理一個非常關鍵的環節。
其次是價值分析,通過業務屬性和數據訪問這兩個維度對數據進行評估數據的價值,業務屬性也即是公司在各個領域的業務比如賬號體系等等。如數據訪問的量或者訪問頻次越高,就認為該數據重要或者具有更高的價值。
然后是數據清理,為了避免數據清理或者減少權限變更影響的范圍,需要進行影響分析判斷,同時結合自動化清理工具完成整個數據清理或是權限變更。只是做好數據清理工作是不夠,因為在實際操作數據過程中,可能會出現誤刪或故意刪除的情況;為了保證數據數據情況的可靠性,我們還建立一套數據可恢復的機制,從而保證出現上述情況時,能夠快速進行數據恢復,盡可能地降低影響范圍。
最后是生命周期,結合數據血緣和訪問頻次等學習,為用戶設置數據生命周期時,對該數據的生命周期進行智能化推薦;當然,這只是推薦的生命周期,數據最終的生命周期要結合著人工審核判斷,給定一個比較合理的周期。
5、騰訊數據治理測評體系:元數據管理成熟度
我們對元數據管理制定了測評體系,用于對公司整個數據管理和評估,可以看到圖中從下到上分為五個等級,一二級是一些初始或基本管理方法,第三級則是相對來說已經比較成熟,但是完全不夠的,還需要將數據驅動和數據治理與數據使用形成閉環,以便做好元原數據的管理,此時已經是第四級,是比較優秀的程度。第五級則是比較卓越管理體系,需要具備自我完善和自我改進的功能,同時能夠在公司內或業界有一定影響力,元數據管理真正能做到這個級別的少之又少 。
6、數據安全治理
數據安全也是數據使用過程中一個非常重要的環節,在這過程中,我們首先對數據進行了分類分級處理,為數據確定安全等級和標記,并與數據資產進行關聯。其次在進行數據管控,根據數據的分類分級結果,定制不同數據級別的申請流程,比如動態或靜態數據,數據加密和脫敏,在數據使用中對數據進行管控。最后是安全審計,支持一些安全審計相關功能比如數據權限訪問監控、訪問記錄、下載日志等等,并可以輸出安全報告。
7、騰訊數據治理測評特征-安全管理能力成熟度
我們對數據安全能力管控也制定了評測體系,即安全管理能力成熟度,包含了 12 個管理域以及 86 個控制項。數據安全管理能力從低到高分成五個等級。
制定了數據安全管理能力標準后,數據治理通過 OTeam 進行統一組織和協調,各個部門自行申請或者參與到整個評測的工作中。
三、數據治理技術實踐
這部分是本次分享的最核心部分:騰訊內部元數據管理、數據血緣相關技術和相關的后臺技術實現。
1、技術架構
下圖是我們內部統一元數據系統的技術架構。對外來說,上層可以支持不同類型元數據,可以滿足各種分析引擎對元數據相關的要求,同時對接各種自定義或者標準化的數據源。這套底層統一的元數據服務既要滿足公司內部的要求,同時也要滿足外部的用戶對整個數據治理的需求。目前這套元數據管理除了內部使用外,也支持了騰訊云上的產品比如 WeData 等,我們統一元數據平臺目前對公司內外及相關產品都可以提供支持。
從下往上看,整個統一元數據可分成兩個垂直的領域。
左邊是數據治理體系,主要面向的是離線采集、存儲,然后做數據檢索、生命周期、數據安全、數據血緣和數據質量的管理,這些就是數據治理提供的基礎服務。在線元數據是支持引擎側的實時元數據寫入,比如大數據領域最典型的 Hive、RDBMS、Strom,通過 thrift 協議,將數據實時寫入到元數據服務。離線數據治理和在線數據治理所面臨領域和技術的差異是比較大的,數據治理更關注的是大數據量基礎上,如何做好分析、檢索和工作。因此在底層存儲的選型方面結合了各種數據庫,比如 HBase、ES、圖數據庫以及關系型數據庫來支撐整個離線治理工作。在線元數據服務因為有部分事務工作,比如建庫建表,實時寫入時,需要考慮到事務、數據一致性和高可靠等因素,因此,在底層存儲時,選擇了傳統的關系型數據庫進行存儲。需要事務和一致性、高可靠的方式去完成。像騰訊體量的公司,數據量是非常龐大的,單純的靠單機 MySQL、PQ 是很難支持這種海量數據存儲。因此,我們在這個基礎上進行分庫分表,并利用公司內部 TDSql 分布式數據庫存儲。
右邊在是統一元數據服務基礎,提供公共的平臺能力,比如認證、鑒權、任務調度、用戶租戶以及運營監控。
2、微服務劃分
上圖是我們整個元數據治理服務后臺微服務劃分,上層是元數據產品、計算引擎、數據源,第二層是在第一層基礎上提供后臺能力,比如數據地圖、元數據采集、數據血緣和資產管理等功能,最底層就是整個支撐這套體系的技術服務。
后臺的技術服務又分成了兩層:第一層是數據層或接入層,主要由databus、center、metastores 組成,其中 hybirs 是元數據服務內部代號。databus 的作用是統一消費經過 MQ 轉發的消息并落庫,http 服務和 Thrift 服務經過接入層服務后,通過 RPC 協議進入基礎服務層并在基礎服務層進行業務邏輯處理,最后寫入到底層存儲。
接入層分為兩層是為了底層存儲能夠提供通用的服務能力。接入層的第二層更靈活,可以支持不同產品和引擎,以及不同數據源對接和適配。從圖中可以看到,databus 有一條直通底層數據庫的鏈路。考慮到 databus 的職責所在,因為 databus 是對 mq 消息進行統一消費,考慮到數據量,databus 對寫入效率的要求非常高。http 服務和 Thrift 服務的數據量相比而言就少 很多,為了減少數據消費的延遲,我們將 databus 消費的數據直接落庫,減少 http/Thrift 服務中的 RPC 調用,縮短鏈路,進一步提升數據入效率,從而將采集的數據及時地存儲底層存儲中。
3、數據采集
首先是統一元數據的數據采集,數據采集可以分成兩個方向:定時采集和實時采集。
定時就是通過定時任務或調度定期連接數據源,對上游的元數據進行采集。采集的過程又分為增量采集和全量采集。因此定時采集可以分為定時增量采集和定時全量采集;定時增量就是每次只采最近一段時間的數據,通過積累采集全部歷史數據。定時全量就是每次將全部數據一次性采集完,然后落地。
在實際工作中,往往是將增量采集和全量采集結合使用。數據采集并不是最初就進行全量采集,而是待數據積累到一定量后才對元數據采集或治理工作。首次采集時,通常是使用全量采集的方式將歷史數據采集,后續的數據往往是通過定時增量的方式采集。
對于那些必須要定時增量的數據,為了減少后續鏈路的壓力,我們做了針對性的優化:通過 redis 對定時增量做了過濾處理,比如采集周期內,對庫信息、表信息以及分區信息計算 md5 值并存儲在 redis,然后對采集的元數據進行 md5 計算,再與 Redis 中對應的值進行比對,在源頭過濾掉沒有差異的數據,從而減少重復數據的發送。
面臨的另一個問題就是全量采集時全量刪除和全量覆蓋。在增量化處理時,數據刪除是面臨問題的:上一次是全量處理,后續則是增量處理,比如在某個周期內,有五個庫,這一次采集,需要刪了一個庫(表),增量采集的方式是沒辦法直接找到要刪除的庫(表) ,也即是刪除些信息沒辦法透徹到下游。
針對數據刪除無法發現,我們對數據源所在庫和表做了緩存,在后續的數據采集時,與 redis 中緩存數據做全量對比取交集和差集,從而判斷數據的修改情況比如刪除、新增或修改,在源頭去掉重復的數據,同時有又能發現刪除的情況,最后把過濾處理后的數據發到消息中間件。經過后續的消費、分發(采集的數據源是有多種多樣的,因此會有分發器來識別和和處理不同類型元數據)最終分發不同的數據存儲的流程。比如血緣信息、元數據 DDL 信息、審計日志信息的數據,針對不同類型信息數據有不同的處理鏈路,根據數據特點落入不同的存儲,比如血緣信息數據寫入圖數據庫,元數據 DDL 信息存儲到 HBase。
數據治理產品前端交互是通過 ES 完成,打上寬表滿足前端交互和數據發現以及數據管理的需求。數據審計的日志流水,則使用內部 hermes ,hermes 是一個類似 ES 的產品,但在存儲方面做了針對性優化。
傳統關系數據庫都有唯一的主鍵,根據這個主鍵就可以增刪改查等處理。但是在元數據管理中,對于非采用非關系數據庫,該如何處理呢?比如上游采集好的一條元數據信息傳遞過來,我們需要對數據進行判斷,比如是否存在或者是否修改。首先是查詢,根據庫(表)名查詢是否存在,若存在則是更新操作;不存在則是新增操作。這個過程會與數據庫發生兩次交互,對整個鏈路會產生較大的影響 。
為了處理這個問題,我們引入了 guid 生成器(guid generator),將庫和表的信息和數據源信息輸入到 guid 生成器,生成一個統一編碼的 guid,作為底層存儲的唯一標識。然后用生成的 guid 對數據庫進行一個類似叫 replace into 的方式,從而實現通過一次跟數據庫的交互就能新增或修改操作。這樣處理對整個寫入流程是一個很大的提升。比如 hbase,直接使用 upsert,將新數據寫入數據庫,無需關心是新增還是修改。為了保證數據的最終一致性,我們將實時與周期性全量或增量的方式結合,去實現數據的最終一致性。在發生數據實時采集不及時或者鏈路有問題的情況下,通過全量采集的方式進行補漏處理。
4、統一元數據-血緣采集分析
血緣分析對整個數據價值體驗是非常重要的,如何做血緣分析呢?首先是血緣的來源,最直接的方式就是用戶通過執行引擎的客戶端或者直連執行引的 server 提交的 sql。比如基于 hive 或者騰訊內部的 thive 提交 sql 后,我們通過 hook 或者 spark 的 listener 或者 hbase 的協處理器的方式攔截到具體 query plan,query plan里面記錄了用戶提交的 sql 以及整個執行過程中 context 的上下游信息,包括 intoput、output 等信息。對 query plan 進一步解析,從而形成了數據血緣的 mode,然后寫到 MQ,最后獲取 sql 數據進行解析,將血源信息落到圖數據庫。
另外一種就是通過定時調度產生的血緣,感知到用戶提交的 sql 表信息之外。還需要將用戶調度任務信息與庫和表的關系進行一個呈現。同時會將通過其他方式提交的歷史任務記錄的日志消息存儲在 HDFS。我們會定時抓取這些日志并對日志做統一分析處理,比如 mr 、spark、sql 分析,形成血緣模型,發送到 mq,最終寫入數據庫。
sql 解析是血緣解析過程的關鍵技術,業界有很對 sql 解析和開源的技術,我們內部是基于 Druid 進行封裝和改進構建了sql guru,并進行 sql 解析。相比于 hive 的 antlr 解析器,通過實際效果對比,我們選擇了在性能穩定性以及支持的場景更有優勢的 Druid。Druid 處理廣泛使用的連接池之外,它數據 sql 解析方面也是比較強悍的。除了常見的血緣解析能力之外,我們還擴展了一些比如像物化視圖、像臨時表 with as,join 等復雜 sql 的解析。基于相對全面元數據采集,結合強悍的 sql 解析能力以及語法支持,我們將血緣分析的場景盡可能做得完善。
5、數數據血緣存儲
圖數據庫是血緣存儲的常見方式,因此圖數據庫也作為了我們內部血緣存儲的一種方式。當數據量級比較小時,圖數據庫并不是血緣存儲的唯一方式,基于傳統的關系數據庫可以表達出來血緣的關系,血緣無非就是各種實體以及它們之間關系的記錄。
以圖中的 case 所示,圖中有兩個調度任務,第一個調度任務里面有兩段 sql,執行第一個 task 是會執行兩個獨立的 sql,第一個 sql 是 a 和 b 的關系,第二個 sql 是 d 和 c 的關系。第二個 task 只有一個 sql,它是 a 和 b 的關系,那這個時候就會有一個問題:數據血緣圖數據庫里面怎么呈現的呢?
圖數據庫存儲的無非就是點和邊以及中間的線,橫向來看,我們把表和任務作為點來存儲,可以看到左邊這種情況 那我們看 比如像 task A 把 a 和 b 關聯,同時將 c 和 d 關聯。因此,它們的血緣關系如圖左上角所示。因為是通過同一個 task 關聯,當我們去尋找與 c 有關聯的血緣時,會找到 b 和 d 都找到了。從圖中可以看到 task A 一個特性里面看到有兩段的 sql,但 a 和 b 才有真正但血緣關系,c 和 b 之間是沒血緣關系的。c 與 b 之間有血緣關系是因為錯亂導致的。
因此我們做了針對性優化,如右上圖所示,可以看到右邊這種情況。將任務節點拆成兩個節點,雖然兩個節點輸入同一個任務,但是每個節點都有唯一的標識記錄,這樣就可以區分出來,建立關系清晰的血緣鏈路。從 a 出發,就只會知道與它有血緣關系的 b,這樣就解決了上面所說的錯亂的問題。
另一種思路就是將表作為點,任務去作為邊,那這種情況會有什么問題呢?可以看到 a 和 b 通過 task A 和 taskB 分別建立這個血緣關系。除了這個表的血緣關系之外還需要體現任務的血緣關系。而在圖數據庫中兩個相同的點之間,只能有唯一的一條邊,按這種方式處理前面提到的情況,是首先是 a 和 b 建立血緣關系,后面 b 則會再和 a 建立血緣關系。這樣就會將出現任務信息覆蓋的情況,導致整個血緣關系的不完整。結合在血緣關系處理過程中可能出現的各種情況以及它們帶來的問題,我們最終選擇圖數據庫的方式將表和任務均作為點,然后用邊建立血緣關系,記錄整個血緣。
以上就是本次分享的內容。本次分享主要是我們騰訊內部數據治過程遇到的問題以及處理方法。希望通過本次分享能夠給在做數據治理和建設的同學一些指導,幫助大家規避一些在日常工作中可能出現的問題。