如何運維多叢集資料庫?58 同城 NebulaGraph Database 運維實踐

NebulaGraph發表於2023-02-16

58 同城基於 NebulaGraph 一鍵部署運維架構的實踐

圖計算業務背景介紹

我們為什麼選擇 NebulaGraph?

在公司各個業務線中,有不少部門都有著關係分析等圖探索場景,隨著業務發展,相關的需求越來越多。大量需求使用多模資料庫來實現,開發成本和管理成本相對較高。

隨著圖資料庫的發展,相關係統應用越來越成熟,於是引入專業圖資料庫來滿足這部分業務需求的事務也提上日程。接下來要考慮的問題就是圖資料庫選型了。

首先,NebulaGraph 有大量網際網路大廠應用案例,說明 NebulaGraph 可以應對海量資料的圖探索場景。另外,目前 NebulaGraph 在 DB-Engines 在圖資料庫領域排名 14,而且增長勢頭強勁。排名靠前的圖資料庫,部分不開源或者單機版開源,場景受限。

圖計算業務背景介紹

NebulaGraph 實際測試表現如何

在匯入效能上,資料量小的時候 NebulaGraph 的匯入效率稍慢於 neo4j,但在大資料量的時候 NebulaGraph 的匯入明顯優於其他兩款圖資料庫。在 3 種查詢場景下,NebulaGraph 的效率都明顯高於 neo4j,與 HugeGraph 相比也有一定的優勢。

圖計算業務背景介紹

適用場景有哪些

公司有多種線上業務,工程複雜度和架構複雜度都較高,各個業務部門都需要專門的圖資料庫來實現對實體關係資料的處理和探索。

透過圖資料庫實現對任務依賴的執行時間進行監控,及時獲取延遲任務、銷售激勵平臺任務血緣關係處理、分析應用內部的類/方法級呼叫關係、業務風險資料分析、記錄企業高管、法人、股東關係,用於簽單業務等場景。

資源申請和叢集管理方式

為了更好的管理和維護,圖資料庫在運維部門集中運維管理。使用者按需在工單平臺中提交申請即可,工單中填寫詳細的資源需求資料和效能需求指標,由運維同學統一稽核交付叢集資源。

公司目前伺服器環境是自建機房,採用高配物理機,單機多例項混部資料庫服務。為了實現規模化管理和維護,需要提前制定好例項標準和規則。

叢集規模

得益於 NebulaGraph 良好的圖計算能力,我們已經持續交付叢集接近 20 套,目前還有業務部門在持續申請相關叢集服務資源。

NebulaGraph 規範和架構設計

由於需要滿足大量業務需求,未來會有大量的叢集需要交付和維護。為了高效管理和運維規模化的叢集,需要提前規劃和制定規範。

版本規範

目前使用版本為 2.0.1

路徑規範

  • 程式路徑為 /opt/soft/nebula201,該路徑下有 bin、scripts、share 等,作為公共的服務依賴路徑,從服務路徑中抽離出來

同樣,升級為 3.X 版本,只需要將程式路徑抽離出來作為公共的服務依賴路徑即可。

  • 服務路徑為 /work/nebulagraph+graph 埠,該路徑下有 data、etc、logs、pids

埠規範

  1. 叢集之間埠遞增 5,因為 storage 副本需要埠通訊,通常是 storage 埠 -1,例如兩套叢集 graph 埠分別是 60000 和 60005;
  2. 每種服務埠和 http、http2 埠之間步長為 10000,例如 graph 埠是 60000,ws_http_port 就是 50000,ws_h2_port 就是 40000;
  3. 三種服務埠之間相差 1000,例如 graph 埠是 60000,meta 埠就是 61000,storage 埠就是 62000;

    • 60000 graph 埠;50000 ws_http_port;40000 ws_h2_port
    • 61000 meta 埠;51000 ws_http_port;41000 ws_h2_port
    • 62000 storage 埠;52000 ws_http_port;42000 ws_h2_port

運維規範

第一,建立 space 需用 ngdb_ 左字首,分片預設是節點數的 2 倍,副本數預設為 2,參考 CREATE SPACE ngdb_demo (partition_num=6,replica_factor=2,charset=utf8,collate=utf8_bin,vid_type=FIXED_STRING(128),atomic_edge=false) ON default;
第二,授予業務賬號 DBA 角色:GRANT ROLE DBA ON ngdb_demo TO demo_wr;
第三,搭建一套 NebulaGraph 叢集后,將內建賬號 root 的密碼重置,之後將 /work/nebulagraph+graph 埠 路徑打包生成 rpm,作為標準安裝包

