圖數據結構,可以更好地表徵現實世界。美團業務相對較複雜,存在比較多的圖數據存儲及多跳查詢需求,亟需一種組件來對千億量級圖數據進行管理,海量圖數據的高效存儲和查詢是圖數據庫研究的核心課題。本文介紹了美團在圖數據庫選型及平臺建設方面的一些工做。
圖數據結構,可以很天然地表徵現實世界。好比用戶、門店、騎手這些實體能夠用圖中的點來表示,用戶到門店的消費行爲、騎手給用戶的送餐行爲能夠用圖中的邊來表示。使用圖的方式對場景建模,便於描述複雜關係。在美團,也有比較多的圖數據存儲及多跳查詢需求,歸納起來主要包括如下 4 個方面:前端
整體來講,美團須要一種組件來管理千億級別的圖數據,解決圖數據存儲以及多跳查詢問題。海量圖數據的高效存儲和查詢是圖數據庫研究的核心課題,如何在大規模分佈式場景中進行工程落地是咱們面臨的痛點問題。傳統的關係型數據庫、NoSQL 數據庫能夠用來存儲圖數據,可是不能很好處理圖上多跳查詢這一高頻的操做。git
Neo4j 公司在社交場景(見圖1)裏作了傳統關係型數據庫 MySQL 跟圖數據庫 Neo4j 的查詢性能對比 [1],在一個包含 100 萬人、每人約有 50 個朋友的社交網絡裏找最大深度爲 5 的朋友的朋友,實驗結果代表多跳查詢中圖數據庫優點明顯(見圖 2)。然而選取或者自主研發一款高吞吐、低查詢延時、能存儲海量數據且易用的圖數據庫很是困難。下面將介紹美團在圖數據庫選型及平臺建設方面的一些工做。github
在圖數據庫的選型上咱們主要考慮瞭如下 5 點:(A) 項目開源,暫不考慮需付費的圖數據庫;(B) 分佈式架構設計,具有良好的可擴展性;(C) 毫秒級的多跳查詢延遲;(D) 支持千億量級點邊存儲;(E) 具有批量從數倉導入數據的能力。算法
分析 DB-Engines[2] 上排名前 30 的圖數據庫,剔除不開源的項目,咱們將剩餘的圖數據庫分爲三類:數據庫
DGraph 是由前 Google 員工 Manish Rai Jain 離職創業後,在 2016 年推出的圖數據庫產品,底層數據模型是 RDF[12],基於 Go 語言編寫,存儲引擎基於 BadgerDB[13] 改造,使用 RAFT 保證數據讀寫的強一致性。後端
NebulaGraph 是由前 Facebook 員工葉小萌離職創業後,在 2019年 推出的圖數據庫產品,底層數據模型是屬性圖,基於 C++ 語言編寫,存儲引擎基於 RocksDB[14] 改造,使用 RAFT 保證數據讀寫的強一致性。安全
這兩個項目的創始人都在互聯網公司圖數據庫領域深耕多年,對圖數據庫的落地痛點有深入認識,總體的架構設計也有較多類似之處。在圖數據庫最終的選型上,咱們基於 LDBC-SNB 數據集[15]對 NebulaGraph、DGraph、HugeGraph 進行了深度性能測評,測試詳情見文章:主流開源分佈式圖數據庫 Benchmark,從測試結果看 NebulaGraph 在數據導入、實時寫入及多跳查詢方面性能均優於競品。此外,NebulaGraph 社區活躍,問題響應速度快,因此團隊最終選擇基於 NebulaGraph 來搭建圖數據庫平臺。網絡
一個完整的 NebulaGraph 集羣包含三類服務,即 Query Service、Storage Service 和 Meta Service。每類服務都有其各自的可執行二進制文件,既能夠部署在同一節點上,也能夠部署在不一樣的節點上。下面是NebulaGraph 架構設計(見圖 3)的幾個核心點16。數據結構
NebulaGraph 基於 C++ 實現,架構設計支持存儲千億頂點、萬億邊,並提供毫秒級別的查詢延時。咱們在 3 臺 48U192G 物理機搭建的集羣上灌入 10 億美食圖譜數據對 NebulaGraph 的功能進行了驗證。架構
爲了統一管理圖數據,減小工程同窗在圖數據庫集羣上的運維壓力,咱們基於開源分佈式圖數據庫 NebulaGraph,搭建了一套一站式圖數據庫自助管理平臺(見圖 4),該平臺包含如下 4 層:
數據存儲層。 支持兩種圖數據庫集羣的部署。
與業界方案相比,團隊主導設計的圖數據庫平臺除了支持存儲千億頂點、萬億邊,具有毫秒級別查詢能力外,還提供了以下四項能力:應用可用性 SLA 達 99.99%;支持每小時百億量級數據導入;實時寫入數據時保證多集羣數據最終一致性;易用的圖譜可視化能力。下面將介紹具體的設計思路。
首先介紹單應用多集羣高可用模塊的設計(AP 方案)。爲何有 AP 方案的設計呢?由於接入圖數據庫平臺的業務方比較在乎的指標是集羣可用性。在線服務對集羣的可用性要求很是高,最基礎的要求是集羣可用性能達到 4 個 9,即一年裏集羣的不可用時間要小於一個小時。對於在線服務來講,服務或者集羣的可用性是整個業務的生命線,若是這點保證不了,即便集羣提供的能力再多再豐富,那麼業務方也不會考慮使用,可用性是業務選型的基礎。
另外,公司要求中間件要有跨區域容災能力,即要具有在多個地域部署多集羣的能力。咱們分析了平臺接入方的業務需求,大約 80% 的場景是 T+1 全量導入數據、線上只讀。在這種場景下,對圖數據的讀寫強一致性要求並不高,所以咱們設計了單應用多集羣這種部署方案。
AP 方案部署方式能夠參考圖 5,一個業務方在圖數據庫平臺上建立了 1 個應用並部署了 4 個集羣,其中北京 2 個、上海 2 個,平時這 4 個集羣同時對外提供服務。假如如今北京集羣 1 掛了,那麼北京集羣 2 能夠提供服務。若是說真那麼不巧,北京集羣都掛了,或者北京側對外的網絡不可用,那麼上海的集羣也能夠提供服務。在這種部署方式下,平臺會盡量地經過一些方式來保證整個應用的可用性。而後每一個集羣內部儘可能部署同機房的機器,由於圖數據庫集羣內部 RPC 很是多,若是有跨機房或者跨區域的頻繁調用,整個集羣對外的性能會比較低。
高可用模塊主要包含下面 4 個部分,如上圖 6 所示:
第一部分是右側的圖數據庫 Agent,它是部署在圖數據庫集羣的一個進程,用來收集機器和圖數據庫三個核心模塊的信息,並上報到圖數據庫平臺。Agent 可以接收圖數據庫平臺的命令並對圖數據庫進行操做。
第二部分是圖數據庫平臺,它主要是對集羣進行管理,並同步圖數據庫集羣的狀態到配置中心。
第三部分是圖數據庫 SDK,主要負責管理鏈接到圖數據庫集羣的鏈接。若是業務方發送了某個查詢請求,SDK 會進行集羣的路由和負載均衡,選擇出一條高質量的鏈接來發送請求。此外,SDK 還會處理圖數據庫集羣中問題機器的自動降級以及恢復,而且支持平滑切換集羣的數據版本。
第四部分是配置中心,相似 ZooKeeper,存儲集羣的當前狀態。
第二個模塊是每小時百億量級數據導入模塊,平臺在 2019 年末- 2020 年初全量導入數據的方式是調用 NebulaGraph 對外提供的批量數據導入接口,這種方式的數據寫入速率大概是每小時 10 億級別,導入百億數據大概要耗費 10 個小時,耗時較長。此外,在以幾十萬每秒的速度導數據的過程當中,會長期佔用機器的 CPU、IO 資源,一方面會對機器形成損耗,另外一方面數據導入過程當中集羣對外提供的讀性能會變弱。
爲了解決上面兩個問題,平臺進行了以下優化:在 Spark 集羣中直接生成圖數據庫底層文件 SST File,再借助 RocksDB 的 Bulkload 功能直接 ingest 文件到圖數據庫。
數據導入的核心流程能夠參考圖 7,當用戶執行導數據操做後,圖數據庫平臺會向公司的 Spark 集羣提交一個 Spark 任務,在 Spark 任務中會生成圖數據庫裏相關的點、邊以及點索引、邊索引相關的 SST 文件,並上傳到美團的 S3 雲存儲上。文件生成後,圖數據庫平臺會通知應用中多個集羣去下載這些存儲文件,以後完成 ingest 跟 compact 操做,最後完成數據版本的切換。
爲兼顧各個業務方的不一樣需求,平臺統一了應用導入、集羣導入、離線導入、在線導入,以及全量導入、增量導入這些場景,而後細分紅下面九個階段,從流程上保證在導數據過程當中應用總體的可用性:SST File 生成 、SST File 下載 、ingest、compact、數據校驗、增量回溯、數據版本切換、集羣重啓、數據預熱。
第三個模塊是實時寫入多集羣數據同步模塊,平臺約有 15% 的需求場景是在實時讀取數據時,還要把新產生的業務數據實時寫入集羣,而且對數據的讀寫強一致性要求不高。就是說,業務方寫到圖數據庫裏的數據,不須要立馬能讀到。針對上述場景,業務方在使用單應用多集羣這種部署方案時,多集羣裏的數據須要保證最終一致性。針對這一需求,咱們作了如下設計。
第一部分是引入 Kafka 組件,業務方在服務中經過 SDK 對圖數據庫進行寫操做時,SDK 並不直接寫圖數據庫,而是把寫操做寫到 Kafka 隊列裏,以後由該應用下的多個集羣異步消費這個 Kafka 隊列。
第二部分是集羣在應用級別可配置消費併發度,來控制數據寫入集羣的速度。具體流程以下:
第三部分是在實時寫入數據過程當中,平臺能夠同步生成一個全量數據版本,並作平滑切換(見圖 9),確保數據的不重、不漏、不延遲。
第四個模塊是圖可視化模塊(見圖10),主要是用於解決子圖探索問題。當用戶在圖數據庫平臺經過可視化組件查看圖數據時,能儘可能經過恰當的交互設計來避免由於節點過多而引起爆屏。主要包括如下幾個功能:
該項目數據是基於美團商戶數據、用戶評論構建的餐飲娛樂知識圖譜,覆蓋美食、酒店、旅遊等領域,包含 13 類實體和 22 類關係。目前,點邊數量大概在百億級別,數據 T+1 全量更新,主要用於解決搜索或者智能助理裏 KBQA(全稱:Knowledge Based Question Answer)類問題。核心處理流程是經過 NLP 算法識別關係和實體後構造出 NebulaGraph SQL 語句,再到圖數據庫獲取數據。
典型的應用場景包括商場找店,好比,某個用戶想知道望京新薈城這個商場有沒有海底撈,系統能夠快速查出結果告訴用戶;另外一個場景是標籤找店,用戶想知道望京 SOHO 附近有沒有適合情侶約會的餐廳,或者能夠多加幾個場景標籤,系統均可以幫忙查找出來。
該項目數據是基於醫美商家信息構建的醫美知識圖譜,包含 9 類實體和 13 類關係,點邊數量在百萬級別,一樣也是 T+1 全量更新,主要用於大搜底層實時召回,返回與 Query 相關的商戶、產品或醫生信息,解決醫美類搜索詞少結果、無結果問題。好比,某個用戶搜「啤酒肚」這種症狀、或者「潤百顏」這類品牌,系統能夠召回相關的醫美門店。
該項目數據來自用戶的畫像信息、商戶的特徵信息、用戶半年內收藏/購買行爲,數據量級是 10 億級別,T+1 全量更新。如今美團 App 和點評 App 上默認的商戶推薦列表是由深度學習模型生成的,但模型並不會給出生成這個列表的理由,缺乏可解釋性。
而在圖譜裏用戶跟商戶之間自然存在多條連通路徑,項目考慮選出一條合適路徑來生成推薦理由,在 App 界面上展現給用戶推薦某家店的緣由。該項目基於用戶的協同過濾算法來生成推薦理由,在家鄉、消費水平、偏好類目、偏好菜系等多個組合維度中找出多條路徑,而後給這些路徑打分,選出一條分值較高的路徑,以後按照特定 Pattern 產出推薦理由。經過上述方式,就能夠得到「在北京喜歡北京菜的山東老鄉都說這家店很贊」,或者「廣州老鄉都中意他家的正宗北京炸醬麪」這類理由。
該項目把代碼庫中代碼依賴關係寫入到圖數據庫。代碼庫中存在不少服務代碼,這些服務會包括對外提供的接口,這些接口的實現依賴於該服務中某些類的成員函數,這些類的成員函數又依賴了本類的成員變量、成員函數或者其它類的成員函數,那麼它們之間的依賴關係就造成了一張圖,能夠把這個圖寫到圖數據庫裏作代碼依賴分析。
典型應用場景是精準測試:當開發同窗完成需求並向公司的代碼倉庫提交了 PR 後,能夠把更改實時地寫到圖數據庫中。這樣的話,開發同窗就能查到他所寫的代碼影響了哪些外部接口,而且藉助圖可視化組件查看調用路徑。若是開發同窗原本是要改接口 A 的行爲,改了不少代碼,可是他可能並不知道他改的代碼也會影響到對外接口 B、C、D,這時候就能夠用代碼依賴分析來作個 Check,增長測試的完備性。
目前,圖數據庫平臺基本具有了對圖數據的一站式自助管理功能。若是某個業務方要使用這種圖數據庫能力,那麼業務方能夠在平臺上自助地建立圖數據庫集羣、建立圖的 Schema、導入圖數據、配置導入數據的執行計劃、引入平臺提供的 SDK 對數據進行操做等等。平臺側主要負責各業務方圖數據庫集羣的穩定性。目前,美團有三四十個業務已經在平臺上落地,基本知足了各個業務方的需求。
將來規劃主要有兩個方向,第一,根據業務場景優化圖數據庫內核,提高平臺穩定性,開發的通用 Feature 持續反哺 NebulaGraph 社區。第二,挖掘更多的圖數據價值。如今平臺僅支持圖數據存儲及多跳查詢這種基本能力,後續將基於 NebulaGraph 去探索圖學習、圖計算的能力,爲平臺用戶提供更多挖掘圖數據價值的功能。
登昌、梁帥、高辰、楊鑫、尊遠、王超等,均爲美團搜索與NLP部工程師。
若是你對「圖存儲」、「圖學習」、「圖計算」感興趣,歡迎給咱們投遞簡歷,投遞郵箱:zhaodengchang@meituan.com。
閱讀美團技術團隊更多技術文章合集
前端 | 算法 | 後端 | 數據 | 安全 | 運維 | iOS | Android | 測試
| 在公衆號菜單欄對話框回覆【2020年貨】、【2019年貨】、【2018年貨】、【2017年貨】等關鍵詞,可查看美團技術團隊歷年技術文章合集。
| 本文系美團技術團隊出品,著做權歸屬美團。歡迎出於分享和交流等非商業目的轉載或使用本文內容,敬請註明「內容轉載自美團技術團隊」。本文未經許可,不得進行商業性轉載或者使用。任何商用行爲,請發送郵件至tech@meituan.com申請受權。