美團圖數(shù)據(jù)庫平臺建設及業(yè)務實踐

1 前言
2 圖數(shù)據(jù)庫選型
3 NebulaGraph架構(gòu)
4 圖數(shù)據(jù)庫平臺建設
4.1 高可用模塊設計
4.2 每小時百億量級數(shù)據(jù)導入模塊設計
4.3 實時寫入多集群數(shù)據(jù)同步模塊設計
4.4 圖可視化模塊設計
5 業(yè)務實踐
5.1 智能助理
5.2 搜索召回
5.3 圖譜推薦理由
5.4 代碼依賴分析
6 總結(jié)與展望
7 作者信息
8 參考資料
9 招聘信息
1 前言
圖數(shù)據(jù)結(jié)構(gòu),能夠很自然地表征現(xiàn)實世界。比如用戶、門店、騎手這些實體可以用圖中的點來表示,用戶到門店的消費行為、騎手給用戶的送餐行為可以用圖中的邊來表示。使用圖的方式對場景建模,便于描述復雜關(guān)系。在美團,存在比較多的圖數(shù)據(jù)存儲及多跳查詢需求,概括起來主要包括以下 4 個方面:
圖譜挖掘: 美團有美食圖譜、商品圖譜、旅游圖譜、用戶全景圖譜在內(nèi)的近 10 個領域知識圖譜,數(shù)據(jù)量級大概在千億級別。在迭代、挖掘數(shù)據(jù)的過程中,需要一種組件對這些圖譜數(shù)據(jù)進行統(tǒng)一的管理。 安全風控: 業(yè)務部門有內(nèi)容風控的需求,希望在商戶、用戶、評論中通過多跳查詢來識別虛假評價;在支付時進行金融風控的驗證,實時多跳查詢風險點。 鏈路分析: 包括代碼分析、服務治理、數(shù)據(jù)血緣管理,比如公司數(shù)據(jù)平臺上有很多 ETL Job,Job 和 Job 之間存在強弱依賴關(guān)系,這些強弱依賴關(guān)系形成了一張圖,在進行 ETL Job 的優(yōu)化或者故障處理時,需要對這個圖進行實時查詢分析。 組織架構(gòu): 公司組織架構(gòu)的管理,實線匯報鏈、虛線匯報鏈、虛擬組織的管理,以及商家連鎖門店的管理。比如,維護一個商家在不同區(qū)域都有哪些門店,能夠進行多層關(guān)系查找或者逆向關(guān)系搜索。
總體來說,美團需要一種組件來管理千億級別的圖數(shù)據(jù),解決圖數(shù)據(jù)存儲以及多跳查詢問題。海量圖數(shù)據(jù)的高效存儲和查詢是圖數(shù)據(jù)庫研究的核心課題,如何在大規(guī)模分布式場景中進行工程落地是我們面臨的痛點問題。傳統(tǒng)的關(guān)系型數(shù)據(jù)庫、NoSQL 數(shù)據(jù)庫可以用來存儲圖數(shù)據(jù),但是不能很好處理圖上多跳查詢這一高頻的操作。
Neo4j 公司在社交場景(見圖1)里做了傳統(tǒng)關(guān)系型數(shù)據(jù)庫 MySQL 跟圖數(shù)據(jù)庫 Neo4j 的查詢性能對比 [1],在一個包含 100 萬人、每人約有 50 個朋友的社交網(wǎng)絡里找最大深度為 5 的朋友的朋友,實驗結(jié)果表明多跳查詢中圖數(shù)據(jù)庫優(yōu)勢明顯(見圖 2)。然而選取或者自主研發(fā)一款高吞吐、低查詢延時、能存儲海量數(shù)據(jù)且易用的圖數(shù)據(jù)庫非常困難。下面將介紹美團在圖數(shù)據(jù)庫選型及平臺建設方面的一些工作。


