news 2026/9/15 22:16:20

ScyllaDB 集群安全关机(Safe Shutdown)完整指南:drain、验证与重启全流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
ScyllaDB 集群安全关机(Safe Shutdown)完整指南:drain、验证与重启全流程

ScyllaDB 集群安全关机(Safe Shutdown)完整指南:drain、验证与重启全流程

【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb

本文基于 safe-shutdown.rst 官方文档,完整讲解在物理搬迁硬件或计划性停机场景下,如何以不损坏数据、不触发额外修复的方式安全关闭 ScyllaDB 集群,并配套源码级原理剖析与重启(safe-start)衔接流程。读完本文,你将掌握nodetool drain+nodetool status+ 停止服务的标准三步法,并能根据节点状态码判断停机是否真正成功。

为什么需要"安全关机"而不是直接关电源

ScyllaDB 是一个基于 Seastar 框架的 NoSQL 数据存储,兼容 Apache Cassandra 与 Amazon DynamoDB。它在内存(memtable)中缓存大量近期写入数据,并以周期性刷盘(flush)的方式持久化到磁盘上的 SSTable 文件。如果直接断电或强制 kill 进程,未刷盘的 memtable 数据虽可通过 commitlog 在重启时重放恢复,但代价是:重启时需要进行崩溃恢复(replay commitlog),在集群多个节点同时重启的场景下,还可能触发大范围的流式修复(repair)、hinted handoff 投递积压,显著拉长集群恢复时间,甚至放大停机窗口内的风险。

因此官方文档给出的做法是:在需要物理移动硬件、或别无选择必须停机时,先执行 drain 让节点优雅地把内存数据全部落盘,再干净地停止服务,从而把重启成本降到最低。

操作前检查(Before you begin)

官方文档明确要求在动手之前确认一件事:

确认没有任何应用程序正在把该集群作为后端存储使用。

这一步非常关键:nodetool drain执行后节点会停止监听来自客户端和其他节点的连接,此时节点上的读写请求会立即失败。如果在业务高峰期或有在线应用持续读写时执行 drain,会造成明显的请求中断。因此应先在应用层完成流量摘除(例如停止写入任务、切换只读、或让客户端连接到其他节点),再对目标节点执行关机流程。

安全关机三步法(在每个节点上并行执行)

官方流程要求在集群的每个节点上、以并行方式依次执行以下三个步骤。并行执行的含义是:不要串行地逐台关机,而是各节点几乎同时完成 drain → 验证 → 停止,以缩短集群整体不可用窗口。

第 1 步:执行nodetool drain

nodetool drain

根据 drain 命令文档 的定义,该命令会:

  • 将节点上所有 memtable 刷写(flush)为磁盘上的 SSTable;
  • 停止监听来自客户端和其他节点的连接;
  • 执行完成后需要重启 ScyllaDB 才能恢复服务。

该命令通常用于节点升级前、或任何维护动作之前。从 tools/scylla-nodetool.cc 的源码可以看到它的帮助文本与官方文档一致:

Drain the node (stop accepting writes and flush all tables) Flushes all memtables from a node to the SSTables that are on the disk. Scylla stops listening for connections from the client and other nodes. You need to restart Scylla after running this command. ...

注意:如果你只想把 memtable 刷盘、而不需要停止节点对外服务,应当使用 nodetool flush 而不是 drain。flush 的语法为:

nodetool flush # 刷写所有 keyspace nodetool flush keyspace1 # 刷写指定 keyspace nodetool flush keyspace1 standard1 # 刷写指定 keyspace 的指定表

<keyspace><table> ...均为可选参数:省略 keyspace 时刷写全部 keyspace;指定 keyspace 后可进一步限定一张或多张表。

第 2 步:用nodetool status验证 drain 完成

nodetool status

drain 命令本身在正常完成后会正常返回,但官方流程仍要求用nodetool status二次确认。判断标准非常明确:

如果节点状态被列为DN,则说明 drain 命令已成功执行。

理解DN的含义需要拆解 nodetool status 输出的两列标记:

  • Status 列U= Up(节点在线)、D= Down(节点离线)、X= excluded(已被removenodeexcludenode或节点替换标记为永久丢失的宕机节点);
  • State 列N= Normal、L= Leaving、J= Joining、M= Moving。

所以DN表示节点处于Down + Normal:节点已停止对外服务但状态正常(并未处于离开/加入/移动等过渡状态),这正是 drain 成功后节点应有的表现。而正常运行时节点应显示为UN(Up + Normal),例如:

Datacenter: datacenter1 ======================= Status=Up/Down/eXcluded |/ State=Normal/Leaving/Joining/Moving -- Address Load Tokens Owns (effective) Host ID Rack UN 127.0.0.1 394.97 MB 256 33.4% 292a6c7f-2063-484c-b54d-9015216f1750 rack1 UN 127.0.0.2 151.07 MB 256 34.3% 102b6ecd-2081-4073-8172-bf818c35e27b rack1 XN 127.0.0.4 149.07 MB 256 32.3% dd961642-c7c6-4962-9f5a-ea774dbaed77 rack1

第 3 步:drain 成功后停止节点

确认节点状态为DN后,即可停止该节点的 ScyllaDB 服务。根据 scylla-commands-stop-index.rst,停止命令因部署方式而异:

  • 支持的操作系统(systemd 安装)

    sudo systemctl stop scylla-server
  • Docker 部署(注意:只停止容器内的 scylla 进程,而不停止容器本身):

    docker exec -it some-scylla supervisorctl stop scylla

    上面的some-scylla是容器名,需替换为你实际的容器名称。

三个步骤在所有节点上并行完成后,集群即处于完全停机状态,此时可以进行物理搬迁等操作。

drain 的底层原理(源码佐证)

