數據血緣圖譜升級方案設計與實現
數據地圖平臺是字節跳動內部的大數據檢索平臺,每天近萬的字節員工在此查找所需數據。數據地圖通過提供便捷的找數,理解數服務,大大節省了內部數據的溝通和建設成本。
數據血緣圖譜介紹
字節的數據可分爲端數據和業務數據,這些記錄往往需要通過加工處理才能產生業務價值。數據加工處理的流程一般是讀取原始數據,進行數據清洗,再經過多種計算和存儲,最終匯入指標、報表和數據服務系統。數據血緣描述了數據的來源和去向,以及數據在多個處理過程中的轉換,是組織內使數據發揮價值的重要基礎能力。
數據地圖平臺在 2021 年接入了全鏈路核心元數據,包括但不限於:Hive、Clickhouse、Kafka、BI 報表、BI 數據集、畫像、埋點、MySQL、Abase。這些數據全部要通過數據血緣連接起來,進而可以進行影響分析、內部審計、SLA 保障、歸因分析、理解和查找數據、自動化推薦等操作。
隨着內部數據不斷膨脹,簡單的數據血緣圖譜已經無法滿足萬級表血緣的關係展示。一些突出的問題包括看不清單個表的直接上下游,看不清數據鏈路,整體情況等等。因此需要重構一種更清晰、靈活、便利的方式。下圖簡單展示了優化後的使用效果。
在新版血緣圖譜中,我們可以直接清晰的看到每個表的多層上下游依賴關係,甚至可以直接看到一些特殊場景下用戶關注的表屬性,通過點擊節點高亮查看數據鏈路,更可以看清每層的統計信息。在下文中我們將詳細拆解優化的全過程。
需求發現
要做出一個能滿足用戶需求的圖產品,首先是要清楚用戶想從圖中獲取什麼信息,從而有針對性的將這些信息展示出來。從血緣圖譜的背景本身可以推斷出用戶希望在圖譜中查看錶之間的關係,查看關係鏈路,而更多的使用場景待發掘。因此我們對內部重度用戶進行了訪談,整理得出了以下不同用戶角色使用數據血緣圖譜的用戶場景。
結合訪談結果和用戶的日常反饋,數據血緣圖譜的場景按目前用戶的使用頻率從大到小排序依次爲:
抽象出幾個主要需求即爲:
-
表血緣關係查看:能從圖中清楚的瀏覽用戶關注的表的上下游血緣關係,最好還能便捷的查看一些場景相關的表屬性。
-
表血緣鏈路查看:能清晰的查看到某個上游 / 下游表到用戶關注表的鏈路情況。
-
按關鍵指標分組查看:例如當表數據發生變更時,分組查看所有下游表的負責人以便通知變更。
-
篩選關鍵信息查看:例如用戶找數據指標的時候,僅看相關的報表更高效。
問題分析
其實上述需求舊版血緣圖譜都有一定程度上的滿足,我們需要去找出舊版血緣圖譜提供的功能爲什麼不滿足用戶需求,有哪些問題需要在新版中注意避免。
- 概覽:在數據量較小的情況下可用,在數據量大的時候完全不可用。看不清每層有多少個節點,層級關係是怎麼樣的,且鏈路查看困難。
節點較少,比較清晰
大量節點,查看困難
-
舊版血緣圖譜中功能細節粗糙:
-
用戶無法直觀的區分節點:舊版節點上顯示了表類型、庫名、表名。因此表名只能顯示幾個字符,不具備辨識度。
-
無法知曉表到表之間的任務:舊版血緣圖譜僅在側邊欄列出了與當前表相關的任務有哪些並未列出加工邏輯的對應關係,歸因分析困難。
-
分組結構不清晰:舊版是在原圖中框出節點來展示分組的。一方面是空間利用率更低,另一方面是看節點時難定位到所屬分組,看分組時則無法看清包含的節點。
-
篩選功能不直觀:符合篩選條件的節點高亮展示,而被篩掉的表仍在圖中,無法有效提升用戶瀏覽效率。
方案設計
用戶在使用過程中看重的是查看關係的效率和屬性的完備度,因此在設計優化方案時會盡量從這兩點出發去考慮。
首先是表數據查看的效率問題。看不清表名,無法區分相同前綴的表是用戶痛點之一。首先我們統計了現有表的平均字符數是 47 位,於是調寬了節點讓用戶能更直觀的區分表名。用數據地圖平臺中通用的類型圖表來代替色塊圖例,讓數據類型一目瞭然。
其次對於數據量大時看不清數據關係的問題,我們需要一個更緊湊清晰的數據呈現方式。通過需求分析和用戶調研,我們瞭解到用戶關心的是節點所在層級和節點之間的聯繫。對於同一層級節點的先後順序,次層級節點之間的關係不是很看重。
說到緊湊的佈局方式,自然而然我們就想到了列表。如果能用一個列表來承載層級血緣的節點,用連線來連接不同層級的節點,那麼久可以表達節點之間的血緣關係了。當節點較多超出一屏時可以拖動此列滾動條來查看更多節點,連線隨之刷新位置。當層級不滿一屏時整體居中展示,層級過多超過一屏時可以左右滑動查看。這樣在保留層級結構信息的同時最大程度的利用了可視區域,展示出了儘可能多的數據。
新版血緣圖譜支持了點擊任意節點則高亮該節點到主節點的鏈路功能。配合列滾動和連線刷新,不管數據量多大總能看清一整條數據鏈路。
我們還在每列列表頂部增加了層級信息和節點統計,讓用戶能同時查看每個節點細節和節點的整體分佈。最終實現效果如下圖:
當用戶想去找數,理解數或做歸因分析時,不僅要了解一個表的上游依賴,更需要理解表的加工邏輯。因此我們在節點的連線上新增了任務信息。當用戶 hover 到連線上後,連線會加粗高亮並彈出任務信息。我們還附上了大數據開發平臺的對應任務鏈接,點擊鏈接即可跳轉到新頁面查看任務邏輯詳情。
舊版血緣圖譜的篩選功能是在前端處理的,由於一些性能限制導致篩選後只能顯示部分數據,用戶無法得知符合條件的節點是否已經全部展示。新版血緣圖譜針對這個用戶痛點,將前端篩選改爲了服務端篩選,儘量展示全符合要求的數據。每個層級的頂欄對應更新爲篩選後的統計信息。同時更新連線,如果篩選後節點之間是有關聯的,也會展示關聯關係和高亮關係鏈路。
不同職能的用戶在不同場景下使用血緣圖譜時關注的節點屬性並不相同,如果血緣圖譜可以直接在圖上顯示用戶當前想關注的表屬性就能幫助用戶更高效的解決問題。於是我們在血緣圖譜上設計了屬性展示功能,用戶可以勾選自己感興趣的屬性直接顯示到圖中。比如下圖中展示了每個節點表熱度和生命週期兩個屬性。
技術實現
技術選型
在編碼實現之前,我們需要進行技術選型。好的選型往往能讓編碼事半功倍。在做技術選型時,我們會主要考慮實現複雜度、研發週期、可擴展性三個角度。分析整個血緣圖譜的需求:
-
Canvas 實現滾動條,節點文字標籤混排很複雜,要達到 HTML 的美觀度需要大量調試,後續迭代要新增屬性標籤,進行流式佈局會很頭痛。開放組件給別的產品複用也有很大的定製成本。而這些問題使用 React 框架渲染就可以輕鬆解決。
-
如果用 DOM 實現不但很難實現箭頭,在連線高亮時也很難靈活處理層疊關係。在大數據量下連線很多,還容易出現性能問題。而這是 Canvas 的優勢。
於是我們結合兩者之長,選用了 React + Canvas 的混合模式來實現血緣圖譜。Canvas 居於底部,僅負責畫連線。React 在上層負責渲染節點響應 hover 等交互。DOM 層疊關係如下:
整個血緣圖譜的初始化流程如下:
-
數據預處理:服務端給到點邊結構的數據。由於兩個節點之間可能存在多個任務,對應會有多條連線記錄。而血緣圖譜中相同兩個節點之間僅一條連線,對應多個任務。先做連線的合併處理。
-
計算節點層級:服務端會給到點邊結構的數據,根據主節點的連線關係向來源和去向兩個方向做廣度遍歷來確定每個節點的層級。
-
數據分組:按分組條件對每列數據進行分組計算。
-
節點佈局:根據層級和分組情況佈局節點,相對應的每個節點有 { x, y, width, height 屬性以確定每個節點的定位。
-
初始化畫布:畫布用於繪製連線,響應連線的交互。採用內部自研的圖形渲染引擎實現。
-
渲染節點:根據節點的位置和分組情況用 React 渲染出每一列節點 DOM。
-
渲染畫布:根據前景的列和節點位置調整畫布,繪製連線。在渲染連線時分兩個圖層:默認狀態連線在底層;高亮鏈路和高亮連線狀態下的連線在上層。這樣做的好處是高亮的連線永遠在默認狀態的上方,不用特殊處理圖形的層疊關係。
實現細節
用這種混合模式的一個挑戰就是 Canvas 和 DOM 的刷新率和同步率。 在血緣圖譜中滾動橫向滾動條和每一列的縱向滾動條時 Canvas 要進行及時的刷新以保證連線和節點的相對位置一定。
-
當圖譜橫向滾動時,每條連線的斜率不變,只是端點左右平移了。我們可以通過更新繪圖矩陣來加速這種情況下的更新,不需要去重計算每條連線的位置。具體做法是監聽容器的滾動事件,根據容器的 scrollLeft 屬性來更新繪圖矩陣後重繪。
-
當圖譜縱向滾動時,與當前滾動的列中節點相連的連線斜率和端點都有變化,而與滾動列不直接相連的連線無需更新。我們僅重計算並更新與當前列連接的線條位置。
另一個挑戰是 DOM 節點在大數據量下的性能問題。 通常情況下我們認爲 Canvas 在大數據量渲染有更好的性能,而萬級的 DOM 節點就會讓用戶在使用中感受到卡頓了。這時候我們想到了按需渲染。 用戶在圖譜可視區域中一屏能看到的節點數量是有限的,高度爲 1120 的容器中,一列僅存在至多 30 個節點。如果僅渲染可見的節點,則能保證使用 過程的流暢。具體做法是在節點佈局時增加以下步驟:
-
根據視口的位置(主要是圖容器的橫向滾動距離 scrollLeft )和每一列的滾動距離(主要是每一列容器的縱向滾動距離 scrollTop )計算目前的可視範圍。
-
計算節點座標時判斷是否在可視範圍的上半屏和下半屏內,如果在此範圍內則打標。多顯示一屏的節點是希望在用戶上下滾動瀏覽節點時不會出現空白區域閃一下等體驗不佳的問題。
-
計算出每一列的真實長度。
在 React 渲染時更新每列容器的長度,將節點根據座標絕對定位到正確的位 置上。看起來就跟全量渲染的效果一致,渲染效率大幅提升。
然而問題並不止於此。在進行大數據量的縱向滾動時,會發現幀率很低,交 互還是不流暢。分析得知是由於列表滾動時會在短時間內進行大量線條重計算和渲染。於是還要在 Canvas 繪製上進行優化。
我們從上圖可以看到在單層節點很多的情況下,主節點與不可見節點的連線可見,但是沒有任何價值,只是加重了用戶對當前節點連線查看的負擔。因此我們對線條也進行了渲染優化,僅當一條連線兩端的節點都在可見範圍中時才渲染連線,在連線的 Tooltip 上增加了來源去向的展示輔助查看。至此我們做到了在複雜情況下的流暢展示血緣數據。
總結
以上就是數據血緣圖譜的整個優化過程。在這個過程中,我總結起來就是在瞭解用戶訴求的前提下,剋制地表達關係圖中的信息,在合適的場景下突出核心的內容。做圖分析產品時不需要拘泥於某種形式,而是真正的從用戶需求出發,爲用戶服務。
關於我們
火山引擎大數據研發治理套件 DataLeap
一站式數據中臺套件,幫助用戶快速完成數據集成、開發、運維、治理、資產、安全等全套數據中臺建設,幫助數據團隊有效的降低工作成本和數據維護成本、挖掘數據價值、爲企業決策提供數據支撐。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/S83O5yvceQfoS_KqSjfS4g