2 圖數(shù)據(jù)庫選型
在圖數(shù)據(jù)庫的選型上我們主要考慮了以下 5 點:(A) 項目開源,暫不考慮需付費的圖數(shù)據(jù)庫;(B) 分布式架構(gòu)設計,具備良好的可擴展性;(C) 毫秒級的多跳查詢延遲;(D) 支持千億量級點邊存儲;(E) 具備批量從數(shù)倉導入數(shù)據(jù)的能力。
分析 DB-Engines[2] 上排名前 30 的圖數(shù)據(jù)庫,剔除不開源的項目,我們將剩余的圖數(shù)據(jù)庫分為三類:
第一類:Neo4j[3]、ArangoDB[4]、Virtuoso[5]、TigerGraph[6]、RedisGraph[7]。 此類圖數(shù)據(jù)庫只有單機版本開源可用,性能優(yōu)秀,但不能應對分布式場景中數(shù)據(jù)的規(guī)模增長,即不滿足選型要求(B)、(D)。 第二類:JanusGraph[8]、HugeGraph[9]。 此類圖數(shù)據(jù)庫在現(xiàn)有存儲系統(tǒng)之上新增了通用的圖語義解釋層,圖語義層提供了圖遍歷的能力,但是受到存儲層或者架構(gòu)限制,不支持完整的計算下推,多跳遍歷的性能較差,很難滿足 OLTP 場景下對低延時的要求,即不滿足選型要求(C)。 第三類:DGraph[10]、NebulaGraph[11]。 此類圖數(shù)據(jù)庫根據(jù)圖數(shù)據(jù)的特點對數(shù)據(jù)存儲模型、點邊分布、執(zhí)行引擎進行了全新設計,對圖的多跳遍歷進行了深度優(yōu)化,基本滿足我們的選型要求。
DGraph 是由前 Google 員工 Manish Rai Jain 離職創(chuàng)業(yè)后,在 2016 年推出的圖數(shù)據(jù)庫產(chǎn)品,底層數(shù)據(jù)模型是 RDF[12],基于 Go 語言編寫,存儲引擎基于 BadgerDB[13] 改造,使用 RAFT 保證數(shù)據(jù)讀寫的強一致性。
NebulaGraph 是由前 Facebook 員工葉小萌離職創(chuàng)業(yè)后,在 2019年 推出的圖數(shù)據(jù)庫產(chǎn)品,底層數(shù)據(jù)模型是屬性圖,基于 C++ 語言編寫,存儲引擎基于 RocksDB[14] 改造,也使用 RAFT 保證數(shù)據(jù)讀寫的強一致性。
這兩個項目的創(chuàng)始人都在互聯(lián)網(wǎng)公司圖數(shù)據(jù)庫領域深耕多年,對圖數(shù)據(jù)庫的落地痛點有深刻認識,整體的架構(gòu)設計也有較多相似之處。在圖數(shù)據(jù)庫最終的選型上,我們基于 LDBC-SNB 數(shù)據(jù)集[15]對 NebulaGraph、DGraph、HugeGraph 進行了深度性能測評,測試詳情見文章:主流開源分布式圖數(shù)據(jù)庫 Benchmark,從測試結(jié)果看 NebulaGraph 在數(shù)據(jù)導入、實時寫入及多跳查詢方面性能均優(yōu)于競品。此外,NebulaGraph 社區(qū)活躍,問題響應速度快,所以我們團隊最終選擇基于 NebulaGraph 來搭建圖數(shù)據(jù)庫平臺。

