京東大數(shù)據(jù)治理探索與實(shí)踐
一、背景和方案
在當(dāng)今的數(shù)據(jù)驅(qū)動(dòng)時(shí)代,數(shù)據(jù)作為關(guān)鍵生產(chǎn)要素之一,其在商業(yè)活動(dòng)中的戰(zhàn)略價(jià)值愈加凸顯,京東也不例外。

作為國內(nèi)領(lǐng)先的電商平臺(tái),京東在數(shù)據(jù)基礎(chǔ)設(shè)施上的投入極為巨大,涵蓋數(shù)萬臺(tái)服務(wù)器、數(shù) EB 級(jí)存儲(chǔ)、數(shù)百萬個(gè)數(shù)據(jù)模型及數(shù)以百萬計(jì)的任務(wù)執(zhí)行。每年成本上的投入高達(dá)兩位數(shù)個(gè)小目標(biāo),而且還在持續(xù)增長,成本壓力比較大。
面對(duì)這樣的成本壓力,治理是一個(gè)必然的選擇,并且不能是運(yùn)動(dòng)式、救火式的,而應(yīng)該是持續(xù)的,需要一個(gè)規(guī)?;?、常態(tài)化的治理體系。為了實(shí)現(xiàn)這一目標(biāo),就要應(yīng)對(duì)治理中的諸多挑戰(zhàn)。首先,場(chǎng)景復(fù)雜,平臺(tái)建設(shè)是個(gè)長期過程,管控規(guī)則在不斷迭代,歷史原因?qū)е缕脚_(tái)有部分作業(yè)的訪問方式跳過數(shù)據(jù)表直接訪問底層 HDFS 文件,或者繞過平臺(tái)的推數(shù)工具,直接在 MapReduce 或 Spark 里面寫入數(shù)據(jù),導(dǎo)致審計(jì)和血緣追蹤困難,給治理帶來了很大風(fēng)險(xiǎn)。此外,平臺(tái)用戶較多,成本意識(shí)很難拉齊,且大家工作繁忙,主動(dòng)治理的意愿較低。而且人工治理不僅成本高,風(fēng)險(xiǎn)也高,如果人工判斷不準(zhǔn),就會(huì)造成生產(chǎn)事故。

為了解決這些問題,我們首先設(shè)計(jì)了健康分和貨幣化賬單,用來量化治理的收益,幫助用戶直觀感受治理的變化。再就是打造自動(dòng)化治理平臺(tái),自動(dòng)發(fā)現(xiàn)問題,及時(shí)通知用戶,一鍵執(zhí)行,并通過量化指標(biāo)來判斷收益,提高治理人效。
具體治理從以下幾個(gè)角度一起考慮:
- 多種數(shù)據(jù)源相互印證。聯(lián)合 HDFS 和 Hive 的審計(jì)日志、HDFS 的元數(shù)據(jù)以及數(shù)據(jù)血緣等數(shù)據(jù)一起校驗(yàn),避免因單一數(shù)據(jù)源引發(fā)的誤判。
- 設(shè)置多環(huán)節(jié)校驗(yàn)。判斷會(huì)綜合連續(xù)多日的診斷結(jié)果,避免特殊異常波動(dòng)導(dǎo)致誤診。
- 作業(yè)提交會(huì)進(jìn)行實(shí)時(shí)校驗(yàn)。當(dāng)前數(shù)據(jù)作業(yè)是通過 t+1 離線模型進(jìn)行計(jì)算,存在時(shí)間差,為避免時(shí)間差導(dǎo)致誤診,在執(zhí)行時(shí)針對(duì)選擇的治理做二次校驗(yàn)。
- 操作可逆。對(duì)于治理數(shù)據(jù)做自動(dòng)備份,即使有誤操作,也可以一鍵回滾。
- 數(shù)據(jù)治理落地的機(jī)制保障。增加數(shù)據(jù)管理專員小組、組織機(jī)構(gòu)治理負(fù)責(zé)人等角色,并明確各自職責(zé)。
- 明確目標(biāo)。每年采購前,會(huì)達(dá)成年度治理目標(biāo)的共識(shí)及預(yù)計(jì)的治理量。將目標(biāo)拆解到每個(gè)事業(yè)部、每個(gè)部門,以及每個(gè)季度、每個(gè)月的指標(biāo),并通過周期性例行會(huì)議不斷跟進(jìn)和校準(zhǔn)。
- 完善獎(jiǎng)懲機(jī)制,做得好會(huì)有激勵(lì),做得不好,會(huì)在其他產(chǎn)品上限制其使用。
當(dāng)前整個(gè)治理系統(tǒng)已經(jīng)涵蓋了成本、穩(wěn)定性、安全、質(zhì)量等四個(gè)方向一共幾十個(gè)治理項(xiàng)。例如成本治理中表的生命周期,不僅僅按照人工設(shè)定時(shí)間定期刪除數(shù)據(jù),還可以根據(jù)數(shù)據(jù)實(shí)際被訪問的周期推薦更合理的生命周期數(shù)值。在穩(wěn)定性中的“依賴缺失”治理,防止任務(wù)執(zhí)行時(shí),上游數(shù)據(jù)還未產(chǎn)出,導(dǎo)致任務(wù)失敗。在安全方面,平臺(tái)能及時(shí)發(fā)現(xiàn)對(duì)安全等級(jí)打標(biāo)不準(zhǔn),質(zhì)量方向的元數(shù)據(jù)缺失,元數(shù)據(jù)標(biāo)注不準(zhǔn)以及數(shù)據(jù)質(zhì)量異常等治理項(xiàng),及時(shí)發(fā)現(xiàn),及時(shí)處理。
二、關(guān)鍵技術(shù)
接下來介紹一下治理平臺(tái)使用的關(guān)鍵技術(shù)。

