京東大數(shù)據(jù)治理探索與實踐
一、背景和方案
在當(dāng)今的數(shù)據(jù)驅(qū)動時代,數(shù)據(jù)作為關(guān)鍵生產(chǎn)要素之一,其在商業(yè)活動中的戰(zhàn)略價值愈加凸顯,京東也不例外。
作為國內(nèi)領(lǐng)先的電商平臺,京東在數(shù)據(jù)基礎(chǔ)設(shè)施上的投入極為巨大,涵蓋數(shù)萬臺服務(wù)器、數(shù) EB 級存儲、數(shù)百萬個數(shù)據(jù)模型及數(shù)以百萬計的任務(wù)執(zhí)行。每年成本上的投入高達兩位數(shù)個小目標(biāo),而且還在持續(xù)增長,成本壓力比較大。
面對這樣的成本壓力,治理是一個必然的選擇,并且不能是運動式、救火式的,而應(yīng)該是持續(xù)的,需要一個規(guī)?;?、常態(tài)化的治理體系。為了實現(xiàn)這一目標(biāo),就要應(yīng)對治理中的諸多挑戰(zhàn)。首先,場景復(fù)雜,平臺建設(shè)是個長期過程,管控規(guī)則在不斷迭代,歷史原因?qū)е缕脚_有部分作業(yè)的訪問方式跳過數(shù)據(jù)表直接訪問底層 HDFS 文件,或者繞過平臺的推數(shù)工具,直接在 MapReduce 或 Spark 里面寫入數(shù)據(jù),導(dǎo)致審計和血緣追蹤困難,給治理帶來了很大風(fēng)險。此外,平臺用戶較多,成本意識很難拉齊,且大家工作繁忙,主動治理的意愿較低。而且人工治理不僅成本高,風(fēng)險也高,如果人工判斷不準(zhǔn),就會造成生產(chǎn)事故。
為了解決這些問題,我們首先設(shè)計了健康分和貨幣化賬單,用來量化治理的收益,幫助用戶直觀感受治理的變化。再就是打造自動化治理平臺,自動發(fā)現(xiàn)問題,及時通知用戶,一鍵執(zhí)行,并通過量化指標(biāo)來判斷收益,提高治理人效。
具體治理從以下幾個角度一起考慮:
- 多種數(shù)據(jù)源相互印證。聯(lián)合 HDFS 和 Hive 的審計日志、HDFS 的元數(shù)據(jù)以及數(shù)據(jù)血緣等數(shù)據(jù)一起校驗,避免因單一數(shù)據(jù)源引發(fā)的誤判。
- 設(shè)置多環(huán)節(jié)校驗。判斷會綜合連續(xù)多日的診斷結(jié)果,避免特殊異常波動導(dǎo)致誤診。
- 作業(yè)提交會進行實時校驗。當(dāng)前數(shù)據(jù)作業(yè)是通過 t+1 離線模型進行計算,存在時間差,為避免時間差導(dǎo)致誤診,在執(zhí)行時針對選擇的治理做二次校驗。
- 操作可逆。對于治理數(shù)據(jù)做自動備份,即使有誤操作,也可以一鍵回滾。
- 數(shù)據(jù)治理落地的機制保障。增加數(shù)據(jù)管理專員小組、組織機構(gòu)治理負責(zé)人等角色,并明確各自職責(zé)。
- 明確目標(biāo)。每年采購前,會達成年度治理目標(biāo)的共識及預(yù)計的治理量。將目標(biāo)拆解到每個事業(yè)部、每個部門,以及每個季度、每個月的指標(biāo),并通過周期性例行會議不斷跟進和校準(zhǔn)。
- 完善獎懲機制,做得好會有激勵,做得不好,會在其他產(chǎn)品上限制其使用。
當(dāng)前整個治理系統(tǒng)已經(jīng)涵蓋了成本、穩(wěn)定性、安全、質(zhì)量等四個方向一共幾十個治理項。例如成本治理中表的生命周期,不僅僅按照人工設(shè)定時間定期刪除數(shù)據(jù),還可以根據(jù)數(shù)據(jù)實際被訪問的周期推薦更合理的生命周期數(shù)值。在穩(wěn)定性中的“依賴缺失”治理,防止任務(wù)執(zhí)行時,上游數(shù)據(jù)還未產(chǎn)出,導(dǎo)致任務(wù)失敗。在安全方面,平臺能及時發(fā)現(xiàn)對安全等級打標(biāo)不準(zhǔn),質(zhì)量方向的元數(shù)據(jù)缺失,元數(shù)據(jù)標(biāo)注不準(zhǔn)以及數(shù)據(jù)質(zhì)量異常等治理項,及時發(fā)現(xiàn),及時處理。
二、關(guān)鍵技術(shù)
接下來介紹一下治理平臺使用的關(guān)鍵技術(shù)。
1. 審計日志
審計日志記錄了用戶在何時何地因何原因訪問了哪些數(shù)據(jù)及訪問方式,這是安全治理的基礎(chǔ)。
以無效任務(wù)為例(有產(chǎn)出,但是產(chǎn)出的數(shù)據(jù)沒有下游訪問),自身作業(yè)還在運行,一定有日志產(chǎn)生,那如何來判斷有沒有下游呢,就需要排除掉自身任務(wù)的訪問,審計當(dāng)中就必須要有“任務(wù) ID”這個屬性。另外,治理需要明確的責(zé)任人,單單靠大家主動去維護表的負責(zé)人,一定會存在錯漏的問題,所以審計一定要能識別到具體哪個人在操作,再加上數(shù)據(jù)的反算策略,來補充和校準(zhǔn)負責(zé)人信息,確保數(shù)據(jù)一定有人負責(zé)。
原生的大數(shù)據(jù)系統(tǒng),并沒有這么豐富的信息,所以需要定制化改造:
- 改造 API 協(xié)議。通過對底層 HDFS,以及上層計算引擎的適配性改造,附加了任務(wù)來源以及任務(wù) ID 等上下文信息。
- 內(nèi)容反算。原始 metastore 日志記錄存儲的是原子 API 的使用記錄(如 get_table ,get_partition),但具體操作(讀、寫、改表)沒辦法區(qū)分。平臺通過對命令的訪問序列,總結(jié)規(guī)律,生成自動識別規(guī)則進行反算。
- 數(shù)據(jù)聯(lián)合使用。Hive 審計日志只記錄表級,具體訪問的分區(qū)是看不到的。而結(jié)合 HDFS 審計來反推分區(qū)訪問的活躍程度,從而推薦合理的生命周期,避免生命周期設(shè)置的偏大或偏小。
2. 全鏈路血緣
首先介紹一下圖中的一些術(shù)語,JDQ:是京東基于 kafka 進行二開的消息隊列;JRC:京東實時數(shù)據(jù)加工平臺,主要是用的 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ù)平臺,要進行數(shù)據(jù)治理,如果不能掌握上下游關(guān)系,很容易出現(xiàn)問題。比如數(shù)倉將數(shù)據(jù)推到了應(yīng)用系統(tǒng),后續(xù)訪問都在大數(shù)據(jù)平臺外,如果把表的加工任務(wù)當(dāng)成無效任務(wù)禁用后,就會影響業(yè)務(wù)正常運行。
除治理外,還可以利用血緣對全鏈路進行影響分析,鏈路優(yōu)化等(比如一個表在任務(wù)加工鏈路上屬于第 10 層,而他所依賴的所有數(shù)據(jù)都在第 3 層,那中間的幾層依賴即為無效的,直接依賴第 3 層的加工任務(wù)來縮短鏈路,就可以更快完成數(shù)據(jù)加工)。
在不同階段會用到不同的技術(shù),比如生產(chǎn)側(cè)主要用到的是調(diào)用鏈,在大數(shù)據(jù)側(cè)主要使用審計和執(zhí)行計劃的解析,在數(shù)據(jù)應(yīng)用與服務(wù)側(cè)主要是運用審計的能力。將各階段的數(shù)據(jù)進行整合,就可以得到全鏈路的血緣。
血緣的粒度如果只到表一級,還是存在一些局限性,在分析的時候,影響容易被放大。比如下游的表僅僅使用上游表做關(guān)聯(lián)查詢條件,他的結(jié)果當(dāng)中就不會保存上游表的數(shù)據(jù)內(nèi)容,在前面提到的影響分析場景,就應(yīng)該排除掉。要做到這一點,就需要實現(xiàn)算子級血緣。
算子級血緣描述的是字段間存在的具體關(guān)系,比如是直接引用的原字段,還是做了加減乘除等轉(zhuǎn)換,是結(jié)果存儲還是僅作為關(guān)聯(lián)條件,為精細化數(shù)據(jù)治理提供支撐。比如相似表計算和重復(fù)存儲識別就需要算子級血緣來幫助判斷。我們的算子血緣實現(xiàn)的方案集成在了邏輯執(zhí)行計劃優(yōu)化的階段,和優(yōu)化之后的 Hive Hook 的方式相比,可以拿到更原汁原味的血緣關(guān)系,對用戶來說更容易理解。下面就是利用血緣關(guān)系,進行主動元數(shù)據(jù)治理的一個案例。
用戶開發(fā)時,經(jīng)常要去找依賴的數(shù)據(jù)在哪里,有的是直接找表,而更多的時候是找字段,比如我想要知道訂單優(yōu)惠后的金額在哪,他的加工口徑是什么,這樣單純的按表來檢索就非常低效。所以我們設(shè)計了標(biāo)準(zhǔn)字段的概念,他是字段的抽象,在標(biāo)準(zhǔn)字段上可以維護更多的元數(shù)據(jù)信息,比如加工口徑,使用說明等。當(dāng)標(biāo)準(zhǔn)字段和表的實體字段關(guān)聯(lián)上之后,就可以通過它來尋找字段和表。
但是如果需要大家一個個的維護關(guān)聯(lián)關(guān)系,也是個巨大的成本,在這里就可以通過算子血緣來進行提效,用戶僅需要將字段的源頭做好關(guān)聯(lián),那么根據(jù)算子血緣關(guān)系,就可以直接算出有哪些直接引用的下游。
當(dāng)然,我們這個標(biāo)準(zhǔn)字段也不僅僅是用于找數(shù)的提效,在字段元數(shù)據(jù)上維護好枚舉值、取值范圍、格式規(guī)范等信息,我們在后臺會自動檢測真實數(shù)據(jù)是否和定義匹配,異常及時觸達用戶,讓用戶做治理。這個檢測不需要提前配置,完全是系統(tǒng)自動行為。
三、從“節(jié)流”到“開源”
前面介紹的內(nèi)容更多是如何推動業(yè)務(wù)主動治理,其目的主要是“節(jié)流”,減少不必要的占用。另一方面,我們也在尋求“開源”的手段,在不增加成本的情況下,使資源得到更充分的利用。這里主要列舉三種手段:資源混部、任務(wù)錯峰,以及跨機房的任務(wù)編排。
京東有兩大消耗大戶,分別是大數(shù)據(jù)和在線服務(wù),基數(shù)大,而且資源缺口也大。拿在線服務(wù)來說,在雙十一、618 等促銷節(jié)點,資源非常緊缺。而離線是常年高負荷運行,利用率都達百分之七八十。當(dāng)在線服務(wù)在大促峰值過后,需求就會降得很低,就可以借給離線使用。離線雖然常年是高負載的情況,但每天晚上八點后相對比較空,在大促時就可以進行在線的支援。因此資源混部的價值是很大的。
資源池化,可以根據(jù)業(yè)務(wù)特點和等級進行資源分配,進行統(tǒng)一調(diào)度。此外也可以進行按需分配,當(dāng)大促時,離線只需要借用幾個小時不會對整體造成影響,離線可借用的空間就會很大。
資源池化落地有幾個關(guān)鍵點。
- 存算分離是基礎(chǔ),計算需要做到無狀態(tài)才行。
- 容器化技術(shù),尤其是離線計算服務(wù)的容器化。
- 資源隔離,包括各種層面的隔離(比如 CPU 網(wǎng)絡(luò))。
前面講的是空間的挪移,而任務(wù)錯峰則是時間上的挪移。平臺上跑的上百萬的作業(yè),涉及很多開發(fā)人員,靠人工設(shè)定的運行規(guī)則,不是很合理。從數(shù)據(jù)表現(xiàn)來看,在凌晨 3-5 點集中了 30% 的任務(wù),導(dǎo)致資源搶占和高峰擁堵。還有就是父任務(wù)的結(jié)束時間和當(dāng)前任務(wù)的開始時間存在大量的 gap,如果父任務(wù)結(jié)束之后的空檔期,資源負載較低的話,可以把任務(wù)做提前的編排,不光可以提高資源的利用率,也可以提升運行的時效。對整個過程中每個隊列的資源使用情況,以及任務(wù)的運行時長進行預(yù)測,并根據(jù)這個預(yù)測結(jié)果結(jié)合任務(wù)的重要度來去動態(tài)調(diào)整任務(wù)的可執(zhí)行時間,即可實現(xiàn)削峰填谷。
第三個手段就是跨機房的任務(wù)搬遷。對于大公司來說,單個機房很難完全滿足需求,因為很少有機房能放數(shù)十萬臺服務(wù)器。另外也很難做到高可用,從安全角度來講,一般是要做到兩地三中心的架構(gòu),不同機房間的系統(tǒng)負載就很難相同,一定有的機房相對繁忙,另外一邊相對空閑。如果能對任務(wù)進行動態(tài)調(diào)整,把任務(wù)盡量分在空閑的一邊,就一定能跑得更快。這里比前面兩個手段要多出一項對存儲的考量,因為計算和存儲是跨機房的訪問,勢必就會帶來兩機房之間專線的額外占用。如果調(diào)度不當(dāng),就會導(dǎo)致專線堵塞。而且跨機房的存儲調(diào)撥,也會帶來一些更高的存儲需求。這個過程需要平衡存儲和計算的成本。
以上三個方面如果能夠做到極致,利用率就會接近一條直線,僅在均線上下小幅波動,采購就會大幅減少,甚至零采購,從而降低成本。
四、未來展望
未來的治理將在以下幾個方向繼續(xù)推進:
- 實時發(fā)現(xiàn)和治理。當(dāng)前的數(shù)據(jù)治理主要是依托于離線模型測算,后面會做更實時的診斷與治理,盡量是在業(yè)務(wù)上線之前就做到攔截,減少事后治理的場景。
- 智能化。系統(tǒng)從規(guī)則化向智能化演變,讓問題的識別變得更精準(zhǔn)、更智能。
- 自動化?,F(xiàn)在治理需要人工參與一小部分,未來的目標(biāo)是落地托管模式,實現(xiàn)無人化的治理。