一個完整的 NebulaGraph 集群包含三類服務,即 Query Service、Storage Service 和 Meta Service。每類服務都有各自的可執(zhí)行二進制文件,既可以部署在同一節(jié)點上,也可以部署在不同的節(jié)點上。下面是NebulaGraph 架構(gòu)設計(見圖 3)的幾個核心點[16][17]。
Meta Service: 架構(gòu)圖中右側(cè)為 Meta Service 集群,它采用 Leader/Follower 架構(gòu)。Leader 由集群中所有的 Meta Service 節(jié)點選出,然后對外提供服務;Followers 處于待命狀態(tài),并從 Leader 復制更新的數(shù)據(jù)。一旦 Leader 節(jié)點 Down 掉,會再選舉其中一個 Follower 成為新的 Leader。Meta Service 不僅負責存儲和提供圖數(shù)據(jù)的 Meta 信息,如 Schema、數(shù)據(jù)分片信息等,同時還提供 Job Manager 機制管理長耗時任務,負責指揮數(shù)據(jù)遷移、Leader 變更、數(shù)據(jù) compaction、索引重建等運維操作。 存儲計算分離: 在架構(gòu)圖中 Meta Service 的左側(cè),為 NebulaGraph 的主要服務,NebulaGraph 采用存儲與計算分離的架構(gòu),虛線以上為計算,以下為存儲。存儲計算分離有諸多優(yōu)勢,最直接的優(yōu)勢就是,計算層和存儲層可以根據(jù)各自的情況彈性擴容、縮容。存儲計算分離還帶來了另一個優(yōu)勢:使水平擴展成為可能。此外,存儲計算分離使得 Storage Service 可以為多種類型的計算層或者計算引擎提供服務。當前 Query Service 是一個高優(yōu)先級的 OLTP 計算層,而各種 OLAP 迭代計算框架會是另外一個計算層。 無狀態(tài)計算層: 每個計算節(jié)點都運行著一個無狀態(tài)的查詢計算引擎,而節(jié)點彼此間無任何通信關(guān)系。計算節(jié)點僅從 Meta Service 讀取 Meta 信息以及和 Storage Service 進行交互。這樣設計使得計算層集群更容易使用 K8s 管理或部署在云上。每個查詢計算引擎都能接收客戶端的請求,解析查詢語句,生成抽象語法樹(AST)并將 AST 傳遞給執(zhí)行計劃器和優(yōu)化器,最后再交由執(zhí)行器執(zhí)行。 Shared-nothing 分布式存儲層: Storage Service 采用 Shared-nothing 的分布式架構(gòu)設計,共有三層,最底層是 Store Engine,它是一個單機版 Local Store Engine,提供了對本地數(shù)據(jù)的 get/put/scan/delete 操作,該層定義了數(shù)據(jù)操作接口,用戶可以根據(jù)自己的需求定制開發(fā)相關(guān) Local Store Plugin。目前,NebulaGraph 提供了基于 RocksDB 實現(xiàn)的 Store Engine。在 Local Store Engine 之上是 Consensus 層,實現(xiàn)了 Multi Group Raft,每一個 Partition 都對應了一組 Raft Group。在 Consensus 層上面是 Storage interfaces,這一層定義了一系列和圖相關(guān)的 API。這些 API 請求會在這一層被翻譯成一組針對相應 Partition 的 KV 操作。正是這一層的存在,使得存儲服務變成了真正的圖存儲。否則,Storage Service 只是一個 KV 存儲罷了。而 NebulaGraph 沒把 KV 作為一個服務單獨提出,最主要的原因便是圖查詢過程中會涉及到大量計算,這些計算往往需要使用圖的 Schema,而 KV 層沒有數(shù)據(jù) Schema 概念,這樣設計比較容易實現(xiàn)計算下推,是 NebulaGraph 查詢性能優(yōu)越的主要原因。
NebulaGraph 基于 C++ 實現(xiàn),架構(gòu)設計支持存儲千億頂點、萬億邊,并提供毫秒級別的查詢延時。我們在 3 臺 48U192G 物理機搭建的集群上灌入 10 億美食圖譜數(shù)據(jù)對 NebulaGraph 的功能進行了驗證。
一跳查詢 TP99 延時在 5ms 內(nèi),兩跳查詢 TP99 延時在 20ms 內(nèi),一般的多跳查詢 TP99 延時在百毫秒內(nèi)。 集群在線寫入速率約為20萬 Records/s。 支持通過 Spark 任務離線生成 RocksDB 底層 SST File,直接將數(shù)據(jù)文件載入到集群中,即類似 HBase BulkLoad 能力。 提供了類 SQL 查詢語言,對于新增的業(yè)務需求,只需構(gòu)造 NebulaGraph SQL 語句,易于理解且能滿足各類復雜查詢要求。 提供聯(lián)合索引、GEO 索引,可通過實體屬性或者關(guān)系屬性查詢實體、關(guān)系,或者查詢在某個經(jīng)緯度附近 N 米內(nèi)的實體。 一個 NebulaGraph 集群中可以創(chuàng)建多個 Space (概念類似 MySQL 的DataBase),并且不同 Space 中的數(shù)據(jù)在物理上是隔離的。
4 圖數(shù)據(jù)庫平臺建設

