存储服务的负载均衡和数据迁移

Nebula Graph 的服务可分为 graphd,storaged,metad。此文档中的 balance 仅针对 storaged 进行操作。目前,storaged 的扩缩容是通过 balance 命令来实现的。balance 命令有两种,一种需要迁移数据,命令为 BALANCE DATA;另一种不需要迁移数据,只改变 partition 的 leader 分布,来达到负载均衡的目的,命令为 BALANCE LEADER

Balance data

以下举例说明 BALANCE DATA 的使用方式。本例将集群从 3 个实例(进程)扩展到 8 个实例(进程):

Step 1 准备

部署一个三副本的集群,1个 graphd,1个 metad,3个 storaged(具体部署方式请参考集群部署文档),通过 SHOW HOSTS 命令可以看到集群的状态信息:

Step 1.1

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 返回结果说明:

  • IP, Port 表示当前的 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 在每个图空间上的分布,目前尚未创建任何图空间。
  • Partition distribution:不同 space 中 partition 的数目。

Step 1.2

创建一个名为 test 的图空间,包含 100 个 partition 和 3 个 replica。

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              |
------------------------------------------------------------------------------------------------

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     |
------------------------------------------------------------------------------------------------

新启动的 storage instance 此时还没有任何 partition。

Step 3 迁移数据

运行 BALANCE DATA 命令, 查看当前的 balance 计划 id。如果当前集群有新机器加入,则会生成一个新的计划 id。对于已经平衡的集群,重复运行 BALANCE DATA 不会有任何新操作。

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

也可通过 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, 1:1, 192.168.8.210:34700->192.168.8.210:34920]   | succeeded   |
-------------------------------------------------------------------------------
| [1570761786, 1:1, 192.168.8.210:34500->192.168.8.210:34800]   | succeeded   |
-------------------------------------------------------------------------------
...
| Total:189, Succeeded:170, Failed:0, In Progress:19, Invalid:0 | 89.947090%  |
-------------------------------------------------------------------------------

BALANCE DATA $id 返回结果说明:

  • 第一列 balanceId, spaceId:partId, src->dst 表示一个具体的 balance task。 以 1570761786, 1:88, 192.168.8.210:34700->192.168.8.210:35940 为例:

    • 1570761786 为 balance ID
    • 1:88,1 表示当前的 spaceId,88 表示迁移的 partId
    • 192.168.8.210:34700->192.168.8.210:3594,表示数据从192.168.8.210:34700 搬迁至 192.168.8.210:35940
  • 第二列表示当前 task 的运行状态,目前有 4 种状态
    • Succeeded:运行成功
    • Failed:运行失败
    • In progress:运行中
    • Invalid:无效的 task

最后一行为对所有 task 运行状态的统计,部分 partition 尚未完成迁移。

Step 4 查看结果

大多数情况下,搬迁数据是个比较漫长的过程。但是搬迁过程不会影响已有服务。运行结束后,进度会提示 100%。如果有运行失败的 task,可再次运行 BALANCE DATA 命令进行修复。如果多次运行仍无法修复,请与社区联系 GitHub。最后,通过 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)

可以看到 partition 和对应的数据已均衡的分布至各个机器。

Balance stop

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 计划并开始执行。

批量缩容

Nebula Graph 支持指定需要下线的机器进行批量缩容。语法为 BALANCE DATA REMOVE $host_list,例如 BALANCE DATA REMOVE 192.168.0.1:50000,192.168.0.2:50000,将在本次 balance 过程中移除 192.168.0.1:50000,192.168.0.2:50000 两台机器。

如果移除指定机器后,不满足副本数要求(例如剩余机器数小于副本数,或者三副本中有一台已经离线,此时要求移除剩余两副本中的一个),Nebula Graph 将拒绝本次 balance 请求,并返回相关错误码。

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)