ScyllaDB 节点下线前的磁盘空间规划:decommission 容量检查与失败规避完整指南
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
在 ScyllaDB 集群缩容(scale-down)操作中,nodetool decommission会把被移除节点的数据流式传输(streaming)到其余节点,因此剩余节点是否有足够的磁盘空间,直接决定下线操作成败。本文以仓库中复用于多份文档的官方警告(decommission_warning.rst)为核心,系统讲解下线前磁盘空间评估方法、空间不足的失败表现、完整的下线流程与规避手段,帮助你在执行节点移除前完成正确的容量规划,避免操作中途失败。
一、警告原文:官方强制要求在下线前完成容量审查
ScyllaDB 官方文档将以下警告以 Sphinx.. include::复用片段的形式,同时嵌入到节点移除操作流程(remove-node.rst)与nodetool decommission命令参考(decommission.rst)中,其原文要点如下:
- 审查现有节点当前的磁盘空间使用率,确保从被移除节点流出的数据量能够放进剩余节点可用磁盘空间中;
- 如果剩余节点磁盘空间不足,节点移除将失败;
- 必须在开始移除流程之前为剩余节点增加存储。
这段警告虽然只有寥寥数行,却概括了 ScyllaDB 缩容操作中最容易踩坑的一类事故:decommission 不是一个"逻辑上摘掉节点"的元数据操作,而是一个会产生真实数据搬运的存储操作。下面我们从源码层面解释它为什么如此关键。
二、为什么需要磁盘空间:decommission 的数据流机制
从源码结构看,ScyllaDB 的 decommission 本质上是"反向引导(unbootstrap)"流程:
- 入口为 service/storage_service.cc 中的
storage_service::decommission(),它通过run_with_api_lock串行化执行,避免与其他拓扑操作并发冲突; - 对于使用 Raft 协调的集群,实际请求进入
raft_decommission()(service/storage_service.cc),并向 group0 提交一条decommission: request decommission for ...命令(service/storage_service.cc); - 数据搬运由
dht::range_streamer承担,在源码中以"Unbootstrap"为流名称、以streaming::stream_reason::decommission为原因发起(service/storage_service.cc); - 被下线节点负责将自身持有的 token 范围数据流式传输给环上的其他节点,之后才将自身从
left_token_ring拓扑状态中移除(service/storage_service.cc)。
这意味着:下线一个节点,相当于把它的"负载"(含 SSTable 数据、二级索引数据、视图数据等)平均或按拓扑规则分摊给剩余节点。剩余节点的可用空间必须大于等于被分摊数据的实际落盘量,否则流式传输写入时会因磁盘写满而失败。
此外,ScyllaDB 通过 REST 接口暴露该操作(/storage_service/decommission),对应 api/storage_service.cc 中的rest_decommission,最终调用ss.local().decommission(ssc)。nodetool decommission正是向该接口发起 HTTP POST 请求——因此 decommission 失败时,客户端会收到形如ScyllaDB API server HTTP POST to URL '/storage_service/decommission' failed的错误(见 failed-decommission.rst)。
三、操作前评估:如何确认剩余节点有足够的可用空间
按照警告的要求,在下线前请逐项执行以下检查:
1. 查看各节点的磁盘使用率
在被移除节点之外的每一个剩余节点上执行:
df -h重点关注挂载点(ScyllaDB 默认数据目录为/var/lib/scylla,可通过scylla.yaml的data_file_directories调整)的Avail(可用空间)列。
2. 估算将被搬运的数据量
- 使用
nodetool status查看各节点当前的Load(各节点持有的数据量); - 被移除节点的
Load是数据搬运量的上限参考。需要说明的是,实际搬运量并不等于该节点全部数据——streaming 只传输那些在新拓扑下仍需要保留在剩余节点上的 token 范围数据,过期数据、已被压缩清除的数据不会重复传输;同时剩余节点各自还要为新数据预留 compaction 等临时空间。因此在规划时,建议以被移除节点Load的相当比例为粗估基准,再结合各 keyspace 的复制因子(RF)与本数据中心剩余节点数量做估算。
3. 空间充足性判定
对于剩余节点集合中的每个节点,近似满足:
节点可用空间 ≥ 该节点将承接的流式数据量 + 日常运行预留空间(compaction 临时文件、commitlog、hints 等)如果任一剩余节点不满足,先在剩余节点上扩容(增加磁盘或数据目录容量),再开始移除流程——这是警告中"before"一词强调的顺序要求:扩容必须发生在移除操作之前,因为一旦 streaming 开始,中途再扩容虽然可能挽救操作,但流程复杂度与风险会显著上升。
四、空间不足会怎样:失败表现与影响
如果忽略容量检查直接执行 decommission,可能出现以下失败形态:
streaming 写入失败:数据流式传输过程中目标节点磁盘写满,流任务中断。此时从运行
nodetool decommission的客户端看,错误形如:nodetool: ScyllaDB API server HTTP POST to URL '/storage_service/decommission' failed: stream_ranges failed该错误信息记录在官方排障文档 failed-decommission.rst 中,同时节点可能停留在
UL(Up Leaving)状态无法自行收敛。操作被拒绝:某些校验性失败会在更早阶段抛出。例如 service/storage_service.cc 中,当 Raft 协调器收到无法受理的下线请求时会抛出
Decommission failed: node decommission rejected: ...;当集群只剩最后一个节点或最后一个持有 token 的节点时,也会直接拒绝(service/storage_service.cc)。数据一致性风险:decommission 过程中若因磁盘问题导致流任务异常,虽然 ScyllaDB 的拓扑状态机与任务管理器可以追踪任务进度,但部分数据可能停留在中间状态。官方排障流程给出的标准恢复路径是:重启被下线节点 → 确认恢复为
UN(Up Normal)→ 重新执行nodetool decommission(见 failed-decommission.rst)。
值得注意:decommission 期间nodetool netstats并不展示正在进行的 streaming 细节(官方在 failed-decommission.rst 中明确提示),它更多用于观察 token 再分配的整体进度。
五、完整的下线流程:警告在流程中的位置
官方推荐的"移除运行中节点"流程(完整步骤见 remove-node.rst)如下,其中第一步之后紧接着就是本文讨论的磁盘空间检查:
- 执行
nodetool status确认待移除节点状态为UN(Up Normal); - (本警告所处位置)审查剩余节点磁盘空间,必要时先扩容;
- 在被移除节点上执行
nodetool decommission; - 执行
nodetool netstats监控 token 再分配进度; - 执行
nodetool status确认该节点已从环上消失; - 手工清理被移除节点上的残留数据(decommission 不会自动删除本地数据):
sudo rm -rf /var/lib/scylla/data sudo find /var/lib/scylla/commitlog -type f -delete sudo find /var/lib/scylla/hints -type f -delete sudo find /var/lib/scylla/view_hints -type f -delete(清理命令源自仓库公共片段 clean-data-code.rst,其中rm命令仅建议在确认数据已全部成功搬离后执行。)
与磁盘规划并列的其它前置校验
nodetool decommission命令参考(decommission.rst)在磁盘空间检查之外还要求:
- 剩余节点数 ≥ keyspace 复制因子(RF):若本数据中心下线后剩余节点数低于 RF,decommission 请求可能失败,此时应先
ALTER KEYSPACE降低 RF 再下线;需留意 audit 功能默认启用,可能需要相应调整auditkeyspace; - 不得在任何现有节点处于 Down 状态时执行 decommission。
六、不可恢复节点的场景:removenode 的容量注意点
当节点永久宕机、无法恢复时,官方推荐改用nodetool removenode <Host ID>(见 removenode.rst)。该命令同样依赖其余节点通过 streaming 重建被移除节点持有的 token 范围数据(tablet 场景下是并行重建,vnode 场景下与其它 vnode 操作串行),因此前文的空间检查在这里同样适用——甚至更应谨慎,因为:
- 被移除节点已宕机,其本地数据不可用,其余节点必须基于已有副本重建数据;
removenode开始时,被移除节点与--ignore-dead-nodes列出的节点会被永久 ban 出集群(removenode.rst),操作失败后无法简单回退;- 官方要求执行
removenode前先做全集群 repair,确保所有副本数据最新(见 remove-node.rst)。
因此,在removenode前同样要先确认剩余节点磁盘空间足够承接重建数据,并满足"剩余节点数 ≥ RF"的前提,否则应考虑走replace流程而不是removenode。
七、最佳实践小结
| 检查项 | 方法 | 失败后果 |
|---|---|---|
| 剩余节点可用空间 | df -h,对比被移除节点Load估算搬运量 | streaming 写满磁盘,操作失败 |
| 剩余节点数 ≥ RF | nodetool status与 keyspace 配置核对 | decommission/removenode 请求被拒绝 |
| 集群其它节点状态 | nodetool status确认全部为 UN | 无法执行 decommission |
| 副本数据新鲜度(removenode) | 先执行全集群 repair | 重建数据不一致 |
核心原则浓缩为官方警告的那句话:在下线流程开始之前,为剩余节点补足存储。容量规划是 ScyllaDB 集群缩容的第一道防线,做好这一步,nodetool decommission与nodetool removenode才能顺畅、安全地完成。
延伸阅读
- 移除集群节点(Down Scale)完整流程
- nodetool decommission 命令参考
- nodetool removenode 命令参考
- Failed Decommission 排障指南
- decommission 源码实现入口:storage_service.cc
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考