从源码看,nodetool drain最终通过 HTTP REST API 触发服务端的 drain 逻辑。在 api/storage_service.cc 中:

static future<json::json_return_type> rest_drain(sharded<service::storage_service>& ss, std::unique_ptr<http::request> req) { apilog.info("drain"); return ss.local().drain().then([] { return make_ready_future<json::json_return_type>(json_void()); }); }

即调用storage_service::drain()完成核心工作。对应的 API 定义位于 api/api-doc/storage_service.json,同时暴露了两个端点:

  • /storage_service/drain(nickname:drain)——触发 drain;
  • 进度查询端点(nickname:get_drain_progress)——用于获取 drain 进度。

进度查询在 api/storage_service.cc 中实现,通过replica::database::get_drain_progress()汇总各 shard 的进度,并输出形如Drained {remaining_cfs}/{total_cfs} ColumnFamilies的进度信息:

future<json::json_return_type> rest_get_drain_progress(sharded<service::storage_service>& ss, std::unique_ptr<http::request> req) { return ss.map_reduce(adder<replica::database::drain_progress>(), [] (auto& ss) { return ss.get_database().get_drain_progress(); }).then([] (auto&& progress) { auto progress_str = format("Drained {}/{} ColumnFamilies", progress.remaining_cfs, progress.total_cfs); return make_ready_future<json::json_return_type>(std::move(progress_str)); }); }

从这段实现可以推断,drain 是一个逐 ColumnFamily(表)串行刷盘的过程:remaining_cfs表示尚未完成刷写的表数,total_cfs表示节点上表的总数,当两者相等时 drain 完成。这也解释了为什么文档要求在执行 drain 后必须确认其完成——如果表数量很大,drain 可能持续一段时间。

另外在 api/storage_service.cc 中可以看到drainget_drain_progress两个 REST 处理器是成对注册的,它们共用同一个 gating(gated),确保在节点 teardown 时先排空在途请求再关闭,进一步印证了"先优雅排空、再停止"的设计哲学。

重新启动集群(Safe Start 衔接)

安全停机之后的恢复流程记录在配套文档 Start Clusters Cleanly 中,它明确要求:启动前必须确认集群是按照 safe-shutdown 流程关闭的,否则应走正常的崩溃恢复路径。

启动步骤同样是并行执行:

  1. 并行启动各节点。根据 scylla-commands-start-index.rst:

    • 支持的操作系统:

      sudo systemctl start scylla-server
    • Docker 部署(容器已在运行的前提下):

      docker exec -it some-scylla supervisorctl start scylla
  2. 验证所有节点恢复正常:运行nodetool status,如果每个节点的状态都是UN(Up + Normal),则说明启动成功。

因为停机前已经通过 drain 将所有 memtable 落盘,节点重启时无需重放大量 commitlog,也不会有大量积压的流式修复,集群可以快速、平稳地回到UN状态。

常见误区与注意事项

  1. 不要把nodetool flushdrain:flush 只刷盘不切断服务,适合日常维护;drain 会停止监听客户端和节点间连接,执行后必须重启才能恢复服务,二者用途不可混淆。
  2. 不要在业务流量未摘除时 drain:drain 后节点立即停止接受读写,应用会报连接失败,务必先确认没有应用把集群当作后端存储。
  3. DN才是 drain 成功的标志:若 status 中节点仍显示UN,说明 drain 未完成或未生效,不应继续执行 stop,否则就退化为"非安全关机"。
  4. Docker 环境下停止的是容器内进程supervisorctl stop scylla只停 scylla 服务,容器本身保持运行,这也是为了便于后续用supervisorctl start scylla快速恢复。
  5. 集群恢复要验证到UN:不要以为节点进程起来了就算成功,必须以nodetool status中每个节点均为UN为准,确认节点间 gossip 正常、数据副本状态一致后再恢复应用流量。

小结

ScyllaDB 集群安全关机不是简单的"停服务",而是一套"先排空内存、再验证、后停止"的优雅停机流程:在每台节点上并行执行nodetool drain刷盘并切断连接 → 用nodetool status确认节点进入DN状态 → 按部署方式(systemd 或 Docker)停止服务 → 后续按 safe-start 流程并行启动并验证UN。结合 api/storage_service.cc 等源码可以看到,drain 本质上是逐 ColumnFamily 刷盘的受控过程,并配有专门的进度查询端点。掌握这一流程,可以在物理搬迁、计划维护等场景下把集群停机与重启的数据风险降到最低。

【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/15 22:15:34

CMake与XMake深度对比:C++构建系统的演进、差异与生态现实

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 22:14:59

企业办公用家用宽带凑合?这笔账到底怎么算

创业团队、小企业主、甚至有几年经营经验的老板&#xff0c;几乎都会在某个阶段动过这个念头&#xff1a;公司不就上个网、发个邮件、开个视频会议吗&#xff0c;家里那根宽带套餐便宜又快&#xff0c;为什么非得多花好几倍的钱去办企业专线&#xff1f;我见过太多公司在这个选…

作者头像 李华
网站建设 2026/9/15 22:14:55

网站风格一般具有哪三大特征从零搭建

告别模板丑站:网站风格三大特征对比评测与避坑指南 做网站最头疼的是什么?不是代码写不出来,而是做出来的东西看着像“五毛特效”,客户一看脸就黑。很多设计师转前端的朋友,手里攥着几张精美的UI图,结果一落地到Web,全是千疮百孔的模板味儿。这种 模板网站太丑不够用 的尴尬,咱们在行业里见得太多了。…

作者头像 李华
网站建设 2026/9/15 22:12:57

Python+Django美容院管理系统开发实战:从需求分析到部署交付

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/15 22:11:45

Flutter on OpenHarmony 实战:从架构原理到环境搭建的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华