Nebula Importer 資料匯入實踐

NebulaGraph 發表於 2022-07-04
本文首發於 Nebula Graph Community 公眾號

前言

Nebula 目前作為較為成熟的產品,已經有著很豐富的生態。資料匯入的維度而言就已經提供了多種選擇。有大而全的Nebula Exchange,小而精簡的Nebula Importer, 還有為 Spark / Flink 引擎提供的Nebula Spark ConnectorNebula Flink Connector

在眾多的匯入方式中,究竟哪種較為方便呢?

使用場景介紹:

  • Nebula Exchange

    • 需要將來自 Kafka、Pulsar 平臺的流式資料, 匯入 Nebula Graph 資料庫
    • 需要從關係型資料庫(如 MySQL)或者分散式檔案系統(如 HDFS)中讀取批式資料
    • 需要將大批量資料生成 Nebula Graph 能識別的 SST 檔案
  • Nebula Importer

    • Importer 適用於將本地 CSV 檔案的內容匯入至 Nebula Graph 中
  • Nebula Spark Connector:

    • 在不同的 Nebula Graph 叢集之間遷移資料
    • 在同一個 Nebula Graph 叢集內不同圖空間之間遷移資料
    • Nebula Graph 與其他資料來源之間遷移資料
    • 結合 Nebula Algorithm 進行圖計算
  • Nebula Flink Connector

    • 在不同的 Nebula Graph 叢集之間遷移資料
    • 在同一個 Nebula Graph 叢集內不同圖空間之間遷移資料
    • Nebula Graph 與其他資料來源之間遷移資料

以上摘自 Nebula 官方文件:https://docs.nebula-graph.com.cn/2.6.2/1.introduction/1.what-is-nebula-graph/

總體來說,Exchange 大而全,可以和大部分的儲存引擎結合,匯入到 Nebula 中,但是需要部署Spark 環境。

Nebula Importer 資料匯入實踐

Importer 使用簡單,所需依賴較少,但需要自己提前生成資料檔案,配置好 schema 一勞永逸,但是不支援斷點續傳,適合資料量中等。

Spark / Flink Connector 需要和流資料結合。

不同的場景選擇不同的工具,如果作為新人使用 Nebula 在匯入資料時,建議使用 Nebula Importer 工具,簡單快速上手

Nebula Importer 的使用

在我們接觸 Nebula Graph 初期,當時生態不夠完善, 加上只有部分業務遷移到 Nebula Graph 上,我們對 Nebula Graph 資料的匯入不管全量還是增量都是採用 Hive 表推到 Kafka,消費 Kafka 批量寫入 Nebula Graph 的方式。後來隨著越來越多的資料和業務切換到 Nebula Graph,匯入的資料效率問題愈發嚴峻,匯入時長的增加,使得業務高峰期時仍然在全量的資料匯入,這是不可接受的。

針對以上問題,在嘗試 Nebula Spark Connector 和 Nebula Importer 之後,由便於維護和遷移多方面考慮,採用 Hive table -> CSV -> Nebula Server -> Nebula Importer 的方式進行全量的匯入,整體耗時時長也有較大的提升。

Nebula Importor 的相關配置

系統環境

[[email protected] importer]# lscpu
Architecture:          x86_64
CPU op-mode(s):        32-bit, 64-bit
Byte Order:            Little Endian
CPU(s):                16
On-line CPU(s) list:   0-15
Thread(s) per core:    2
Core(s) per socket:    8
Socket(s):             1
NUMA node(s):          1
Vendor ID:             GenuineIntel
CPU family:            6
Model:                 85
Model name:            Intel(R) Xeon(R) Platinum 8269CY CPU @ 2.50GHz
Stepping:              7
CPU MHz:               2499.998
BogoMIPS:              4999.99
Hypervisor vendor:     KVM
Virtualization type:   full
L1d cache:             32K
L1i cache:             32K
L2 cache:              1024K
L3 cache:              36608K
NUMA node0 CPU(s):     0-15

Disk:SSD
Memory: 128G

叢集環境

  • Nebula Version:v2.6.1
  • 部署方式:RPM
  • 叢集規模:三副本,六節點

資料規模

+---------+--------------------------+-----------+
| "Space" | "vertices"               | 559191827 |
+---------+--------------------------+-----------+
| "Space" | "edges"                  | 722490436 |
+---------+--------------------------+-----------+

Importer 配置

# Graph版本,連線2.x時設定為v2。
version: v2

description: Relation Space import data

# 是否刪除臨時生成的日誌和錯誤資料檔案。
removeTempFiles: false

