1. 程式人生 > 資料庫 >圖資料庫設計實踐 | 儲存服務的負載均衡和資料遷移

圖資料庫設計實踐 | 儲存服務的負載均衡和資料遷移

image

在文章《Nebula 架構剖析系列(一)圖資料庫的儲存設計》中,我們提過分散式圖儲存的管理由 Meta Service 來統一排程,它記錄了所有 partition 的分佈情況,以及當前機器的狀態。當 DBA 增減機器時,只需要通過 console 輸入相應的指令,Meta Service 便能夠生成整個 Balance 計劃並執行。而之所以沒有采用完全自動 Balance 的方式,主要是為了減少資料搬遷對於線上服務的影響,Balance 的時機由使用者自己控制。

在本文中我們將著重講解在儲存層如何實現資料和服務的負載平衡。

簡單回顧一下,Nebula Graph 的服務可分為 graph,storage,meta。本文主要描述對於儲存層(storage)的資料和服務的 balance。這些都是通過 Balance 命令來實現的:Balance 命令有兩種,一種需要遷移資料,命令為 BALANCE DATA

;另一種不需要遷移資料,只改變 partition 的 raft-leader 分佈(負載均衡),命令為 BALANCE LEADER

本文目錄

  • Balance 機制淺析
  • 叢集資料遷移
    • Step 1:準備工作
      • Step 1.1 檢視現有叢集狀態
      • Step 1.2 建立圖空間
    • Step 2 加入新例項
    • Step 3 遷移資料
    • Step 4 假如要中途停止 balance data
    • Step 5 檢視資料遷移結果
    • Step 6 Balance leader
  • 批量縮容
  • 示例資料遷移

Balance 機制淺析

在圖資料庫 Nebula Graph 中, Balance 主要用來 balance leader 和 partition,只涉及 leader 和 partition 在機器之間轉移,不會增加或者減少 leader 和 partition 的數量

上線新機器並啟動相應的 Nebula 服務後,storage 會自動向 meta 註冊。Meta 會計算出一個新的 partition 分佈,然後通過 remove partitionadd partition 逐步將資料從老機器搬遷到新的機器上。這個過程所對應的命令是 BALANCE DATA ,通常資料搬遷是個比較漫長的過程。

但 BALANCE DATA 僅改變了資料和副本在機器之間的均衡分佈,leader(和對應的負載) 是不會改變的,因此還需要通過命令BALANCE LEADER來實現負載的均衡。這個過程也是通過 meta 實現的。

叢集資料遷移

以下舉例說明 BALANCE DATA

的使用方式。本例將從 3 個例項(程序)擴充套件到 8 個例項(程序):

Step 1:準備工作