為了統(tǒng)一管理圖數(shù)據(jù),減少工程同學在圖數(shù)據(jù)庫集群上的運維壓力,我們基于開源分布式圖數(shù)據(jù)庫 NebulaGraph,搭建了一套一站式圖數(shù)據(jù)庫自助管理平臺(見圖 4),該平臺包含以下 4 層:
數(shù)據(jù)應用層。 業(yè)務方可以在業(yè)務服務中引入圖譜 SDK,實時地對圖數(shù)據(jù)進行增刪改查。 數(shù)據(jù)存儲層。 支持兩種圖數(shù)據(jù)庫集群的部署。 第一種部署方式是 CP 方案,即 Consistency & Partition tolerance。單集群部署,集群中機器數(shù)量大于等于副本的數(shù)量,副本數(shù)量大于等于 3 。只要集群中有大于副本數(shù)一半的機器存活,整個集群就可以對外正常提供服務。CP 方案保證了數(shù)據(jù)讀寫的強一致性,但這種部署方式下集群可用性不高。 第二種部署方式是 AP 方案,即 Availability & Partition tolerance。在一個應用中部署多個圖數(shù)據(jù)庫集群,每個集群數(shù)據(jù)副本數(shù)為 1 ,多集群之間進行互備。這種部署方式的好處在于整個應用對外的可用性高,但數(shù)據(jù)讀寫的一致性要差些。 數(shù)據(jù)生產(chǎn)層。 圖數(shù)據(jù)主要有兩種來源,第一種是業(yè)務方把數(shù)倉中數(shù)據(jù)通過 ETL Job 轉(zhuǎn)成點和邊的 Hive 表,然后離線導入到圖數(shù)據(jù)庫中;第二種是業(yè)務線上實時產(chǎn)生的數(shù)據(jù)、或者通過 Spark/Flink 等流式處理產(chǎn)生的近線數(shù)據(jù),調(diào)用在線批量寫接口實時灌到圖數(shù)據(jù)庫中。 支撐平臺。 提供了 Schema 管理、權(quán)限管理、數(shù)據(jù)質(zhì)檢、數(shù)據(jù)增刪改查、集群擴縮容、圖譜畫像、圖數(shù)據(jù)導出、監(jiān)控報警、圖可視化、集群包管理等功能。
與業(yè)界方案相比,團隊主導設計的圖數(shù)據(jù)庫平臺除了支持存儲千億頂點、萬億邊,具備毫秒級別查詢能力外,還提供了如下四項能力:應用可用性 SLA 達 99.99%;支持每小時百億量級數(shù)據(jù)導入;實時寫入數(shù)據(jù)時保證多集群數(shù)據(jù)最終一致性;易用的圖譜可視化能力。下面將介紹具體的設計思路。
4.1 高可用模塊設計

首先介紹單應用多集群高可用模塊的設計(AP 方案)。為什么有 AP 方案的設計呢?因為接入圖數(shù)據(jù)庫平臺的業(yè)務方比較在意的指標是集群可用性。在線服務對集群的可用性要求非常高,最基礎的要求是集群可用性能達到 4 個 9,即一年里集群的不可用時間要小于一個小時。對于在線服務來說,服務或者集群的可用性是整個業(yè)務的生命線,如果這點保證不了,即使集群提供的能力再多再豐富,那么業(yè)務方也不會考慮使用,可用性是業(yè)務選型的基礎。
另外,公司要求中間件要有跨區(qū)域容災能力,即要具備在多個地域部署多集群的能力。我們分析了平臺接入方的業(yè)務需求,大約 80% 的場景是 T+1 全量導入數(shù)據(jù)、線上只讀。在這種場景下,對圖數(shù)據(jù)的讀寫強一致性要求并不高,因此我們設計了單應用多集群這種部署方案。
AP 方案部署方式可以參考圖 5,一個業(yè)務方在圖數(shù)據(jù)庫平臺上創(chuàng)建了 1 個應用并部署了 4 個集群,其中北京 2 個、上海 2 個,平時這 4 個集群同時對外提供服務。假如現(xiàn)在北京集群 1 掛了,那么北京集群 2 可以提供服務。如果說真那么不巧,北京集群都掛了,或者北京側(cè)對外的網(wǎng)絡不可用,那么上海的集群也可以提供服務。在這種部署方式下,平臺會盡可能地通過一些方式來保證整個應用的可用性。然后每個集群內(nèi)部盡量部署同機房的機器,因為圖數(shù)據(jù)庫集群內(nèi)部 RPC 非常多,如果有跨機房或者跨區(qū)域的頻繁調(diào)用,整個集群對外的性能會比較低。

