ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

ScyllaDB 卡在 JOINING (UJ) 状态节点的安全移除指南:drain、清理数据与重新加入集群

2026/9/15 22:42:44 拓冰建站 浏览量
ScyllaDB 卡在 JOINING (UJ) 状态节点的安全移除指南:drain、清理数据与重新加入集群 ScyllaDB 卡在 JOINING (UJ) 状态节点的安全移除指南drain、清理数据与重新加入集群【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb导读当向 ScyllaDB 集群添加新节点时节点可能长期停留在 Up-Joining (UJ) 状态、始终无法进入 Up-Normal (UN) 状态此时唯一的解决办法是移除该节点并重试。本文基于官方运维手册 safely-removing-joining-node.rst完整讲解drain → 停止 → 清理数据 → 启动四步操作并结合仓库源码剖析nodetool drain的底层实现帮助你在不破坏集群数据的前提下安全处置卡住的加入中节点。问题背景什么是 JOINING (UJ) 状态在 ScyllaDB 中向集群添加新节点是一个涉及数据流streaming的过程新节点加入后其他节点会把属于新节点 token 范围的数据流式传输给它。在此期间通过nodetool status观察新节点会显示为UJUp, Joining状态——即进程已启动、正在加入中但尚未完成数据同步。当数据同步完成、节点进入正常服务状态后状态才会变为UNUp, Normal。这一过程的时间长短取决于数据量和网络带宽参见 add-node-to-cluster.rst。然而在某些情况下新节点可能卡死在 JOINING 状态长时间停留在 UJ 而永远无法进入 UN。官方文档给出的结论是唯一的解决方案是移除该节点。同时文档给出了一个关键的安全边界只要节点从未进入 UN 状态即从未真正加入集群你就可以停止该节点、清理它的数据然后重新尝试加入。也就是说本方案适用于尚未成功加入集群的节点。如果一个节点已经进入过 UN 状态已正常服务那就不能再简单采用停止清理重试的方式否则会破坏集群的副本数据布局此时应改用其他集群管理流程。操作前提与安全边界确认在动手之前请务必确认以下两点确认节点确实处于 UJ 状态运行nodetool status观察目标节点的状态标识。只有确认其显示为UJUp Joining且长时间不变化才适用本文流程。确认该节点从未进入 UN 状态这是整个操作安全性的核心前提。未加入集群的节点上没有集群数据的所有权清理其本地数据不会影响集群其他节点上的数据副本。官方手册 cluster-platform-migration.rst 也给出了同样的判断如果新节点长时间停留在UJ状态应当按本文流程处理。四步操作流程详解以下命令全部在卡住的节点本机上执行。第一步执行 nodetool drainnodetool drainnodetool drain会将该节点上所有 memtable 刷新flush到磁盘上的 SSTable同时停止监听来自客户端和其他节点的连接。官方对 drain 命令的完整定义参见 drain.rst它会停止 ScyllaDB 接收客户端与其他节点的连接且执行后必须重启 ScyllaDB。该命令通常在执行节点升级或任何维护操作前使用。注意如果你只是想简单地把 memtable 刷到磁盘不停止连接应使用nodetool flush而不是nodetool drain。第二步停止节点受支持的 Linux 发行版通过 systemd 安装sudo systemctl stop scylla-serverDocker 部署方式docker exec -it some-scylla supervisorctl stop scylla注意上述命令只停止容器内的 ScyllaDB 进程不会停止some-scylla容器本身。执行后容器仍在运行便于下一步清理数据文件。第三步清理节点数据这是最关键的一步——清空该节点在加入过程中产生的所有本地数据使其恢复到干净状态以便重新加入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/datasudo rm -rf数据目录删除全部 SSTable 与相关数据文件/var/lib/scylla/commitlogsudo find ... -type f -delete提交日志删除文件但保留目录/var/lib/scylla/hintssudo find ... -type f -delete提示hinted handoff文件/var/lib/scylla/view_hintssudo find ... -type f -delete物化视图相关的提示文件路径可能不同以上路径是默认值。ScyllaDB 的数据目录、提交日志目录与提示目录均可在配置文件 conf/scylla.yaml 中调整对应data_file_directories第 32 行、commitlog_directory第 37 行、hints_directory第 284 行、view_hints_directory第 287 行。如果你的节点修改过这些配置请将命令中的路径替换为实际配置值。第四步启动节点受支持的 Linux 发行版sudo systemctl start scylla-serverDocker 部署方式docker exec -it some-scylla supervisorctl start scylla前提some-scylla容器已在运行中。启动完成后ScyllaDB 会重新执行加入流程节点将以 UJ 状态再次尝试加入集群这次通常会正常完成数据流并进入 UN 状态。源码视角nodetool drain 到底做了什么为了确保你在执行 drain 后可以安全地停止并清理节点有必要理解其底层实现。在 ScyllaDB 源码中drain 的 REST API 入口位于 api/storage_service.cc它会调用storage_service::drain()其核心实现在 service/storage_service.cc节点进入DRAINING模式后执行do_drain()完成后将_drain_finished置位并切换到DRAINED模式如果节点已经处于DRAINED状态再次执行会输出警告Cannot drain node (did it already happen?)并直接返回。do_drain()service/storage_service.cc的执行顺序可以概括为停止传输层stop_transport()关闭与客户端及其他节点的连接——这正是 drain 命令停止监听语义的来源取消非本地写响应处理器cancel_nonlocal_write_response_handlers()释放可能被挂起写请求持有的 token_metadata 版本避免后续等待 group0 停止时发生死锁排空视图构建器view_builder/view_building_worker的drain在停止 group0 之前完成视图构建的排空继续排空 group0、提交日志commitlog、memtable 等本地存储组件将内存数据完整落盘。从源码可以看出drain 是一个先切断外部联系、再有序落盘的受控关闭过程。正因为 drain 完成后节点已不再对外服务且数据已刷盘接下来停止服务、清理数据目录才不会有在途请求或未落盘数据丢失的风险。常见问题与注意事项可以跳过 drain 直接停止吗不推荐。文档明确将 drain 列为第一步。跳过 drain 意味着停止前可能还有在途连接与未刷盘的 memtable直接停止可能造成数据不一致或拖慢后续清理。执行 drain 后节点会自动重启吗不会。drain 只会让节点进入 DRAINED 状态并停止监听后续的停止、清理、启动都需要你按步骤手动执行。清理数据会丢失集群数据吗不会。前提是节点从未进入 UN 状态——此时它尚未成为集群数据副本的持有者清理的只是它本地在加入过程中收到的临时数据。集群其他节点上的数据不受影响。重新加入后仍然卡在 UJ如果清理数据后重试节点依然长时间停留在 UJ则说明问题不在本地数据而更可能出在网络、磁盘空间或集群拓扑层面需要结合日志进一步排查可参考 node-joined-without-any-data.rst 中关于 UJ 状态的分析思路。命令需要 root 权限无论是 systemd 还是 Docker 方式停止服务与清理/var/lib/scylla下的文件都需要sudo或在容器内使用具有足够权限的用户。总结处理卡在 JOINING (UJ) 状态、始终无法进入 UN 状态的 ScyllaDB 节点标准做法就是四步nodetool drain受控停止服务 → 停止节点进程 → 清理data/commitlog/hints/view_hints四个目录 → 重新启动节点使其再次尝试加入。这套流程安全的前提是节点从未真正加入集群一旦确认这一前提就可以放心地清理本地数据并重试。掌握这一流程你就能在扩容失败时快速恢复集群的可用状态而无需动用更复杂的集群管理操作。【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考