部署一個 3 副本的叢集,1個 graphd,1個 metad,3 個 storaged(具體部署方式請參考叢集部署文:https://zhuanlan.zhihu.com/p/80335605),通過 SHOW HOSTS 命令可以看到叢集的狀態資訊:

Step 1.1 檢視現有叢集狀態

按照叢集部署文件部署好 3 副本叢集之後,用 SHOW HOSTS 命令檢視下現在叢集情況:

nebula> SHOW HOSTS
================================================================================================
| Ip            | Port  | Status | Leader count | Leader distribution | Partition distribution |
================================================================================================
| 192.168.8.210 | 34600 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34700 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34500 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------
Got 3 rows (Time spent: 5886/6835 us)

SHOW HOSTS 返回結果解釋:

  • IPPort 表示當前的 storage 例項。這個叢集啟動了 3 個 storaged 服務,並且還沒有任何資料。(192.168.8.210:34600,192.168.8.210:34700,192.168.8.210:34500)
  • Status 表示當前例項的狀態,目前有 online/offline 兩種。當機器下線以後(metad 在一段間隔內收不到其心跳),將把其更改為 offline。 這個時間間隔可以在啟動 metad 的時候通過設定 expired_threshold_sec 來修改,當前預設值是 10 分鐘。
  • Leader count:表示當前例項 Raft leader 數目。
  • Leader distribution:表示當前 leader 在每個 space 上的分佈,目前尚未建立任何 space。( space 可以理解為一個獨立的資料空間,類似 MySQL 的 Database)
  • Partition distribution:不同 space 中 partition 的數目。

image

可以看到 Leader distributionPartition distribution 暫時都沒有資料。

Step 1.2 建立圖空間

建立一個名為 test 的圖空間,包含 100 個 partition,每個 partition 有 3 個副本。

nebula> CREATE SPACE test (PARTITION_NUM=100,REPLICA_FACTOR=3)

片刻後,使用 SHOW HOSTS 命令顯示叢集的分佈。

nebula> SHOW HOSTS
================================================================================================
| Ip            | Port  | Status | Leader count | Leader distribution | Partition distribution |
================================================================================================
| 192.168.8.210 | 34600 | online | 0            | test: 0             | test: 100              |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34700 | online | 52           | test: 52            | test: 100              |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34500 | online | 48           | test: 48            | test: 100              |
------------------------------------------------------------------------------------------------

image

如上,建立包含 100 個 partitio_n 和 3 個 replica 圖空間之後,3 個例項的_Leader distribution 和 _Partition distribution _有了對應的數值,對應的 _Partition distribution_都為 100。當然,這樣的 learder 分佈還不均勻。

Step 2 加入新例項

啟動 5 個新 storaged 例項進行擴容。啟動完畢後,使用 SHOW HOSTS 命令檢視新的狀態:

nebula> SHOW HOSTS
================================================================================================
| Ip            | Port  | Status | Leader count | Leader distribution | Partition distribution |
================================================================================================
| 192.168.8.210 | 34600 | online | 0            | test: 0             | test: 100              |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34900 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 35940 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34920 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 44920 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34700 | online | 52           | test: 52            | test: 100              |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34500 | online | 48           | test: 48            | test: 100              |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34800 | online | 0            | No valid partition  | No valid partition     |
------------------------------------------------------------------------------------------------

image

上新例項之後,叢集由原來 3 個例項變成了 8 個例項。上圖資料庫 icon 為藍色的圖示為新增的 5 個例項,此時由於僅僅加入了叢集,新例項的狀態為 Online,但此時_Leader distribution_ 和 Partition distribution 並沒有數值,說明還不會參與服務。

Step 3 遷移資料

執行 BALANCE DATA 命令。

nebula> BALANCE DATA
==============
| ID         |
==============
| 1570761786 |
--------------

如果當前叢集有新機器加入,則會生成一個新的計劃 ID。對於已經平衡的叢集,重複執行 BALANCE DATA 不會有任何新操作。如果當前有正在執行的計劃,那會顯示當前計劃的 ID。

也可通過 BALANCE DATA $id 檢視這個 balance 的具體執行進度。

nebula> BALANCE DATA 1570761786
===============================================================================
| balanceId,spaceId:partId,src->dst                           | status      |
===============================================================================
| [1570761786,1:1,192.168.8.210:34600->192.168.8.210:44920]   | succeeded   |
-------------------------------------------------------------------------------
| [1570761786,192.168.8.210:34700->192.168.8.210:34920]   | succeeded   |
-------------------------------------------------------------------------------
| [1570761786,192.168.8.210:34500->192.168.8.210:34800]   | succeeded   |
-------------------------------------------------------------------------------
...//這裡省略一些。以下一行為例
-------------------------------------------------------------------------------
| [1570761786,1:88,192.168.8.210:34700->192.168.8.210:35940]  | succeeded   |
-------------------------------------------------------------------------------
| Total:189,Succeeded:170,Failed:0,In Progress:19,Invalid:0 | 89.947090%  |
-------------------------------------------------------------------------------
Got 190 rows (Time spent: 5454/11095 us)

BALANCE DATA $id 返回結果說明:

  • 第一列 balanceId,spaceId:partId,src->dst 表示一個具體的 balance task。

    1570761786,192.168.8.210:34700->192.168.8.210:35940 為例:
    • 1570761786 為 balance ID
    • 1:88,1 表示當前的 spaceId(也就是 space test 的 ID),88 表示遷移的 partitionId
    • 192.168.8.210:34700->192.168.8.210:35940,表示資料從 192.168.8.210:34700 搬遷至_192.168.8.210:35940_。而原先 192.168.8.210:34700 中的資料將會在遷移完成後再 GC 刪除
  • 第二列表示當前 task 的執行狀態,有 4 種狀態
    • Succeeded:執行成功
    • Failed:執行失敗
    • In progress:執行中
    • Invalid:無效的 task

最後對所有 task 執行狀態的統計,部分 partition 尚未完成遷移。

Step 4 假如要中途停止 balance data

BALANCE DATA STOP 命令用於停止已經開始執行的 balance data 計劃。如果沒有正在執行的 balance 計劃,則會返回錯誤提示。如果有正在執行的 balance 計劃,則會返回計劃對應的 ID。

由於每個 balance 計劃對應若干個 balance task,BALANCE DATA STOP 不會停止已經開始執行的 balance task,只會取消後續的 task,已經開始的 task 將繼續執行直至完成。

使用者可以在 BALANCE DATA STOP 之後輸入 BALANCE DATA $id 來檢視已經停止的 balance 計劃狀態。

所有已經開始執行的 task 完成後,可以再次執行 BALANCE DATA,重新開始 balance。如果之前停止的計劃中有失敗的 task,則會繼續執行之前的計劃,如果之前停止的計劃中所有 task 都成功了,則會新建一個 balance 計劃並開始執行。

Step 5 檢視資料遷移結果

大多數情況下,搬遷資料是個比較漫長的過程。但是搬遷過程不會影響已有服務。現在可以通過 SHOW HOSTS 檢視執行後的 partition 分佈。

nebula> SHOW HOSTS
================================================================================================
| Ip            | Port  | Status | Leader count | Leader distribution | Partition distribution |
================================================================================================
| 192.168.8.210 | 34600 | online | 3            | test: 3             | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34900 | online | 0            | test: 0             | test: 38               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 35940 | online | 0            | test: 0             | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34920 | online | 0            | test: 0             | test: 38               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 44920 | online | 0            | test: 0             | test: 38               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34700 | online | 35           | test: 35            | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34500 | online | 24           | test: 24            | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34800 | online | 38           | test: 38            | test: 38               |
------------------------------------------------------------------------------------------------
Got 8 rows (Time spent: 5074/6488 us)

image

_Partition distribution _相近,partition 總數 300 不變且 partition 已均衡的分佈至各個例項。

如果有執行失敗的 task,可再次執行 BALANCE DATA 命令進行修復。如果多次執行仍無法修復,請與社群聯絡 GitHub

Step 6 Balance leader

BALANCE DATA 僅能 balance partition,但是 leader 分佈仍然不均衡,這意味著舊例項的服務較重,而新例項的服務能力未得到充分使用。執行 BALANCE LEADER 重新分佈 Raft leader:

nebula> BALANCE LEADER

片刻後,使用 SHOW HOSTS 命令檢視,此時 Raft leader 已均勻分佈至所有的例項。

nebula> SHOW HOSTS
================================================================================================
| Ip            | Port  | Status | Leader count | Leader distribution | Partition distribution |
================================================================================================
| 192.168.8.210 | 34600 | online | 13           | test: 13            | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34900 | online | 12           | test: 12            | test: 38               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 35940 | online | 12           | test: 12            | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34920 | online | 12           | test: 12            | test: 38               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 44920 | online | 13           | test: 13            | test: 38               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34700 | online | 12           | test: 12            | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34500 | online | 13           | test: 13            | test: 37               |
------------------------------------------------------------------------------------------------
| 192.168.8.210 | 34800 | online | 13           | test: 13            | test: 38               |
------------------------------------------------------------------------------------------------
Got 8 rows (Time spent: 5039/6346 us)

image

如上, BALANCE LEADER 成功執行後,新增的例項和原來的例項(對應上圖 icon 藍色和黑色圖示)的 _Leader distribution_相近, 所有例項已均衡,此外,也可以看到 Balance 命令只涉及 leader 和 partition 在物理機器上的轉移,並沒有增加或者減少 leader 和 partition。

批量縮容

Nebula Graph 支援指定需要下線的機器進行批量縮容。語法為 BALANCE DATA REMOVE $host_list,例如:BALANCE DATA REMOVE 192.168.0.1:50000,192.168.0.2:50000,將指定移除 192.168.0.1:50000,192.168.0.2:50000 兩臺機器。

如果移除指定機器後,不滿足副本數要求(例如剩餘機器數小於副本數),Nebula Graph 將拒絕本次 balance 請求,並返回相關錯誤碼。

示例資料遷移

上面講了如何從 3 個例項變成 8個例項的叢集,如果你對上文有疑問,記得在本文的評論區留言哈。我們現在看看上面遷移的過程,192.168.8.210:34600 這個例項的狀態變化。

image

說明:有顏色為紅色說明對應的數值發生變化,如果數值不變,則為黑色。

附錄

最後是 Nebula 的 GitHub 地址,歡迎大家試用,有什麼問題可以向我們提 issue。GitHub 地址:https://github.com/vesoft-inc/nebula