1. 審計(jì)日志
審計(jì)日志記錄了用戶在何時(shí)何地因何原因訪問了哪些數(shù)據(jù)及訪問方式,這是安全治理的基礎(chǔ)。
以無效任務(wù)為例(有產(chǎn)出,但是產(chǎn)出的數(shù)據(jù)沒有下游訪問),自身作業(yè)還在運(yùn)行,一定有日志產(chǎn)生,那如何來判斷有沒有下游呢,就需要排除掉自身任務(wù)的訪問,審計(jì)當(dāng)中就必須要有“任務(wù) ID”這個(gè)屬性。另外,治理需要明確的責(zé)任人,單單靠大家主動(dòng)去維護(hù)表的負(fù)責(zé)人,一定會(huì)存在錯(cuò)漏的問題,所以審計(jì)一定要能識(shí)別到具體哪個(gè)人在操作,再加上數(shù)據(jù)的反算策略,來補(bǔ)充和校準(zhǔn)負(fù)責(zé)人信息,確保數(shù)據(jù)一定有人負(fù)責(zé)。
原生的大數(shù)據(jù)系統(tǒng),并沒有這么豐富的信息,所以需要定制化改造:
- 改造 API 協(xié)議。通過對(duì)底層 HDFS,以及上層計(jì)算引擎的適配性改造,附加了任務(wù)來源以及任務(wù) ID 等上下文信息。
- 內(nèi)容反算。原始 metastore 日志記錄存儲(chǔ)的是原子 API 的使用記錄(如 get_table ,get_partition),但具體操作(讀、寫、改表)沒辦法區(qū)分。平臺(tái)通過對(duì)命令的訪問序列,總結(jié)規(guī)律,生成自動(dòng)識(shí)別規(guī)則進(jìn)行反算。
- 數(shù)據(jù)聯(lián)合使用。Hive 審計(jì)日志只記錄表級(jí),具體訪問的分區(qū)是看不到的。而結(jié)合 HDFS 審計(jì)來反推分區(qū)訪問的活躍程度,從而推薦合理的生命周期,避免生命周期設(shè)置的偏大或偏小。
2. 全鏈路血緣

首先介紹一下圖中的一些術(shù)語,JDQ:是京東基于 kafka 進(jìn)行二開的消息隊(duì)列;JRC:京東實(shí)時(shí)數(shù)據(jù)加工平臺(tái),主要是用的 FLink 技術(shù);DTS:數(shù)據(jù)集成工具;Plumber in、out:數(shù)據(jù)的導(dǎo)入導(dǎo)出。
上圖展示的是正常的數(shù)據(jù)流轉(zhuǎn)過程。從生產(chǎn)到數(shù)倉,再到數(shù)據(jù)應(yīng)用或服務(wù)的全過程來看,已經(jīng)不單單在大數(shù)據(jù)平臺(tái),要進(jìn)行數(shù)據(jù)治理,如果不能掌握上下游關(guān)系,很容易出現(xiàn)問題。比如數(shù)倉將數(shù)據(jù)推到了應(yīng)用系統(tǒng),后續(xù)訪問都在大數(shù)據(jù)平臺(tái)外,如果把表的加工任務(wù)當(dāng)成無效任務(wù)禁用后,就會(huì)影響業(yè)務(wù)正常運(yùn)行。
除治理外,還可以利用血緣對(duì)全鏈路進(jìn)行影響分析,鏈路優(yōu)化等(比如一個(gè)表在任務(wù)加工鏈路上屬于第 10 層,而他所依賴的所有數(shù)據(jù)都在第 3 層,那中間的幾層依賴即為無效的,直接依賴第 3 層的加工任務(wù)來縮短鏈路,就可以更快完成數(shù)據(jù)加工)。
在不同階段會(huì)用到不同的技術(shù),比如生產(chǎn)側(cè)主要用到的是調(diào)用鏈,在大數(shù)據(jù)側(cè)主要使用審計(jì)和執(zhí)行計(jì)劃的解析,在數(shù)據(jù)應(yīng)用與服務(wù)側(cè)主要是運(yùn)用審計(jì)的能力。將各階段的數(shù)據(jù)進(jìn)行整合,就可以得到全鏈路的血緣。
血緣的粒度如果只到表一級(jí),還是存在一些局限性,在分析的時(shí)候,影響容易被放大。比如下游的表僅僅使用上游表做關(guān)聯(lián)查詢條件,他的結(jié)果當(dāng)中就不會(huì)保存上游表的數(shù)據(jù)內(nèi)容,在前面提到的影響分析場(chǎng)景,就應(yīng)該排除掉。要做到這一點(diǎn),就需要實(shí)現(xiàn)算子級(jí)血緣。

