位元組跳動自研一站式萬億級圖儲存/計算/訓練平臺

qing_yun發表於2022-06-24

      本文整理自DTCC2021大會分陳巨集智博士的演講,將深入介紹該團隊在分散式圖資料庫、圖計算、圖訓練這三個場景下的自研系統(ByteGraph、ByteGAP、ByteGNN)之架構設計,技術實現,關鍵挑戰以及效能分析。並概述在部分業務場景上,如何通過GraphStudio圖平臺提供一站式圖資料服務。

  陳巨集智博士,目前在位元組跳動基礎架構組擔任高階研發工程師,本科畢業於華中科技大學計算機學院,博士畢業於香港中文大學電腦科學與工程系,在計算機系統及資料庫領域發表頂會論文(EuroSys/SoCC/SIGMOD/KDD/TPDS等)十餘篇,研究方向為分散式系統、分散式計算、大規模圖系統,曾獲微軟研究院“明日之星”等榮譽稱號。

  圖資料是一種由點和邊組成的半結構化資料,已被廣泛應用在社交網路、金融風控、生命科學等各個領域。位元組跳動基礎架構ByteGraph團隊從2018年開始打造基於海量圖資料的分散式儲存/計算系統生態,並支援了抖音、頭條、西瓜、火山等幾乎位元組跳動全部產品線。

  ByteGraph全球範圍內多個機房都部署了例項,能夠支援線上千萬貼片,其圖計算的願景是支援百萬億級的邊的規模,此前的圖計算引擎是作為一個In-Memory System,沒有辦法做到百萬億級別的資料分析,所以位元組跳動基礎架構ByteGraph團隊自研了這樣一套系統。

  圖資料庫

  ▶︎ 瞭解圖資料庫

  圖資料庫相比傳統關聯式資料庫,最基本的區別是建模不同,圖資料庫是基於點、邊和屬性構成,關係型資料庫是基於Staple來做。查詢實現也不同,關係型資料庫查詢通常需要做多個表單JOIN,大資料量只能分庫分表。圖資料庫在圖上遍歷(traverse),通過運算元去執行,更為高效。位元組跳動的圖資料庫是通過更細度的Message做Partition的方式去執行結果,然後把結果返回。

  ▶︎ 資料模型和查詢語言

  圖資料庫資料模型分為兩種,RDF(俗稱三元組)和屬性圖。ByteGraph採用有向屬性圖建模。有向屬性圖由點(Vertex)、邊(Edge)、屬性(Property)構成,其中點是實體、概念物件。邊是點之間的關係、聯絡。

  有向屬性圖對映真實世界的實體,見上圖,比如一個自然人,我們是通過Unit32和Unit64,前者表示自然人,後者表示場景。通過有向屬性圖建模,可以把不同型別的應用基於同一個自然人關聯起來,進行跨表查詢。比如基於一個人在某些場景上的使用者習慣,通過資料管理,希望借用這些查詢結果能夠在推薦場景使用,則可以關聯一個真實的自然人,這樣帶標籤的屬性圖,一定要有一個固定的Schema。如上圖中,所有球員型別的點都有一個固定的Schema,球隊的Schema是另外一種型別。

  邊是維護實體間的關係,需要用最基本的節點、終點和邊上的型別,比如關注型別、點贊型別,基於這種型別繫結的Schema去儲存資訊,如一個人對一個視訊點贊,針對這些使用者的屬性和視訊屬性做Sport,可以在邊上對該事件資訊建模。

  ByteGraph支援Gremlin查詢語言。Gremlin語言是圖遍歷式語言,可以簡單理解為,先在圖上定位到一個點,然後從該點開始做圖上的深度/寬度遍歷,在圖上每一步遍歷用Step來描述,不同的Step有不同的功能。

  通過不同功能的Step表示查詢邏輯,比如需要去對一個自然人的二跳鄰居做一個屬性上的限制,能夠Out,每次Out對應的引數就是Label,可以限制需要滿足哪些屬性,之後也可以通過計算方式的屬性總和,一定要大於或小於某一個值去做限制。我們認為這樣的方式對自己的業務方來說更友好一點,因為業務方不僅僅是有資料庫背景的同學,更多的是分析型別的同學。

  ▶︎ ByteGraph架構與實現

  ByteGraph整體架構有三層:查詢引擎層(GQ)、儲存引擎層(GS)和磁碟儲存層,我們是用高可用、高可靠來做三層的元件,每層由多個程式例項組成叢集,查詢層和記憶體儲存層可以混合部署或獨立部署。其中,查詢引擎層主要做使用者Session管理以及最核心的查詢解析,解析之後變成語法數,接下來就會深入展開,然後去做資料分佈的Road Mapping,查詢更側重於高併發實現。儲存引擎層(GS)管理記憶體中的資料,如何去做資料切片,如何實現事務性,追求相對偏底層的極致效能,中間通過RPC去做關聯。

  具體來看ByteGraph查詢引擎層(GQ),其實和MySQL的SQL層一樣,主要工作是做查詢的解析和處理,其中“處理”可以分為以下三個步驟:

  Parser階段:我們實現了一個手寫的基於Gremlin遞迴下降解析器,將查詢語言解析成一個查詢語法樹。

  生成查詢計劃:把步驟1中的查詢語法樹按照一定的查詢優化策略(RBO&CBO)轉換成執行計劃。為了減少解析和優化的開銷,我們支援了查詢計劃快取。

  執行查詢計劃:和GraphStorage(GS)互動,完成查詢計劃。需要理解儲存層資料分Partition的邏輯,找到資料,下推運算元,merge查詢結果,完成查詢。

  我們希望資料的計算是在資料所在的機器內部發生,會把這些查詢下推到儲存層去做一定的計算,不是把結果從儲存層通過RPC回到查詢層去做優化和計算,以減少資料傳輸。

  查詢優化器除了做基於規則的優化外,也做了基於代價(Cost-based)的查詢優化,降低相關開銷。

  在第三層儲存引擎層我們做了讀寫放大平衡,並不希望找一個點再把一個超大的Partition撈上來,所以我們單獨去做拆分。如某大V(點)有100萬粉絲,則Partition中有100萬條邊和終點。一個Partition按照排序鍵組織成Btree,拆成若干跨度,第一層記錄當前的點和邊,作為當前配置,假設現在基於100切分會有1萬。

  我們如何做到事務性?簡單來說把一個單機引擎記憶體其中70%的Memory作為Catch,本身就是對剛才涉及到的若干個Part,其中每個元素表示一個Partition,基於我們自己特定優化的規則定義,當一個流量進來時會找當前Catch是不是有對應配置,如果沒有就會Persistent,拿到以後記錄當前Log ID。因為可能要考慮如果一臺機器掛掉,Catch的資料沒有及時更新,若干個機器能夠組織在一起。

  圖訓練引擎ByteGNN

  ▶︎ 什麼是圖訓練

  簡單介紹一下什麼是圖訓練,一切皆向量,圖也不例外。

  目前,業界的圖資料庫其實也做了跟AI和ML領域的結合,AI和ML的領域是一個向量作用,整體來說是要有一個方向,希望整個圖上的每一個點能夠預設到一個高維空間。以二維空間為例,比如圖上紅色的點和藍色的點,區域性的TOP性質比較相似,整個Model希望學出一個方式,讓上圖中紅色和藍色的點能夠在二維空間中距離儘量近。

  ▶︎ 業界框架簡介

  2019年開始,各個大廠都有自己開源的訓練模型實踐,都是基於分散式的,如GraphLearn、Euler、DGL、AGL等。但是整體來說這些開源框架遇到大規模資料時會有瓶頸,我們去拿這些框架做訓練,比如一個千億級別的圖資料在真實場景上Run,可能訓練需要三天三夜才能收尾,而高效地拿到最近的資料才能更好地去做推薦,所以訓練有必要加速。希望做推薦可以看到的不是T+3的資料,而是T+1甚至T+0的資料。

  ▶︎ ByteGNN設計思想

  我們自研的ByteGNN 框架是基於Mini-Task的大規模圖神經網路訓練引擎,取樣的過程抽象成了一個計算圖,使用者基於Python去做Programming,每個訓練的OP對應C++裡的實現,整體和TensorFlow比較相似,使用者寫完一個模型就在GNN生成取樣和訓練。原生的開源框架依賴於TensorFlow本身自帶的邏輯去做訓練層的訓練。我們把取樣和訓練二者都抽象成了計算圖,分別為執行訓練計算圖T-Worker,執行取樣計算圖S-Worker,通過動態排程使得整個計算資源的利用率更高,某個開源框架的執行效率可能是10%-20%,我們可以直接拉到80%。

  我們每次取樣其實沒有Pipeline過程,可以理解為通過一個語法解析器把查詢邏輯生成計算圖,然後得到一個最優效果,做優化以後整體做一次訓練的時長會顯著變短。ByteGNN是通過Python運算元下推至C++,減少Tensors在Python/C++間的資料轉換。

  當一張圖非常大,ByteGNN設計了取樣友好的圖資料切分策略,按取樣概率隨機選擇種子點集,基於點集做並行BFS將圖劃分成細粒度Blocks,保證資料的Locality,然後將Blocks基於資料區域性性優化策略分配給score最大的Partition。比如,可以把整個圖切成10萬億張的圖,切成10萬億個Blocks,然後分別Assign到當前的100臺機器,就是這樣的平衡之後整個資料的Locality會變得很好,在取樣的時候一跳和二跳都已經在普及,不需要進行網路傳送。

  圖分析引擎

  ▶︎ 圖分析及業內框架簡介

  簡單來說,圖分析就是在大規模圖資料上做迭代式地、以點/邊/子圖為粒度地計算密集型任務。

  傳統的批處理系統如MapReduce/Spark執行圖演算法需要多輪迭代shuffle大量資料,效率低,資源消耗大。

  目前,業內圖資料計算模型主要有節點中心計算模型、邊中心計算模型、路徑中心計算模型和子圖中心資料模型,各有不同的優缺點。比如,節點中心計算模型,演算法實現簡單,但是通訊開銷大,隨機訪問嚴重;邊中心計算模型,資料順序訪問,適合基於磁碟系統,但是通訊開銷大,適用演算法範圍小;子圖中心計算模型,通訊開銷小,但是子圖劃分困難,抽象層次低,演算法實現複雜。

  ▶︎ ByteGap設計思想

  整體來說ByteGAP就是圖計算和圖挖掘兩類,不同於以點為中心的程式設計模型,ByteGAP採用以Task為中心的程式設計模型,單個點或者邊構成最基本的計算單元,單個子圖候選集構成圖挖掘計算單元,挖掘裡面通常是有狀態的,因為需要不斷地去找,做了第一個Match之後要做第二個Match,每次Match過程中都有非常多的組合,記憶體又不夠用了,那怎麼辦?

  我們做成可擴充套件的系統,支援百萬邊規模的圖資料離線計算,記憶體開銷有上界,不容易OOM,搭載可擴充套件外存。

  我們有自己的Partition演算法,支援BSP和ASP兩種計算模式,雲原生相對更復雜。點需要無狀態,一旦有狀態就需要保證能夠可恢復。整體來說,我們把相關資訊分成兩個Part儲存:

  一個Part是把點和Value、狀態這些資訊存在記憶體,要考慮機器掛掉了怎麼辦,對應的邊以及邊上的屬性節點存在記憶體,通過CheckPoint機制保證資料不丟,如果丟了比如算到第二輪就掛掉,當前掛掉的機器會重新拉起程式,其它的機器會幫助恢復第二十一輪到第二十二輪的狀態。

  另一個Part是所有的邊都存在於外側儲存NVM+SSD上,有了這樣的Multi Layer儲存之後整個系統就會變得可擴充套件。

  此外,計算模型也做了很多優化,比如計算和通訊的Pipeline,執行下一輪Receive時有一部分已經開始算起來,不需要等,同時也做了Message Combine。還有前面說的整個記憶體中Task無狀態,有狀態的部分持久化儲存,保證資料不可丟失。同時也支援容錯,計算資源池化,多工共享。

  我們通過GraphStudio平臺,把三個引擎串起來,比如要做圖查詢對應的Engine可以把結果視覺化地顯示出來,要做計算也有業務去選演算法和引數,然後把GNN引擎拉起來,去做生命週期管理。

  整體來看,位元組跳動基礎架構ByteGraph團隊在分散式圖資料庫、圖計算、圖訓練這三個場景下的自研系統(ByteGraph、ByteGAP、ByteGNN),能夠支撐集團的所有和圖相關的場景,從公開資料集測試結果來看快了30倍左右。目前,團隊也積極聯合學術界力量,與香港中文大學、北京理工大學的老師展開合作,一起推動圖資料庫發展。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69925873/viewspace-2902700/,如需轉載,請註明出處,否則將追究法律責任。

相關文章