在 Spark 數據導入中的一些實踐細節

best-practices-import-data-spark-nebula-graph

本文由合合信息大數據團隊柳佳浩撰寫

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

  1. 分佈式——shared-nothing 分佈式架構
  2. 高速 OLTP(性能須要和 Neo4j 相近)——Nebula Graph 的存儲層架構查詢直接映射物理地址,實際上能夠算是原生圖存儲
  3. 服務的高可用(即在非人爲狀況下,圖譜能夠穩定提供服務)——局部失敗服務可用、有快照機制
  4. 保證可擴展性——支持線性擴容,因爲開源、支持二次開發

綜上所述,Nebula Graph 架構上符合實際生產需求,所以對 Nebula Graph 進行了調研、部署、測試。關於部署、性能測試(美團 NLP 團隊性能測試騰訊雲安全團隊性能測試)的部分不管是官網仍是其餘同窗在博客中都有比較詳盡的數據,本文主要從 Spark 導入出發,算是對 Nebula Graph 對 Spark 的支持進行粗淺的理解。git

2.測試環境

  1. Nebula Graph 集羣
    1. 3 臺 32 c(實際限制了16 c)
    2. 400 G 內存(實際配置了 100 G)
    3. SSD
    4. 版本信息:Nebula Graph 版本 1.0.0(當時測試比較早)。
  2. 網絡環境:萬兆。
  3. 圖譜大小:十億級別節點(屬性較少),百億級別邊(有向,無屬性或帶權值)。
  4. Spark 集羣
    1. 版本信息:Spark 2.1.0

實際上 Nebula Graph 的使用資源合計 2T 左右 memory (3 * 30 executor + 1 driver) * 25G。github

3.Spark 批量導入

3.1 基礎流程

  1. 打包 sst.generator(Spark 生成 sst 所須要的包)。
  2. 配置 Nebula Graph 集羣,Nebula Graph 集羣正常啓動,建立圖譜。
  3. Spark 配置文件 config.conf(能夠參考文檔《Spark 導入工具》)進行配置。
  4. 排查 Spark 集羣是否存在衝突的包。
  5. Spark 啓動時使用配置文件和 sst.generator 快樂地導入。
  6. 數據校驗。

3.2 一些細節

  1. 批量導入前推薦先創建索引

這裏推薦先創建索引的緣由是:批量導入僅在非線上圖譜進行,雖然創建索引能夠選擇是否在提供服務的同時進行,可是爲了防止後續 REBUILD 出現問題,這邊能夠優先建好索引。帶來的問題就是在批量導入結點時相對較慢。算法

  1. 推薦用 int 型節點 ID(可使用 Snowflake算法 等),若是節點的 ID 不是 int 型,這裏能夠經過在節點/邊中加入 policy: "uuid" 來設置自動生成 uuid。json

  2. 若是使用的是單獨的 Spark 集羣可能不會出現 Spark 集羣有衝突包的問題,該問題主要是 sst.generator 中存在可能和 Spark 環境內的其餘包產生衝突,解決方法是 shade 掉這些衝突的包,或者更名。安全

  3. Spark 調優方面:能夠根據實際狀況調整參數,儘可能下降 memory 以節約資源,相對的能夠適當提升並行度加速。網絡

3.3 導入結果

十億級別節點(屬性較少),百億級別邊(有向,無屬性或帶權值),提早建好索引的狀況下大約消耗 20 小時左右導入全圖。架構

3.4 關於 PR

由於在較早的版本使用了 Spark 導入,天然也有一些不太完善的地方,這邊也提出了一些拙見,對 SparkClientGenerator.scala 略做了修改。分佈式

  1. 最先在使用 Spark Writer(現:Exchange) 寫入 Nebula Graph 時,發現錯列的問題。

經過看源碼發現 SparkClientGenerator.scala 存在 BUG,讀取的是配置文件的位置而非 parquet/json 文件的位置,修復後提了我第一個 PR#2187,有幸經過

  1. 後續發現使用 SparkClientGenerator 自動生成 uuid/hash 功能時,存在會出現重複的雙引號的問題,致使沒法導入。

這塊能夠說是因爲解決問題的想法不一樣,提交了好屢次。重複引號的問題歸根結底是對類型轉化的時候添加了一次雙引號,我這邊發現有個 extraIndexValue 的方法能夠把用戶自填的非 string 類型的轉成 string 類型,我這邊想着可能會有用戶想把非 string 型的 index 轉成 uuid/hash(好比 array),因此修改的比較多。

可是和官方 @darionyaphet 溝通後,發現我這種作法實際上是對數據源進行了修改,用戶傳 array 等不支持的類型時,應該報錯而不是轉換類型(這個確實,一開始只考慮到了邏輯上跑通以及本身這邊業務的使用,沒考慮通用性)。從新修改,提交 PR #2258,經過。通過此次 PR 我也學到了不少。

  1. 以後發現 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,期待你來現場交流技術 😊

best-practices-import-data-spark-nebula-graph

相關文章
相關標籤/搜索