算子級(jí)血緣描述的是字段間存在的具體關(guān)系,比如是直接引用的原字段,還是做了加減乘除等轉(zhuǎn)換,是結(jié)果存儲(chǔ)還是僅作為關(guān)聯(lián)條件,為精細(xì)化數(shù)據(jù)治理提供支撐。比如相似表計(jì)算和重復(fù)存儲(chǔ)識(shí)別就需要算子級(jí)血緣來幫助判斷。我們的算子血緣實(shí)現(xiàn)的方案集成在了邏輯執(zhí)行計(jì)劃優(yōu)化的階段,和優(yōu)化之后的 Hive Hook 的方式相比,可以拿到更原汁原味的血緣關(guān)系,對(duì)用戶來說更容易理解。下面就是利用血緣關(guān)系,進(jìn)行主動(dòng)元數(shù)據(jù)治理的一個(gè)案例。

用戶開發(fā)時(shí),經(jīng)常要去找依賴的數(shù)據(jù)在哪里,有的是直接找表,而更多的時(shí)候是找字段,比如我想要知道訂單優(yōu)惠后的金額在哪,他的加工口徑是什么,這樣單純的按表來檢索就非常低效。所以我們?cè)O(shè)計(jì)了標(biāo)準(zhǔn)字段的概念,他是字段的抽象,在標(biāo)準(zhǔn)字段上可以維護(hù)更多的元數(shù)據(jù)信息,比如加工口徑,使用說明等。當(dāng)標(biāo)準(zhǔn)字段和表的實(shí)體字段關(guān)聯(lián)上之后,就可以通過它來尋找字段和表。
但是如果需要大家一個(gè)個(gè)的維護(hù)關(guān)聯(lián)關(guān)系,也是個(gè)巨大的成本,在這里就可以通過算子血緣來進(jìn)行提效,用戶僅需要將字段的源頭做好關(guān)聯(lián),那么根據(jù)算子血緣關(guān)系,就可以直接算出有哪些直接引用的下游。
當(dāng)然,我們這個(gè)標(biāo)準(zhǔn)字段也不僅僅是用于找數(shù)的提效,在字段元數(shù)據(jù)上維護(hù)好枚舉值、取值范圍、格式規(guī)范等信息,我們?cè)诤笈_(tái)會(huì)自動(dòng)檢測(cè)真實(shí)數(shù)據(jù)是否和定義匹配,異常及時(shí)觸達(dá)用戶,讓用戶做治理。這個(gè)檢測(cè)不需要提前配置,完全是系統(tǒng)自動(dòng)行為。
三、從“節(jié)流”到“開源”
前面介紹的內(nèi)容更多是如何推動(dòng)業(yè)務(wù)主動(dòng)治理,其目的主要是“節(jié)流”,減少不必要的占用。另一方面,我們也在尋求“開源”的手段,在不增加成本的情況下,使資源得到更充分的利用。這里主要列舉三種手段:資源混部、任務(wù)錯(cuò)峰,以及跨機(jī)房的任務(wù)編排。

