在 Spark 資料匯入中的一些實踐細節

2022-06-05 06:06:07 字數 3199 閱讀 8879

本文由合合資訊大資料團隊柳佳浩撰寫
圖譜業務隨著時間的推移愈發的複雜化,逐漸體現出了效能上的瓶頸:單機不足以支援更大的圖譜。然而,從效能上來看,neo4j 的原生圖儲存有著不可替代的效能優勢,這一點是之前調研的 janusgraph、dgraph 等都難以逾越的鴻溝。即使 janusgraph 在 olap 上面非常出色,對 oltp 也有一定的支援,但是 graphframe 等也足以支撐其 olap 需求,更何況在 spark 3.0 會提供 cypher 支援的情況下,圖譜的 olap 需求相比 oltp 有更多途徑可以解決。這個時候,nebula graph 的「橫空出世」無疑是對分布式 oltp 效率低下現狀的一種突破。

之前在各類調研、部署後,特別是從 janusgraph 的 oltp 效率最終測試發現無法滿足線上需求之後,我們不再對同一圖譜可以同時進行 olap 和 oltp 進行強制性要求,而 nebula graph 的架構剛好符合圖譜方面的需要:

分布式——shared-nothing 分布式架構

高速 oltp(效能需要和 neo4j 相近)——nebula graph 的儲存層架構查詢直接對映實體地址,實際上可以算是原生圖儲存

服務的高可用(即在非人為情況下,圖譜可以穩定提供服務)——區域性失敗服務可用、有快照機制

保證可擴充套件性——支援線性擴容,由於開源、支援二次開發

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。

打包 sst.generator(spark 生成 sst 所需要的包)。

配置 nebula graph 集群,nebula graph 集群正常啟動,建立圖譜。

spark 配置檔案config.conf(可以參考文件《spark 匯入工具》)進行配置。

排查 spark 集群是否存在衝突的包。

spark 啟動時使用配置檔案和sst.generator快樂地匯入。

資料校驗。

批量匯入前推薦先建立索引

這裡推薦先建立索引的原因是:批量匯入僅在非線上圖譜進行,雖然建立索引可以選擇是否在提供服務的同時進行,但是為了防止後續rebuild出現問題,這邊可以優先建好索引。帶來的問題就是在批量匯入結點時相對較慢。

推薦用 int 型節點 id(可以使用snowflake演算法等),如果節點的 id 不是 int 型,這裡可以通過在節點/邊中加入policy: "uuid"來設定自動生成 uuid。

如果使用的是單獨的 spark 集群可能不會出現 spark 集群有衝突包的問題,該問題主要是 sst.generator 中存在可能和 spark 環境內的其他包產生衝突,解決方法是 shade 掉這些衝突的包,或者改名。

spark 調優方面:可以根據實際情況調整引數,盡量降低 memory 以節約資源,相對的可以適當提高並行度加速。

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

因為在較早的版本使用了 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 傳送門:

因為之前調研過 janusgraph,nebula graph 給我的第一印象就是:暗坑相對較少、社群反饋非常及時。在測試後 nebula graph 又用她的效率證明了自己,成為了分布式圖譜的首選項。

nebula graph 社群、群組、pr 官方反饋非常及時,這是圖譜迅速、茁壯成長的不可替代的重要因素,也希望可以後續可以繼續見證 nebula graph 的成長,繼續為 nebula graph 生態的完善添磚加瓦!

喜歡這篇文章?來來來,給我們的 github 點個 star 表鼓勵啦~~

Spark中的一些概念

一次action操作會觸發rdd的延遲計算,我們把這樣的一次計算稱作乙個job。窄依賴指的是 每個parent rdd 的 partition 最多被 child rdd的乙個partition使用 寬依賴指的是 每個parent rdd 的 partition 被多個 child rdd的part...

匯入 模板中的一些規則

1.模板定義內的自定義型別成員呼叫方法 用typename顯示說明 類可以定義型別成員,如size type,size t等型別。在定義模板類時如何呼叫它呢?為了說明是型別,顯示用typename說明。template cl func cl cl p,t value 2.非型別模板形參的使用 模板非...

記錄一些spark快取中的方法

此為使用者自己選擇釋放需要的已經快取的rdd。def unpersistunuse rddstring set string sc sparkcontext 針對多個sp序列跑,其中採用多個sp之間進行重新new sparkcontext和sc.stop進行,否則中間許多快取問題無法解決,始終會有記...