Drain Datanode
Drain 会把某个 Datanode 上的 Leader Region 迁移到其他 Datanode,使该节点可以在不影响写入可用性的前提下停止服务。在恢复调度之前,Metasrv 不会再把 Region 放置到该节点。
Drain 仅在 Datanode 使用共享存储的集群模式下可用,前提条件与 Region Migration 相同。单机实例不支持该操作。
Drain 的作用
- Procedure 开始时会将该 Datanode 标记为不可调度。在 Drain 期间以及 Drain 结束后,Metasrv 都不会再向该节点放置新的 Region。
- 节点上的 Leader Region 会迁移到其他 Datanode。未指定目标节点时,由 Metasrv 为每个 Region 选择目标。
- Follower Region 不会被迁移。节点仍会存储并服务它持有的 Follower Region。Drain 既不会停止 Datanode 进程,也不会把节点从集群中移除。
- Drain 是一个异步 Procedure:HTTP 请求只返回
procedure_id,迁移在后台继续,Metasrv 重启后会恢复执行。 - 无论成功还是失败,Procedure 结束后节点仍处于不可调度状态。恢复调度需要单独执行操作。
前提条件
- 使用共享存储的集群模式。
- 能访问 leader Metasrv 的 HTTP 端口,默认为
4000。在 follower 上调用这些端点会返回 HTTP500和错误码1006。可通过GET /admin/leader获取 leader 地址。 - 在网络层保护 Admin HTTP 端口。Admin API 没有鉴权,详见 Admin API。
查询当前调度状态
curl -X GET 'http://localhost:4000/admin/datanode/scheduling/status?node_id=1'
{"node_id":1,"schedulable":true}
从未被 Drain 的节点,schedulable 为 true。
发起 Drain
curl -X POST 'http://localhost:4000/admin/datanode/drain' \
-H 'Content-Type: application/json' \
-d '{"node_id": 1, "target_node_id": 2, "parallelism": 8, "strategy": "fail_fast", "timeout": "30m"}'
{"procedure_id":"a3b9f746-81c2-4e65-9d07-6f2c8b104ea5"}
请求支持以下可选字段:
target_node_id:目标 Datanode。省略时由 Metasrv 为每个 Region 选择目标。目标节点不能与被 Drain 的节点相同,否则请求返回 HTTP400。parallelism:同时执行的 Leader Region 迁移数量,取值为 1 到 32,默认为4。strategy:try_all在迁移失败后继续迁移剩余 Region,并报告无法迁走的 Region;fail_fast在一批迁移出现失败后停止 Drain。默认为try_all。timeout:整个 Drain 的时间预算,从提交时刻开始计算。支持"30m"、"1h 30m"这类可读时长,默认为20m。
省略字段即使用默认 值。parallelism、strategy 和 timeout 显式传入 null 会被拒绝。
当该节点已有 Drain 在运行时,对同一节点的 Drain 请求(包括内容完全相同的请求)都会被拒绝。请跟踪正在运行的 Procedure,而不是重试请求。
等待 Procedure 结束
curl -X GET 'http://localhost:4000/admin/procedure/status?procedure_id=a3b9f746-81c2-4e65-9d07-6f2c8b104ea5'
{"procedure_id":"a3b9f746-81c2-4e65-9d07-6f2c8b104ea5","status":"Done","error":null}
迁移进行中 status 为 Running。当 Drain 无法迁移部分 Leader Region,或因无法恢复的错误停止时,status 为 Failed;失败信息写在 error 中,无法迁走的 Region 也会列在那里。已经迁移成功的 Region 保持迁移后的状态。
Done 只表示 Drain 没有更多需要提交的迁移,不能证明该节点已不承载任何 Leader Region。Metasrv 重启后,已恢复的 Region 迁移会独立继续执行;Drain 不会处理已有迁移在运行的 Region,因此可能在这些迁移仍为 Running 时报告 Done。Done 也不包含迁移数量。
如果 Drain 失败,排除原因后重新提交即可。新的 Procedure 会重新扫描该节点剩余的 Leader Region,并跳过已经迁走的 Region,不会从头开始。
确认节点上没有 Leader Region
调度状态和 Procedure 状态都不反映 Region 分布。请查询当前 catalog 中该节点仍在担任 leader 的 Region:
SELECT table_schema, table_name, region_id
FROM information_schema.region_peers
WHERE peer_id = 1 AND is_leader = 'Yes';
在将节点下线之前,该查询必须返回空结果。region_peers 会列出当前 catalog 中的所有 peer,因此 is_leader = 'No' 的行是仍留在该节点上的 Follower Region,它们不阻碍下线。仍在迁移中的 Region 依然由该节点担任 leader,因此应等待查询返回空结果,而不是只看 Done。
region_peers 一次只覆盖一个 catalog。请对集群中的每个 catalog 分别执行查询,并要求每个结果都为空;通过 greptime.information_schema.region_peers 这样的限定名可以查询指定 catalog。
恢复调度
维护结束,或需要让该节点重新承载 Region 时,显式恢复调度:
curl -X POST 'http://localhost:4000/admin/datanode/mark-schedulable' \
-H 'Content-Type: application/json' \
-d '{"node_id": 1}'
{"node_id":1,"schedulable":true}
该调用是幂等的,重复执行也会成功。当同一节点仍有 Drain 在运行,或 Metasrv 重启后尚未完成 Procedure 恢复时,该调用会失败。
行为与限制
- Drain 的时间预算默认为 20 分钟,从提交时刻开始计算,可通过
timeout为单次请求调整。超过预算的 Drain 以Failed结束。 - 默认最多同时迁移 4 个 Leader Region,可通过
parallelism设置为 1 到 32。 strategy决定迁移失败后的处理方式:try_all(默认)继续迁移剩余 Region ;fail_fast在出现失败的那一批之后停止。- Procedure 不会把 Datanode 移出集群,也不会迁移 Follower Region。如果节点上仍有 Follower Region 就将其下线,依赖这些 Region 的读请求会受影响。
响应与错误
成功的请求返回 HTTP 200 和 JSON 响应体。被拒绝的请求返回统一的错误响应体:
{"code":1006,"error":"Another drain procedure is running for datanode: 1","execution_time_ms":0}
1006(IllegalState,HTTP500):请求打到了 follower Metasrv;该节点已有 Drain 在运行;恢复调度时该节点正在 Drain;或 Metasrv 尚未完成 Procedure 恢复。1004(InvalidArguments,HTTP400):Drain 的目标节点与源节点相同;parallelism超出 1–32;timeout为零或大到无法调度;或procedure_id格式不合法、不存在。- HTTP
422:JSON 请求体无法解析,例如缺少必填字段、strategy取值未知或timeout时长格式错误。能正常解析但未通过校验的取值(例如parallelism超出 1–32)返回 HTTP400。