完整指南: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 drainnodetool 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 drainnodetool 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 statusdrain 命令本身在正常完成后会正常返回但官方流程仍要求用nodetool status二次确认。判断标准非常明确如果节点状态被列为DN则说明 drain 命令已成功执行。理解DN的含义需要拆解 nodetool status 输出的两列标记Status 列U Up节点在线、D Down节点离线、X excluded已被removenode、excludenode或节点替换标记为永久丢失的宕机节点State 列N Normal、L Leaving、J Joining、M Moving。所以DN表示节点处于Down Normal节点已停止对外服务但状态正常并未处于离开/加入/移动等过渡状态这正是 drain 成功后节点应有的表现。而正常运行时节点应显示为UNUp Normal例如Datacenter: datacenter1 StatusUp/Down/eXcluded |/ StateNormal/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-serverDocker 部署注意只停止容器内的 scylla 进程而不停止容器本身docker exec -it some-scylla supervisorctl stop scylla上面的some-scylla是容器名需替换为你实际的容器名称。三个步骤在所有节点上并行完成后集群即处于完全停机状态此时可以进行物理搬迁等操作。drain 的底层原理源码佐证从源码看nodetool drain最终通过 HTTP REST API 触发服务端的 drain 逻辑。在 api/storage_service.cc 中static futurejson::json_return_type rest_drain(shardedservice::storage_service ss, std::unique_ptrhttp::request req) { apilog.info(drain); return ss.local().drain().then([] { return make_ready_futurejson::json_return_type(json_void()); }); }即调用storage_service::drain()完成核心工作。对应的 API 定义位于 api/api-doc/storage_service.json同时暴露了两个端点/storage_service/drainnicknamedrain——触发 drain进度查询端点nicknameget_drain_progress——用于获取 drain 进度。进度查询在 api/storage_service.cc 中实现通过replica::database::get_drain_progress()汇总各 shard 的进度并输出形如Drained {remaining_cfs}/{total_cfs} ColumnFamilies的进度信息futurejson::json_return_type rest_get_drain_progress(shardedservice::storage_service ss, std::unique_ptrhttp::request req) { return ss.map_reduce(adderreplica::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_futurejson::json_return_type(std::move(progress_str)); }); }从这段实现可以推断drain 是一个逐 ColumnFamily表串行刷盘的过程remaining_cfs表示尚未完成刷写的表数total_cfs表示节点上表的总数当两者相等时 drain 完成。这也解释了为什么文档要求在执行 drain 后必须确认其完成——如果表数量很大drain 可能持续一段时间。另外在 api/storage_service.cc 中可以看到drain与get_drain_progress两个 REST 处理器是成对注册的它们共用同一个 gatinggated确保在节点 teardown 时先排空在途请求再关闭进一步印证了先优雅排空、再停止的设计哲学。重新启动集群Safe Start 衔接安全停机之后的恢复流程记录在配套文档 Start Clusters Cleanly 中它明确要求启动前必须确认集群是按照 safe-shutdown 流程关闭的否则应走正常的崩溃恢复路径。启动步骤同样是并行执行并行启动各节点。根据 scylla-commands-start-index.rst支持的操作系统sudo systemctl start scylla-serverDocker 部署容器已在运行的前提下docker exec -it some-scylla supervisorctl start scylla验证所有节点恢复正常运行nodetool status如果每个节点的状态都是UNUp Normal则说明启动成功。因为停机前已经通过 drain 将所有 memtable 落盘节点重启时无需重放大量 commitlog也不会有大量积压的流式修复集群可以快速、平稳地回到UN状态。常见误区与注意事项不要把nodetool flush当drain用flush 只刷盘不切断服务适合日常维护drain 会停止监听客户端和节点间连接执行后必须重启才能恢复服务二者用途不可混淆。不要在业务流量未摘除时 draindrain 后节点立即停止接受读写应用会报连接失败务必先确认没有应用把集群当作后端存储。DN才是 drain 成功的标志若 status 中节点仍显示UN说明 drain 未完成或未生效不应继续执行 stop否则就退化为非安全关机。Docker 环境下停止的是容器内进程supervisorctl stop scylla只停 scylla 服务容器本身保持运行这也是为了便于后续用supervisorctl start scylla快速恢复。集群恢复要验证到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),仅供参考