NebulaGraph 規範和架構設計

服務請求直接透過 DNS 和閘道器服務到 Graph,方便計算和儲存服務直接互動,由於是透過 DNS 訪問,不對外暴露 Meta 節點資訊,可以更靈活的運維,較少服務繫結 Meta 節點 ip 帶來的運維代價。

這種架構限制了 Java 等驅動的訪問,需要用其他驅動替代。

第四,基礎叢集套餐是 3 個 Graph 節點、3 個 Meta 節點、3 個 Storage 節點,在保證高可用的同時也能保證足夠的處理能力。

基礎叢集分佈在 3 臺物理機上,儲存和計算不需要過多的網路互動。

NebulaGraph 規範和架構設計

叢集部署自動化實現

為了能夠一鍵部署服務,集中式管理服務,我們需要藉助遠端管理工具 Ansible,能幫我們做到快速部署。依據三種角色服務的埠規範,生成 Ansible 的配置檔案。

叢集部署自動化實現

  • 由於將版本資訊寫到了配置檔案中,在相容多版本場景下,只需要在 bootstrap.yml 檔案中增加相應判斷即可,主程式相容多版本成本非常有限。

部署例項時,根據 graph 角色分發檔案,也可以每個節點單獨分發檔案。

  • 依據三種角色,分別分發配置檔案到目的路徑下,並且按照檔案命名規則生成最終配置檔案。
more bootstrap.yml
- hosts: graph
  become: yes
  remote_user: root
  tasks:
    - name: init elasticsearch file on data
      command: cp -r /opt/soft/nebulagraph201 {{ nebula_home }}
- hosts: graph
  become: yes
  remote_user: root
  tasks:
    - name: init config graphfile on master {{ version }}
      template: src=/opt/soft/ngdeploy/conf/templates/201graph dest="{{ nebula_etc }}nggraphd.conf" owner=root group=root mode=0755
- hosts: meta
  become: yes
  remote_user: root
  tasks:
    - name: init config metafile on master {{ version }}
      template: src=/opt/soft/ngdeploy/conf/templates/201meta dest="{{ nebula_etc }}ngmetad.conf" owner=root group=root mode=0755
- hosts: storage
  become: yes
  remote_user: root
  tasks:
    - name: init config storagefile on master {{ version }}
      template: src=/opt/soft/ngdeploy/conf/templates/201storage dest="{{ nebula_etc }}ngstoraged.conf" owner=root group=root mode=0755

配置檔案的分發最為關鍵,有較多變數需要處理,這些變數需要提前在 Ansible 的配置檔案中定義,nebulagraphd 路徑規範和服務埠需要使用 graphport、meta_server_addrs 需要用到 for 迴圈語法實現。

more templates/201graph 
########## basics ##########
--daemonize=true
--pid_file=/work/nebulagraph{{ graphport }}/pids/nebula-graphd.pid
--enable_optimizer=true
########## logging ##########
--log_dir=/work/nebulagraph{{ graphport }}/logs
--minloglevel=0
--v=0
--logbufsecs=0
--redirect_stdout=true
--stdout_log_file=graphd-stdout.log
--stderr_log_file=graphd-stderr.log
--stderrthreshold=2

########## query ##########
--accept_partial_success=false

########## networking ##########
--meta_server_addrs={% for host in groups.graph%}{%if loop.last%}{{ hostvars[host].inventory_hostname }}:{{ hostvars[host].metaport }}{%else%}{{hostvars[host].inventory_hostname }}:{{hostvars[host].metaport}}
,{%endif%}{% endfor %}

--local_ip={{inventory_hostname}}
--listen_netdev=any
--port={{ graphport }}
--reuse_port=false
--listen_backlog=1024
--client_idle_timeout_secs=0
--session_idle_timeout_secs=0
--num_accept_threads=1
--num_netio_threads=0
--num_worker_threads=0
--ws_ip={{inventory_hostname}}
--ws_http_port={{ graph_h1_port }}
--ws_h2_port={{ graph_h2_port }}
--default_charset=utf8
--default_collate=utf8_bin

########## authorization ##########
--enable_authorize=true

########## Authentication ##########
--auth_type=password

