58 同城一鍵部署運維架構的實踐 - 集羣搭配管理平台多場景降本增效

語言: CN / TW / HK

>>>圖計算業務背景介紹

 

我們為什麼選擇 NebulaGraph?

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

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

首先,NebulaGraph 有大量互聯網大廠應用案例,有效驗證了 NebulaGraph 可以應對海量數據的圖探索場景這個事實。另外,目前 NebulaGraph 在 DB-Engines 在圖數據庫領域排名 14,而且增長勢頭強勁。排名靠前的圖數據庫,部分不開源或者單機版開源,場景受限。

 

NebulaGraph 實際測試表現如何

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

 

適用場景有哪些

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

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

 

資源申請和集羣管理方式

為了更好的管理和維護,圖數據庫在運維部門集中運維管理。用户按需在工單平台中提交申請即可,工單中填寫詳細的資源需求數據和性能需求指標,由運維同學統一審核交付集羣資源。

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

 

集羣規模

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

 

>>>NebulaGraph 規範和架構設計

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

 

版本規範

目前使用版本為 2.0.1

 

路徑規範

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

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

2)服務路徑為 /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

 

運維規範

1)創建 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;

2)授予業務賬號 DBA 角色:GRANT ROLE DBA ON ngdb_demo TO demo_wr;

3)搭建一套 NebulaGraph 集羣后,將內置賬號 root 的密碼重置,之後將 /work/nebulagraph+graph 端口路徑打包生成 rpm,作為標準安裝包

服務請求直接通過 DNS 和網關服務到 Graph,方便計算和存儲服務直接交互,由於是通過 DNS 訪問,不對外暴露 Meta 節點信息,可以更靈活的運維,較少服務綁定 Meta 節點 ip 帶來的運維代價。

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

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

基礎集羣分佈在 3 台物理機上,存儲和計算不需要過多的網絡交互。

 

集羣部署自動化實現

為了能夠一鍵部署服務,集中式管理服務,我們需要藉助遠程管理工具 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 名片 ,Nebula 小助手會拉你進羣哦~~
 

官網:http://nebula-graph.com.cn

GitHub:http://github.com/vesoft-inc/nebula

免費開源,可以右上角點 Star(8K) 支持/收藏下~