京東有兩大消耗大戶,分別是大數(shù)據(jù)和在線服務(wù),基數(shù)大,而且資源缺口也大。拿在線服務(wù)來說,在雙十一、618 等促銷節(jié)點(diǎn),資源非常緊缺。而離線是常年高負(fù)荷運(yùn)行,利用率都達(dá)百分之七八十。當(dāng)在線服務(wù)在大促峰值過后,需求就會(huì)降得很低,就可以借給離線使用。離線雖然常年是高負(fù)載的情況,但每天晚上八點(diǎn)后相對(duì)比較空,在大促時(shí)就可以進(jìn)行在線的支援。因此資源混部的價(jià)值是很大的。
資源池化,可以根據(jù)業(yè)務(wù)特點(diǎn)和等級(jí)進(jìn)行資源分配,進(jìn)行統(tǒng)一調(diào)度。此外也可以進(jìn)行按需分配,當(dāng)大促時(shí),離線只需要借用幾個(gè)小時(shí)不會(huì)對(duì)整體造成影響,離線可借用的空間就會(huì)很大。
資源池化落地有幾個(gè)關(guān)鍵點(diǎn)。
- 存算分離是基礎(chǔ),計(jì)算需要做到無狀態(tài)才行。
- 容器化技術(shù),尤其是離線計(jì)算服務(wù)的容器化。
- 資源隔離,包括各種層面的隔離(比如 CPU 網(wǎng)絡(luò))。
前面講的是空間的挪移,而任務(wù)錯(cuò)峰則是時(shí)間上的挪移。平臺(tái)上跑的上百萬的作業(yè),涉及很多開發(fā)人員,靠人工設(shè)定的運(yùn)行規(guī)則,不是很合理。從數(shù)據(jù)表現(xiàn)來看,在凌晨 3-5 點(diǎn)集中了 30% 的任務(wù),導(dǎo)致資源搶占和高峰擁堵。還有就是父任務(wù)的結(jié)束時(shí)間和當(dāng)前任務(wù)的開始時(shí)間存在大量的 gap,如果父任務(wù)結(jié)束之后的空檔期,資源負(fù)載較低的話,可以把任務(wù)做提前的編排,不光可以提高資源的利用率,也可以提升運(yùn)行的時(shí)效。對(duì)整個(gè)過程中每個(gè)隊(duì)列的資源使用情況,以及任務(wù)的運(yùn)行時(shí)長進(jìn)行預(yù)測(cè),并根據(jù)這個(gè)預(yù)測(cè)結(jié)果結(jié)合任務(wù)的重要度來去動(dòng)態(tài)調(diào)整任務(wù)的可執(zhí)行時(shí)間,即可實(shí)現(xiàn)削峰填谷。
第三個(gè)手段就是跨機(jī)房的任務(wù)搬遷。對(duì)于大公司來說,單個(gè)機(jī)房很難完全滿足需求,因?yàn)楹苌儆袡C(jī)房能放數(shù)十萬臺(tái)服務(wù)器。另外也很難做到高可用,從安全角度來講,一般是要做到兩地三中心的架構(gòu),不同機(jī)房間的系統(tǒng)負(fù)載就很難相同,一定有的機(jī)房相對(duì)繁忙,另外一邊相對(duì)空閑。如果能對(duì)任務(wù)進(jìn)行動(dòng)態(tài)調(diào)整,把任務(wù)盡量分在空閑的一邊,就一定能跑得更快。這里比前面兩個(gè)手段要多出一項(xiàng)對(duì)存儲(chǔ)的考量,因?yàn)橛?jì)算和存儲(chǔ)是跨機(jī)房的訪問,勢(shì)必就會(huì)帶來兩機(jī)房之間專線的額外占用。如果調(diào)度不當(dāng),就會(huì)導(dǎo)致專線堵塞。而且跨機(jī)房的存儲(chǔ)調(diào)撥,也會(huì)帶來一些更高的存儲(chǔ)需求。這個(gè)過程需要平衡存儲(chǔ)和計(jì)算的成本。
以上三個(gè)方面如果能夠做到極致,利用率就會(huì)接近一條直線,僅在均線上下小幅波動(dòng),采購就會(huì)大幅減少,甚至零采購,從而降低成本。
四、未來展望

未來的治理將在以下幾個(gè)方向繼續(xù)推進(jìn):
- 實(shí)時(shí)發(fā)現(xiàn)和治理。當(dāng)前的數(shù)據(jù)治理主要是依托于離線模型測(cè)算,后面會(huì)做更實(shí)時(shí)的診斷與治理,盡量是在業(yè)務(wù)上線之前就做到攔截,減少事后治理的場(chǎng)景。
- 智能化。系統(tǒng)從規(guī)則化向智能化演變,讓問題的識(shí)別變得更精準(zhǔn)、更智能。
- 自動(dòng)化?,F(xiàn)在治理需要人工參與一小部分,未來的目標(biāo)是落地托管模式,實(shí)現(xiàn)無人化的治理。