同樣,nebulametad 服務配置檔案路徑規範和服務埠需要使用 metahport、meta_server_addrs 需要用到 for 迴圈語法實現。

more templates/201meta 
########## basics ##########
--daemonize=true
--pid_file=/work/nebulagraph{{graphport}}/pids/nebula-metad.pid
########## logging ##########
--log_dir=/work/nebulagraph{{graphport}}/logs
--minloglevel=0
--v=0
--logbufsecs=0
--redirect_stdout=true
--stdout_log_file=metad-stdout.log
--stderr_log_file=metad-stderr.log
--stderrthreshold=2

########## networking ##########
--meta_server_addrs={% for host in groups.graph%}{%if loop.last%}{{ hostvars[host].inventory_hostname }}:{{ hostvars[host].metaport }}{%else%}{{hostvars[host].inventory_hostname }}:{{hostvars[host].metaport}}
,{%endif%}{% endfor %}

--local_ip={{inventory_hostname}}
--port={{metaport}}
--ws_ip={{inventory_hostname}}
--ws_http_port={{meta_h1_port}}
--ws_h2_port={{meta_h2_port}}
########## storage ##########
--data_path=/work/nebulagraph{{graphport}}/data/meta

########## Misc #########
--default_parts_num=100
--default_replica_factor=1
--heartbeat_interval_secs=10
--timezone_name=CST-8

同樣,nebulastoraged 服務配置檔案路徑規範和服務埠需要使用 storageport、meta_server_addrs 需要用到 for 迴圈語法實現。

more templates/201graph 
########## basics ##########
--daemonize=true
--pid_file=/work/nebulagraph{{ graphport }}/pids/nebula-graphd.pid
--enable_optimizer=true
########## logging ##########
--log_dir=/work/nebulagraph{{ graphport }}/logs
--minloglevel=0
--v=0
--logbufsecs=0
--redirect_stdout=true
--stdout_log_file=graphd-stdout.log
--stderr_log_file=graphd-stderr.log
--stderrthreshold=2

########## query ##########
--accept_partial_success=false

########## networking ##########
--meta_server_addrs={% for host in groups.graph%}{%if loop.last%}{{ hostvars[host].inventory_hostname }}:{{ hostvars[host].metaport }}{%else%}{{hostvars[host].inventory_hostname }}:{{hostvars[host].metaport}}
,{%endif%}{% endfor %}

--local_ip={{inventory_hostname}}
--listen_netdev=any
--port={{ graphport }}
--reuse_port=false
--listen_backlog=1024
--client_idle_timeout_secs=0
--session_idle_timeout_secs=0
--num_accept_threads=1
--num_netio_threads=0
--num_worker_threads=0
--ws_ip={{inventory_hostname}}
--ws_http_port={{ graph_h1_port }}
--ws_h2_port={{ graph_h2_port }}
--default_charset=utf8
--default_collate=utf8_bin

########## authorization ##########
--enable_authorize=true

########## Authentication ##########
--auth_type=password

需要部署新叢集時,需要按照規則和目的伺服器資訊生成 Ansible 的配置檔案,然後呼叫 ansible-playbook,按照 bootstrap.yml 定義的行為執行即可。

叢集部署自動化實現

部署完畢之後,需要按照服務角色依次啟動 start.yml 的指令碼檔案提前定義好三種服務的啟動命令和配置檔案。

叢集部署自動化實現

呼叫 ansible-playbook,根據 start.yml 的指令碼檔案依次執行三種服務的啟動命令即可。

叢集部署自動化實現

視覺化圖探索平臺

有賴於將目標 host 前置於 Web 平臺的設定,我們只需要對多個專案的開發提供一套公共的 Web 平臺即可,減少了 NebulaGraph 叢集的元件數量,有別於 ELK 的標準架構。

視覺化圖探索平臺

開發可以透過 NebulaGraph Studio 實現視覺化管理資料,輕鬆實現資料匯入和匯出,便於使用者探索資料關係。直接呈現出點邊關係,使探索圖資料之間的關係更為直觀。

視覺化圖探索平臺

以上是我們在規模化管理維護 NebulaGraph 叢集過程中的一些經驗,希望對大家有些幫助。


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

NebulaGraph 的開源地址:https://github.com/vesoft-inc/nebula 如果你覺得使用體驗還不錯的話,給我們的 GitHub 點個 ❤️ 鼓勵下開源路上的我們呢~

相關文章