clientSettings:

  # nGQL語句執行失敗的重試次數。
  retry: 3

  # Nebula Graph客戶端併發數。
  concurrency: 5

  # 每個Nebula Graph客戶端的快取佇列大小。
  channelBufferSize: 1024

  # 指定資料要匯入的Nebula Graph圖空間。
  space: Relation

  # 連線資訊。
  connection:
    user: root
    password: ******
    address: 10.0.XXX.XXX:9669,10.0.XXX.XXX:9669

  postStart:
    # 配置連線Nebula Graph伺服器之後,在插入資料之前執行的一些操作。
    commands: |

    # 執行上述命令後到執行插入資料命令之間的間隔。
    afterPeriod: 1s

  preStop:
    # 配置斷開Nebula Graph伺服器連線之前執行的一些操作。
    commands: |

# 錯誤等日誌資訊輸出的檔案路徑。    
logPath: /mnt/csv_file/prod_relation/err/test.log
....

由於篇幅 只展示些全域性相關的配置,點邊相關的配置較多,不再展開,詳情可以參考GitHub

設定 Crontab,Hive 生成表之後傳輸到 Nebula Server,在夜間流量較低的時候跑起 Nebula Importer 任務:

50 03 15 * * /mnt/csv_file/importer/nebula-importer -config /mnt/csv_file/importer/rel.yaml >> /root/rel.log

總共耗時 2h,在六點左右完成全量資料的匯入。

部分 log 如下,匯入速度最高維持在 200,000/s 左右:

2022/05/15 03:50:11 [INFO] statsmgr.go:62: Tick: Time(10.00s), Finished(1952500), Failed(0), Read Failed(0), Latency AVG(4232us), Batches Req AVG(4582us), Rows AVG(195248.59/s)
2022/05/15 03:50:16 [INFO] statsmgr.go:62: Tick: Time(15.00s), Finished(2925600), Failed(0), Read Failed(0), Latency AVG(4421us), Batches Req AVG(4761us), Rows AVG(195039.12/s)
2022/05/15 03:50:21 [INFO] statsmgr.go:62: Tick: Time(20.00s), Finished(3927400), Failed(0), Read Failed(0), Latency AVG(4486us), Batches Req AVG(4818us), Rows AVG(196367.10/s)
2022/05/15 03:50:26 [INFO] statsmgr.go:62: Tick: Time(25.00s), Finished(5140500), Failed(0), Read Failed(0), Latency AVG(4327us), Batches Req AVG(4653us), Rows AVG(205619.44/s)
2022/05/15 03:50:31 [INFO] statsmgr.go:62: Tick: Time(30.00s), Finished(6080800), Failed(0), Read Failed(0), Latency AVG(4431us), Batches Req AVG(4755us), Rows AVG(202693.39/s)
2022/05/15 03:50:36 [INFO] statsmgr.go:62: Tick: Time(35.00s), Finished(7087200), Failed(0), Read Failed(0), Latency AVG(4461us), Batches Req AVG(4784us), Rows AVG(202489.00/s)

然後在七點,根據時間戳,重新消費 Kafka 匯入當天凌晨到七點的增量資料, 防止 T+1 的全量資料覆蓋當天的增量資料。

50 07 15 * * python3  /mnt/code/consumer_by_time/relation_consumer_by_timestamp.py

增量的消費大概耗時 10-15min。

實時性

根據 MD5 對比之後得到的增量資料,匯入Kafka中,實時消費 Kafka 的資料,確保資料的延遲不超過 1 分鐘。

另外長時間的實時可能會有非預期的資料問題出現而未發現,所以每 30 天會匯入一次全量資料,上面介紹的 Importer 匯入。然後給 Space 的點邊新增 TTL=35 天確保未及時更新的資料會被 Filter 和後續回收。

一些注意點

論壇帖子 https://discuss.nebula-graph.com.cn/t/topic/361 這裡提到了關於 CSV 匯入常遇到的問題,大家可以參考下。另外根據經驗這邊有幾點建議:

  1. 關於併發度,問題中有提到,這個 concurrency 指定為你的 cpu cores 就可以, 表示起多少個 client 連線 Nebula Server。 實際操作中,要去 trade off 匯入速度和伺服器壓力的影響。在我們這邊測試,如果併發過高,會導致磁碟 IO 過高,引發設定的一些告警,不建議一下把併發拉太高,可以根據實際業務測試下做權衡。
  2. Importer 並不能斷點續傳,如果出現錯誤,需要手動處理。在實際操作中,我們會程式分析 Importer 的 log,根據情況處理,如果哪部分資料出現了非預期的錯誤,會告警通知,人工介入,防止出現意外。
  3. Hive 生成表之後傳輸到 Nebula Server, 這部分任務 實際耗時是和 Hadoop 資源情況密切相關的,有可能會出現資源不夠導致 Hive 和 CSV 表生成時間滯緩,而 Importer 正常在跑的情況,這部分需要提前做好預判。我們這邊是根據hive任務結束時間和 Importer 任務開始時間做對比,判斷是否需要 Importer 的程式正常執行。

交流圖資料庫技術?加入 Nebula 交流群請先填寫下你的 Nebula 名片,Nebula 小助手會拉你進群~~

相關文章