ScyllaDB 节点下线后重新加入集群:Revoke Decommission 操作完整指南
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
本指南讲解如何将一台已被
nodetool decommission下线(移除)的 ScyllaDB 节点重新加入原集群。无论是误操作导致节点被下线,还是希望通过“下线再上线”的方式重置节点状态,本文给出的标准做法是:先彻底清空该节点上的旧数据,再把它当作一台全新节点走一次标准的加节点(bootstrap)流程。读完本文,你将掌握从状态核验、停止服务、清理数据目录到重新引导入集群的完整操作链,并理解每一步背后的实现原理与注意事项。
为什么需要“撤销下线”:场景与思路
ScyllaDB 的nodetool decommission会把当前节点从其 token 环中移除,并将其持有的数据流式迁移给环内其余节点,然后该节点正式脱离集群。这一操作通常是不可逆的——节点一旦被下线,就没有一条“undo”命令能把它直接恢复原状。
但实际运维中,节点被误下线的情况并不少见。比如管理员在缩容演练时选错了节点、脚本误触发了 decommission,或者节点下线后发现集群容量不足需要它回来。此时官方推荐的做法(见 revoke-decommission.rst)是:
把该节点当作一台全新节点重新加入集群——即清空它本地遗留的所有数据,再执行标准的加节点(bootstrap)流程,让集群其他节点把对应 token 范围的数据重新流式复制给它。
这样做的核心原因在于:下线的节点本地仍残留着旧的 schema 与数据(包括记录 bootstrap 状态的系统表)。如果不清理就重新启动,节点会带着旧身份(Host ID、token 归属、bootstrap 状态)试图恢复,导致初始化(init)流程无法正常进行,甚至与集群当前的拓扑状态冲突。因此在重新加入前,删除旧数据目录是必须的一步。
前置条件:确认节点已从集群中移除
在动手之前,必须先确认该节点确实已经不在集群拓扑中。ScyllaDB 官方文档要求使用nodetool status命令进行核验。
nodetool status用于打印集群中节点的状态信息。在集群内任意一台存活节点上执行:
nodetool status假设被下线的节点 IP 为192.168.1.203,核验后的输出应类似(该节点不再出现在列表中):
Datacenter: DC1 Status=Up/Down State=Normal/Leaving/Joining/Moving -- Address Load Tokens Owns (effective) Host ID Rack UN 192.168.1.201 112.82 KB 256 32.7% 8d5ed9f4-7764-4dbd-bad8-43fddce94b7c B1 UN 192.168.1.202 91.11 KB 256 32.9% 125ed9f4-7777-1dbn-mac8-43fddce9123e B1注意:只有当目标节点完全消失于nodetool status输出中时,才说明它已被彻底下线,可以安全地执行下面的重加流程。如果输出中仍能看到它处于Leaving(L)状态,说明 decommission 尚未完成,应等待其彻底移出集群。
关于nodetool status输出字段的解读,可参考 status.rst:
- Status:
U表示节点存活,D表示宕机,X表示被排除(permanently lost)。 - State:
NNormal(正常)、LLeaving(正在离开)、JJoining(正在加入)、MMoving(移动中)。 - Address / Load / Tokens:节点 IP、磁盘上数据占用(每 60 秒更新)、每节点 token 数。
- Owns (effective):节点拥有的数据百分比(按数据中心与复制因子计算)。
- Host ID:节点被自动分配的唯一 UUID,是节点在集群中的身份标识。
- Rack:节点所在机架名。
从源码结构看,nodetool status对应的实现位于 api/column_family.cc 与 api/storage_service.cc 等 REST 端点之后端,最终汇聚各节点上报的 gossip 状态生成上述表格。
操作步骤
整个流程分为三步:停止服务 → 清理数据 → 重新加节点。下面逐一展开。
第 1 步:停止被下线节点的 ScyllaDB 服务
在待重新加入的节点(本例192.168.1.203)上停止 ScyllaDB 服务,确保后续清理操作时没有进程正在写入数据文件。
使用 systemd 的常规安装(Supported OS):
sudo systemctl stop scylla-server使用 Docker 部署:
docker exec -it some-scylla supervisorctl stop scyllaDocker 场景下只需停止容器内的scylla服务,无需停止some-scylla容器本身。
第 2 步:删除数据与 commitlog 目录
由于该节点将以新节点身份重新加入集群,必须删除旧的 data 文件夹;否则残留的旧状态(如 bootstrap 状态)会阻碍新节点启动初始化流程。官方给出的清理命令如下(对应仓库中的 clean-data-code.rst):
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逐条说明各目录的作用与删除必要性:
| 目录 | 作用 | 为何必须清理 |
|---|---|---|
/var/lib/scylla/data | 存放所有 keyspace 的 SSTable 数据及系统表(system keyspace) | 残留的 system 表记录着旧的 bootstrap 状态、Host ID 与 token 归属,会阻止节点以新身份初始化 |
/var/lib/scylla/commitlog | 预写日志(commit log),未刷盘的写入记录 | 旧提交日志可能引用已被删除的 SSTable 数据,且与新的节点身份不匹配 |
/var/lib/scylla/hints | 针对离线副本的 Hinted Handoff 提示 | 与旧拓扑相关的 hint 在新身份下无意义,甚至可能投递给错误的副本 |
/var/lib/scylla/view_hints | 物化视图的 hint | 同上,属于旧节点残留 |
关于数据清理的更多背景,可参考 clear-data.rst(该文档同时描述了“服务意外先启动”时应如何处理:停止服务、清空数据、重新启动)。
第 3 步:按“新增节点”流程把节点加回集群
清理完成后,即可遵循 add-node-to-cluster.rst 描述的“添加新节点到已有集群”流程,把该节点重新引导入集群。核心要点如下:
3.1 收集集群信息
在被下线节点上执行以下命令收集必要信息(也可登录集群内任一节点获取):
grep cluster_name /etc/scylla/scylla.yaml grep seeds: /etc/scylla/scylla.yaml grep endpoint_snitch /etc/scylla/scylla.yaml grep authenticator /etc/scylla/scylla.yaml scylla --version即集群名、种子节点、snitch 类型、认证器配置,以及 ScyllaDB 版本。对应的模板配置可参见仓库中的 conf/scylla.yaml。
3.2 配置/etc/scylla/scylla.yaml
编辑该节点的/etc/scylla/scylla.yaml,确认或修改以下关键参数:
- cluster_name:集群名称,必须与集群内其他节点一致(模板默认
'Test Cluster')。 - listen_address:节点用于与集群其他节点通信的内部 IP。
- endpoint_snitch:拓扑感知策略,必须与集群一致(模板默认
SimpleSnitch)。 - rpc_address:面向 CQL 客户端连接的服务地址(模板默认
localhost)。 - seeds:集群中一个已存在节点的 IP,新节点通过它连接集群并学习拓扑与状态。
版本一致性提醒:务必使新节点的 ScyllaDB补丁版本与集群其余节点完全一致,不建议用不同 release 的节点加入集群。例如当前部署版本为 2025.1.0 时:
sudo yum install scylla-2025.1.0该要求同样记录于 match_version.rst。
3.3 启动并验证
启动 ScyllaDB 服务:
# systemd 安装 sudo systemctl start scylla-server # Docker 部署(容器已运行) docker exec -it some-scylla supervisorctl start scylla然后再次执行nodetool status验证节点加入情况。此时集群其他节点会向新节点流式传输数据,新节点会先处于Up Joining (UJ)状态,类似:
Datacenter: DC1 Status=Up/Down State=Normal/Leaving/Joining/Moving -- Address Load Tokens Owns (effective) Host ID Rack UN 192.168.1.201 112.82 KB 256 32.7% 8d5ed9f4-7764-4dbd-bad8-43fddce94b7c B1 UN 192.168.1.202 91.11 KB 256 32.9% 125ed9f4-7777-1dbn-mac8-43fddce9123e B1 UJ 192.168.1.203 124.42 KB 256 32.6% 675ed9f4-6564-6dbd-ca08-43fddce952de B1等待流式传输完成,状态变为Up Normal (UN):
Datacenter: DC1 Status=Up/Down State=Normal/Leaving/Joining/Moving -- Address Load Tokens Owns (effective) Host ID Rack UN 192.168.1.201 112.82 KB 256 32.7% 8d5ed9f4-7764-4dbd-bad8-43fddce94b7c B1 UN 192.168.1.202 91.11 KB 256 32.9% 125ed9f4-7777-1dbn-mac8-43fddce9123e B1 UN 192.168.1.203 124.42 KB 256 32.6% 675ed9f4-6564-6dbd-ca08-43fddce952de B13.4 执行nodetool cleanup
当新节点状态变为 UN 后,需要在集群中除新节点外的所有其他节点上执行:
nodetool cleanupcleanup用于清除那些已经流式迁移给新节点、不再由原节点拥有的 key,防止数据“复活”回旧位置。官方文档特别给出以下提示以降低 cleanup 的资源开销:
- 添加多个节点时,可在所有节点都加入完成后,仅在“除最后一个加入节点外”的其他节点上执行 cleanup;
- 可将 cleanup 推迟到低峰时段执行,但必须确保在任何节点 decommission/remove 之前完成;
- 一次只在一个节点上运行 cleanup,降低对集群整体的影响。
源码视角:decommission 与重新加入的机制
从源码与测试层面,可以进一步理解这一操作闭环的底层机制:
- decommission 的入口:
nodetool decommission命令对应 decommission.rst 文档,其核心行为是把节点数据流式迁移给环上的下一个节点。官方文档提醒:执行 decommission 前要确认剩余节点磁盘空间充足、且 decommission 后 DC 内剩余节点数不低于 keyspace 的复制因子(RF)。 - remove-node 文档的呼应:在 remove-node.rst 中,节点被移除后同样要求手动清理数据与 commitlog(复用同一份 clean-data-code.rst 清理命令),原因与本文一致——被移除节点的数据不会自动删除,其本地残留状态会干扰后续以新身份加入集群。
- 服务端实现位置:从源码结构看,与节点生命周期相关的 REST API 处理集中在 api/storage_service.cc(如 decommission/removenode 等端点),数据流式迁移逻辑则在 streaming/ 目录下实现;
nodetool status依赖 gossip 状态汇总,相关实现在 gms/gossiper.cc。 - 测试覆盖:仓库 test/ 目录中包含了大量围绕节点生命周期(decommission、add node、replace、cleanup)的集成测试用例(如
test/topology*系列),可用于验证“下线节点清空数据后重新加入”这一场景的正确性。
注意事项与常见误区
- decommission 一旦完成就没有“撤销”命令。不要试图用重启、
nodetool removenode的逆操作等方式恢复下线节点,唯一受支持的正确路径就是本文的“清空数据 + 重新 bootstrap”。 - 必须确认节点已完全移出
nodetool status输出后再开始操作。若节点仍处于Leaving状态,应等待 decommission 彻底结束。 - 清理必须彻底。仅删除
data目录而不清理 commitlog、hints、view_hints 的做法会导致新身份与旧残留数据不一致。 - 配置必须与集群一致。
cluster_name、endpoint_snitch、seeds等任一参数不匹配都会导致节点无法成功加入。 - 版本必须匹配补丁版本。以不同 release 加入集群不被推荐,可能引发协议或功能不兼容。
- 不要忽略 cleanup。若不执行
nodetool cleanup,被迁移走的 key 会残留在旧节点磁盘上,带来数据一致性与存储浪费隐患。
小结
把已下线(decommissioned)的 ScyllaDB 节点重新加入集群,本质上是执行一次“受控的新节点添加”:确认节点已离群 → 停止服务 → 清理本地全部数据与日志 → 按新增节点流程重新 bootstrap。这套流程的关键在于彻底清除节点旧身份残留,让集群能够安全地把它当作全新成员重新接纳,并由其他节点重新流式同步其应属的数据。相关命令与说明均可在此前的 decommission、remove-node、add-node-to-cluster 文档及仓库源码中找到一致印证。
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考