本文由合合信息大數據團隊柳佳浩撰寫
1.前言
圖譜業務隨着時間的推移愈發的複雜化,逐漸體現出了性能上的瓶頸:單機不足以支持更大的圖譜。然而,從性能上來看,Neo4j 的原生圖存儲有着不可替代的性能優點,這一點是以前調研的 JanusGraph、Dgraph 等都難以逾越的鴻溝。即便 JanusGraph 在 OLAP 上面很是出色,對 OLTP 也有必定的支持,可是 GraphFrame 等也足以支撐其 OLAP 需求,更況且在 Spark 3.0 會提供 Cypher 支持的狀況下,圖譜的 OLAP 需求相比 OLTP 有更多途徑能夠解決。這個時候,Nebula Graph 的「橫空出世」無疑是對分佈式 OLTP 效率低下現狀的一種突破。java
以前在各種調研、部署後,特別是從 JanusGraph 的 OLTP 效率最終測試發現沒法知足線上需求以後,咱們再也不對同一圖譜能夠同時進行 OLAP 和 OLTP 進行強制性要求,而 Nebula Graph 的架構恰好符合圖譜方面的須要:python
- 分佈式——shared-nothing 分佈式架構
- 高速 OLTP(性能須要和 Neo4j 相近)——Nebula Graph 的存儲層架構查詢直接映射物理地址,實際上能夠算是原生圖存儲
- 服務的高可用(即在非人爲狀況下,圖譜能夠穩定提供服務)——局部失敗服務可用、有快照機制
- 保證可擴展性——支持線性擴容,因爲開源、支持二次開發
綜上所述,Nebula Graph 架構上符合實際生產需求,所以對 Nebula Graph 進行了調研、部署、測試。關於部署、性能測試(美團 NLP 團隊性能測試、騰訊雲安全團隊性能測試)的部分不管是官網仍是其餘同窗在博客中都有比較詳盡的數據,本文主要從 Spark 導入出發,算是對 Nebula Graph 對 Spark 的支持進行粗淺的理解。git
2.測試環境
- Nebula Graph 集羣
- 3 臺 32 c(實際限制了16 c)
- 400 G 內存(實際配置了 100 G)
- SSD
- 版本信息:Nebula Graph 版本 1.0.0(當時測試比較早)。
- 網絡環境:萬兆。
- 圖譜大小:十億級別節點(屬性較少),百億級別邊(有向,無屬性或帶權值)。
- Spark 集羣
- 版本信息:Spark 2.1.0
實際上 Nebula Graph 的使用資源合計 2T 左右 memory (3 * 30 executor + 1 driver) * 25G。github
3.Spark 批量導入
3.1 基礎流程
- 打包 sst.generator(Spark 生成 sst 所須要的包)。
- 配置 Nebula Graph 集羣,Nebula Graph 集羣正常啓動,建立圖譜。
- Spark 配置文件
config.conf
(能夠參考文檔《Spark 導入工具》)進行配置。 - 排查 Spark 集羣是否存在衝突的包。
- Spark 啓動時使用配置文件和
sst.generator
快樂地導入。 - 數據校驗。
3.2 一些細節
- 批量導入前推薦先創建索引。
這裏推薦先創建索引的緣由是:批量導入僅在非線上圖譜進行,雖然創建索引能夠選擇是否在提供服務的同時進行,可是爲了防止後續 REBUILD
出現問題,這邊能夠優先建好索引。帶來的問題就是在批量導入結點時相對較慢。算法
-
推薦用 int 型節點 ID(可使用 Snowflake算法 等),若是節點的 ID 不是 int 型,這裏能夠經過在節點/邊中加入
policy: "uuid"
來設置自動生成 uuid。json -
若是使用的是單獨的 Spark 集羣可能不會出現 Spark 集羣有衝突包的問題,該問題主要是 sst.generator 中存在可能和 Spark 環境內的其餘包產生衝突,解決方法是 shade 掉這些衝突的包,或者更名。安全
-
Spark 調優方面:能夠根據實際狀況調整參數,儘可能下降 memory 以節約資源,相對的能夠適當提升並行度加速。網絡
3.3 導入結果
十億級別節點(屬性較少),百億級別邊(有向,無屬性或帶權值),提早建好索引的狀況下大約消耗 20 小時左右導入全圖。架構
3.4 關於 PR
由於在較早的版本使用了 Spark 導入,天然也有一些不太完善的地方,這邊也提出了一些拙見,對 SparkClientGenerator.scala 略做了修改。分佈式
- 最先在使用 Spark Writer(現:Exchange) 寫入 Nebula Graph 時,發現錯列的問題。
經過看源碼發現 SparkClientGenerator.scala 存在 BUG,讀取的是配置文件的位置而非 parquet/json
文件的位置,修復後提了我第一個 PR#2187,有幸經過
- 後續發現使用 SparkClientGenerator 自動生成 uuid/hash 功能時,存在會出現重複的雙引號的問題,致使沒法導入。
這塊能夠說是因爲解決問題的想法不一樣,提交了好屢次。重複引號的問題歸根結底是對類型轉化的時候添加了一次雙引號,我這邊發現有個 extraIndexValue 的方法能夠把用戶自填的非 string 類型的轉成 string 類型,我這邊想着可能會有用戶想把非 string 型的 index 轉成 uuid/hash(好比 array),因此修改的比較多。
可是和官方 @darionyaphet 溝通後,發現我這種作法實際上是對數據源進行了修改,用戶傳 array 等不支持的類型時,應該報錯而不是轉換類型(這個確實,一開始只考慮到了邏輯上跑通以及本身這邊業務的使用,沒考慮通用性)。從新修改,提交 PR #2258,經過。通過此次 PR 我也學到了不少。
- 以後發現 nebula-python 也有和官方 thrift 衝突的問題,原本想 shade 後提 PR,可是以爲這個改動太大了,因此直接提給官方,近期也修復了。
Nebula Graph 旁白:歡迎社區小夥伴來 GitHub 給咱們提 PR,GitHub 傳送門:https://github.com/vesoft-inc/nebula/issues
4.總結 & 展望
由於以前調研過 JanusGraph,Nebula Graph 給個人第一印象就是:暗坑相對較少、社區反饋很是及時。在測試後 Nebula Graph 又用她的效率證實了本身,成爲了分佈式圖譜的首選項。
Nebula Graph 社區、羣組、PR 官方反饋很是及時,這是圖譜迅速、茁壯成長的不可替代的重要因素,也但願能夠後續能夠繼續見證 Nebula Graph 的成長,繼續爲 Nebula Graph 生態的完善添磚加瓦!
喜歡這篇文章?來來來,給咱們的 GitHub 點個 star 表鼓勵啦~~ 🙇♂️🙇♀️ [手動跪謝]
Nebula Graph Meetup 深圳場報名中:https://www.huodongxing.com/event/4572357498700,期待你來現場交流技術 😊