高可用模塊主要包含下面 4 個部分,如上圖 6 所示:
第一部分是右側(cè)的圖數(shù)據(jù)庫 Agent,它是部署在圖數(shù)據(jù)庫集群的一個進程,用來收集機器和圖數(shù)據(jù)庫三個核心模塊的信息,并上報到圖數(shù)據(jù)庫平臺。Agent 能夠接收圖數(shù)據(jù)庫平臺的命令并對圖數(shù)據(jù)庫進行操作。
第二部分是圖數(shù)據(jù)庫平臺,它主要是對集群進行管理,并同步圖數(shù)據(jù)庫集群的狀態(tài)到配置中心。
第三部分是圖數(shù)據(jù)庫 SDK,主要負責管理連接到圖數(shù)據(jù)庫集群的連接。如果業(yè)務方發(fā)送了某個查詢請求,SDK 會進行集群的路由和負載均衡,選擇出一條高質(zhì)量的連接來發(fā)送請求。此外,SDK 還會處理圖數(shù)據(jù)庫集群中問題機器的自動降級以及恢復,并且支持平滑切換集群的數(shù)據(jù)版本。
第四部分是配置中心,類似 ZooKeeper,存儲集群的當前狀態(tài)。
4.2 每小時百億量級數(shù)據(jù)導入模塊設計

第二個模塊是每小時百億量級數(shù)據(jù)導入模塊,平臺在 2019 年底- 2020 年初全量導入數(shù)據(jù)的方式是調(diào)用 NebulaGraph 對外提供的批量數(shù)據(jù)導入接口,這種方式的數(shù)據(jù)寫入速率大概是每小時 10 億級別,導入百億數(shù)據(jù)大概要耗費 10 個小時,耗時較長。此外,在以幾十萬每秒的速度導數(shù)據(jù)的過程中,會長期占用機器的 CPU、IO 資源,一方面會對機器造成損耗,另一方面數(shù)據(jù)導入過程中集群對外提供的讀性能會變?nèi)酢?/span>
為了解決上面兩個問題,平臺進行了如下優(yōu)化:在 Spark 集群中直接生成圖數(shù)據(jù)庫底層文件 SST File,再借助 RocksDB 的 Bulkload 功能直接 ingest 文件到圖數(shù)據(jù)庫。
數(shù)據(jù)導入的核心流程可以參考圖 7,當用戶執(zhí)行導數(shù)據(jù)操作后,圖數(shù)據(jù)庫平臺會向公司的 Spark 集群提交一個 Spark 任務,在 Spark 任務中會生成圖數(shù)據(jù)庫里相關(guān)的點、邊以及點索引、邊索引相關(guān)的 SST 文件,并上傳到美團的 S3 云存儲上。文件生成后,圖數(shù)據(jù)庫平臺會通知應用中多個集群去下載這些存儲文件,之后完成 ingest 跟 compact 操作,最后完成數(shù)據(jù)版本的切換。
為兼顧各個業(yè)務方的不同需求,平臺統(tǒng)一了應用導入、集群導入、離線導入、在線導入,以及全量導入、增量導入這些場景,然后細分成下面九個階段,從流程上保證在導數(shù)據(jù)過程中應用整體的可用性:SST File 生成 、SST File 下載 、ingest、compact、數(shù)據(jù)校驗、增量回溯、數(shù)據(jù)版本切換、集群重啟、數(shù)據(jù)預熱。
4.3 實時寫入多集群數(shù)據(jù)同步模塊設計

第三個模塊是實時寫入多集群數(shù)據(jù)同步模塊,平臺約有 15% 的需求場景是在實時讀取數(shù)據(jù)時,還要把新產(chǎn)生的業(yè)務數(shù)據(jù)實時寫入集群,并且對數(shù)據(jù)的讀寫強一致性要求不高。就是說,業(yè)務方寫到圖數(shù)據(jù)庫里的數(shù)據(jù),不需要立馬能讀到。針對上述場景,業(yè)務方在使用單應用多集群這種部署方案時,多集群里的數(shù)據(jù)需要保證最終一致性。針對這一需求,我們做了以下設計。
第一部分是引入 Kafka 組件,業(yè)務方在服務中通過 SDK 對圖數(shù)據(jù)庫進行寫操作時,SDK 并不直接寫圖數(shù)據(jù)庫,而是把寫操作寫到 Kafka 隊列里,之后由該應用下的多個集群異步消費這個 Kafka 隊列。
第二部分是集群在應用級別可配置消費并發(fā)度,來控制數(shù)據(jù)寫入集群的速度。具體流程如下:
SDK 對用戶寫操作語句做語法解析,將其中點邊的批量操作拆解成單個點邊操作,即對寫語句做一次改寫。 Agent 消費 Kafka 時確保每個點及其出邊相關(guān)操作在單個線程里順序執(zhí)行(見圖 8),保證這點就能保證各個集群執(zhí)行完寫操作后最終的結(jié)果是一致的。 并發(fā)擴展:通過改變 Kafka 分片數(shù)、Agent 中消費 Kafka 線程數(shù)來調(diào)整 Kafka 中操作的消費速度。如果未來圖數(shù)據(jù)庫支持事務的話,上面的配置需要調(diào)整成單分片單線程消費,有必要對設計方案再做優(yōu)化調(diào)整。

第三部分是在實時寫入數(shù)據(jù)過程中,平臺可以同步生成一個全量數(shù)據(jù)版本,并做平滑切換(見圖 9),確保數(shù)據(jù)的不重、不漏、不延遲。
4.4 圖可視化模塊設計

第四個模塊是圖可視化模塊(見圖10),主要是用于解決子圖探索問題。當用戶在圖數(shù)據(jù)庫平臺通過可視化組件查看圖數(shù)據(jù)時,能盡量通過恰當?shù)慕换ピO計來避免因為節(jié)點過多而引發(fā)爆屏。主要包括以下幾個功能:
通過 ID 或者索引查找頂點。 能查看頂點和邊的卡片(卡片中展示點邊屬性和屬性值),可以單選、多選、框選以及按類型選擇頂點。 圖探索,當用戶點擊某個頂點時,系統(tǒng)會展示它的一跳鄰居信息,包括該頂點有哪些出邊?通過這個邊它能關(guān)聯(lián)到幾個點?該頂點的入邊又是什么情況?通過這種一跳信息的展示,用戶在平臺上探索子圖的時候,可快速了解到周邊的鄰居信息,更快地進行子圖探索。在探索過程中,平臺也支持通過屬性對邊進行過濾。 圖編輯能力,讓平臺用戶在不熟悉 NebulaGraph 語法的情況下也能增刪改點邊數(shù)據(jù),對線上數(shù)據(jù)進行臨時干預。
5 業(yè)務實踐
5.1 智能助理

該項目數(shù)據(jù)是基于美團商戶數(shù)據(jù)、用戶評論構(gòu)建的餐飲娛樂知識圖譜,覆蓋美食、酒店、旅游等領域,包含 13 類實體和 22 類關(guān)系。目前,點邊數(shù)量大概在百億級別,數(shù)據(jù) T+1 全量更新,主要用于解決搜索或者智能助理里 KBQA(全稱:Knowledge Based Question Answer)類問題。核心處理流程是通過 NLP 算法識別關(guān)系和實體后構(gòu)造出 NebulaGraph SQL 語句,再到圖數(shù)據(jù)庫獲取數(shù)據(jù)。
典型的應用場景包括商場找店,比如,某個用戶想知道望京新薈城這個商場有沒有海底撈,系統(tǒng)可以快速查出結(jié)果告訴用戶;另一個場景是標簽找店,用戶想知道望京 SOHO 附近有沒有適合情侶約會的餐廳,或者可以多加幾個場景標簽,系統(tǒng)都可以幫忙查找出來。
5.2 搜索召回

該項目數(shù)據(jù)是基于醫(yī)美商家信息構(gòu)建的醫(yī)美知識圖譜,包含 9 類實體和 13 類關(guān)系,點邊數(shù)量在百萬級別,同樣也是 T+1 全量更新,主要用于大搜底層實時召回,返回與 Query 相關(guān)的商戶、產(chǎn)品或醫(yī)生信息,解決醫(yī)美類搜索詞少結(jié)果、無結(jié)果問題。比如,某個用戶搜“啤酒肚”這種癥狀、或者“潤百顏”這類品牌,系統(tǒng)可以召回相關(guān)的醫(yī)美門店。
5.3 圖譜推薦理由

該項目數(shù)據(jù)來自用戶的畫像信息、商戶的特征信息、用戶半年內(nèi)收藏/購買行為,數(shù)據(jù)量級是 10 億級別,T+1 全量更新?,F(xiàn)在美團 App 和點評 App 上默認的商戶推薦列表是由深度學習模型生成的,但模型并不會給出生成這個列表的理由,缺少可解釋性。
而在圖譜里用戶跟商戶之間天然存在多條連通路徑,項目考慮選出一條合適路徑來生成推薦理由,在 App 界面上展示給用戶推薦某家店的原因。該項目基于用戶的協(xié)同過濾算法來生成推薦理由,在家鄉(xiāng)、消費水平、偏好類目、偏好菜系等多個組合維度中找出多條路徑,然后給這些路徑打分,選出一條分值較高的路徑,之后按照特定 Pattern 產(chǎn)出推薦理由。通過上述方式,就可以獲得“在北京喜歡北京菜的山東老鄉(xiāng)都說這家店很贊”,或者“廣州老鄉(xiāng)都中意他家的正宗北京炸醬面”這類理由。
5.4 代碼依賴分析

該項目把代碼庫中代碼依賴關(guān)系寫入到圖數(shù)據(jù)庫。代碼庫中存在很多服務代碼,這些服務會包括對外提供的接口,這些接口的實現(xiàn)依賴于該服務中某些類的成員函數(shù),這些類的成員函數(shù)又依賴了本類的成員變量、成員函數(shù)或者其它類的成員函數(shù),那么它們之間的依賴關(guān)系就形成了一張圖,可以把這個圖寫到圖數(shù)據(jù)庫里做代碼依賴分析。
典型應用場景是精準測試:當開發(fā)同學完成需求并向公司的代碼倉庫提交了 PR 后,可以把更改實時地寫到圖數(shù)據(jù)庫中。這樣的話,開發(fā)同學就能查到他所寫的代碼影響了哪些外部接口,并且借助圖可視化組件查看調(diào)用路徑。如果開發(fā)同學本來是要改接口 A 的行為,改了很多代碼,但是他可能并不知道他改的代碼也會影響到對外接口 B、C、D,這時候就可以用代碼依賴分析來做個 Check,增加測試的完備性。
6 總結(jié)與展望
目前,圖數(shù)據(jù)庫平臺基本具備了對圖數(shù)據(jù)的一站式自助管理功能。如果某個業(yè)務方要使用這種圖數(shù)據(jù)庫能力,那么業(yè)務方可以在平臺上自助地創(chuàng)建圖數(shù)據(jù)庫集群、創(chuàng)建圖的 Schema、導入圖數(shù)據(jù)、配置導入數(shù)據(jù)的執(zhí)行計劃、引入平臺提供的 SDK 對數(shù)據(jù)進行操作等等。平臺側(cè)主要負責各業(yè)務方圖數(shù)據(jù)庫集群的穩(wěn)定性。目前,美團有三四十個業(yè)務已經(jīng)在該平臺上落地,基本滿足了各個業(yè)務方的需求。
未來規(guī)劃主要有兩個方向,第一,根據(jù)業(yè)務場景優(yōu)化圖數(shù)據(jù)庫內(nèi)核,提升平臺穩(wěn)定性,開發(fā)的通用 Feature 持續(xù)反哺 NebulaGraph 社區(qū)。第二,挖掘更多的圖數(shù)據(jù)價值?,F(xiàn)在平臺僅支持圖數(shù)據(jù)存儲及多跳查詢這種基本能力,后續(xù)將基于 NebulaGraph 去探索圖學習、圖計算的能力,為平臺用戶提供更多挖掘圖數(shù)據(jù)價值的功能。
7 作者信息
登昌、梁帥、高辰、楊鑫、尊遠、王超等,均為美團搜索與NLP部工程師。
