
ScyllaDB Nodetool rebuild 命令完全指南跨数据中心数据重建与 RBNO 修复机制【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladbrebuild是 ScyllaDB 中一条重要的节点运维命令用于通过流式传输streaming从集群中其他节点重建本节点的数据其行为与 bootstrap加入集群时的数据初始化类似。本指南以官方文档 docs/operating-scylla/nodetool-commands/rebuild.rst 为骨架结合仓库源码深入解析其工作流程、--force与source-dc参数语义、RBNORepair Based Node Operations模式下的修复式重建实现以及 vnode 与 tablet keyspace 的适用性差异。读完本文你将掌握nodetool rebuild的正确使用场景、参数含义与底层原理能够安全地在新数据中心接入、本地数据丢失恢复等场景中执行该命令。命令概述nodetool rebuild的完整语法为nodetool rebuild [[--force] source-dc-name]它通过从集群中其他节点流式传输数据来重建一个节点的数据工作方式与 bootstrap 相似。从 tools/scylla-nodetool.cc 的命令注册可以看到rebuild 支持两个参数--force即使使用 source_dc 选项不安全也强制使用该选项执行 rebuildsource-dc位置参数默认 any DC指定从哪个数据中心流式传输数据。scylla-nodetool在收到命令后会构造 REST API 请求将参数原样传给 ScyllaDB 的 HTTP 接口void rebuild_operation(scylla_rest_client client, const bpo::variables_map vm) { std::unordered_mapsstring, sstring params; if (vm.contains(source-dc)) { params[source_dc] vm[source-dc].assstring(); } if (vm.contains(force)) { params[force] true; } client.post(/storage_service/rebuild, std::move(params)); }对应的服务端入口位于 api/storage_service.cc它调用ss.local().rebuild(std::move(source_dc))进入 service/storage_service.cc 中的核心实现。注意本仓库的 nodetool 实现基于 ScyllaDB 自带的scylla-nodetooltools/scylla-nodetool.cc命令最终通过 REST APIPOST /storage_service/rebuild而不是 JMX 触发这是 ScyllaDB 与 Apache Cassandra 在工具实现上的一个差异点。执行流程ScyllaDB 如何找到数据源当执行该命令时ScyllaDB 会按以下步骤工作确定本节点负责的 token 范围rangesScyllaDB 首先计算待重建节点本地节点当前负责的 token 范围寻找包含相同范围的节点确定集群中哪些节点持有这些相同 token 范围的数据副本流式传输数据从数据源节点将对应范围的数据流式传输到本地节点。在非 RBNO 模式下重建每个 token range 时数据是从**单个源副本single source replica**流式传输的。从源码看storage_service::rebuild()首先检查是否存在 tablet 启用的 keyspace见下文“与 tablet keyspace 的关系”一节然后调用raft_rebuild()future storage_service::rebuild(utils::optional_param source_dc) { return run_with_api_lock(sstring(rebuild), [source_dc] (storage_service ss) - future { if (auto tablets_keyspaces ss._db.local().get_tablets_keyspaces(); !tablets_keyspaces.empty()) { std::ranges::sort(tablets_keyspaces); slogger.warn(Rebuild is not supported for the following tablets-enabled keyspaces: {}: ..., tablets_keyspaces); } co_await ss.raft_rebuild(source_dc); }); }在raft_rebuild()service/storage_service.cc中ScyllaDB 会通过 group0/raft 向拓扑状态机提交一个topology_request::rebuild请求并在请求中携带rebuild_option即source_dc若带--force则会以source_dc:force的形式编码sstring source_dc sdc_param.value_or(); if (sdc_param.force() !source_dc.empty()) { source_dc :force; } builder.with_node(raft_server.id()) .set(topology_request, topology_request::rebuild) .set(rebuild_option, source_dc) .set(request_id, guard.new_group0_state_id());同时raft_rebuild()还包含几个重要的前置校验本地节点必须已是集群成员否则抛出 “local node is not a member of the cluster”本地节点状态必须是normal本地节点必须拥有 token无 token 时仅记录警告并跳过冗余 rebuild集群中至少要有 2 个 normal 节点否则抛出 “Cannot rebuild a single node”。请求提交后raft_rebuild()会通过wait_for_topology_request_completion()等待重建任务完成若失败则抛出包含错误信息的异常。这也印证了文档中的要点rebuild 由拓扑协调器驱动最终在目标节点上执行流式传输任务。source-dc 参数与 --force 的语义nodetool rebuild支持指定数据源数据中心若提供了source-dc-nameScyllaDB 将仅从该数据中心的节点流式传输数据在安全的前提下否则ScyllaDB 会考虑一个没有丢失节点的替代数据中心如果不存在这样的替代数据中心则考虑所有数据中心使用--force选项可以强制使用指定的 source datacenter即使这样做不安全。“不安全”的典型场景包括指定的源数据中心自身有节点不可达down此时从中重建可能无法获得完整、一致的数据。服务端在收到--force后会将force: true作为参数传入随后在raft_rebuild()中编码为source_dc:force提交给拓扑执行重建的节点在 service/storage_service.cc 中解析该标记case node_state::rebuilding: { auto source_dc std::getrebuild_param(_topology_state_machine._topology.req_param[id]).source_dc; ... utils::optional_param sdc_param; bool force; if ((force source_dc.ends_with(:force))) { source_dc.resize(source_dc.size() - 6); } if (!source_dc.empty()) { sdc_param.emplace(source_dc).set_user_provided().set_force(force); } ... }对应地nodetool 工具与 REST 层的参数传递在测试中有明确的断言参见 test/nodetool/test_rebuild.pytest_rebuild不带参数期望请求POST /storage_service/rebuild无参数test_rebuild_source_dcnodetool rebuild UNKNOWN_DC期望参数source_dcUNKNOWN_DCtest_rebuild_force_source_dcnodetool rebuild --force UNKNOWN_DC期望参数forcetrue与source_dcUNKNOWN_DCtest_rebuild_force_no_source_dcnodetool rebuild --force期望参数forcetrue不带 source_dc。RBNO 模式Repair-Based Rebuild文档指出当在 Repair Based Node Operations (RBNO) 中启用 rebuild 时数据通过repair-based-rebuild重建即读取每个 token range 的所有源副本并修复它们之间的任何差异discrepancies。否则重建每个 token range 时数据从单个源副本流式传输。源码中的分支逻辑位于 service/storage_service.ccif (is_repair_based_node_ops_enabled(streaming::stream_reason::rebuild)) { co_await _repair.local().rebuild_with_repair(std::move(ks_erms), tmptr, std::move(sdc_param), session); } else { auto streamer make_lw_shareddht::range_streamer(_stream_manager, tmptr, _abort_source, ...); streamer-add_source_filter(std::make_uniquedht::range_streamer::failure_detector_source_filter(_gossiper.get_unreachable_members())); if (source_dc ! ) { streamer-add_source_filter(std::make_uniquedht::range_streamer::single_datacenter_filter(source_dc)); } for (const auto [keyspace_name, erm] : ks_erms) { auto ranges co_await get_ranges_for_endpoint(*erm, my_host_id()); co_await streamer-add_ranges(keyspace_name, erm, std::move(ranges), _gossiper, false); } co_await streamer-stream_async(); }两种模式的关键区别维度流式传输模式默认RBNOrepair-based rebuild数据源每个 token range 从单个源副本流式传输读取每个 token range 的所有源副本并修复差异可靠性依赖源副本数据的完整性多副本交叉校验更稳健、更安全RBNO 文档的定位实现路径dht::range_streamer 流式传输repair_service::rebuild_with_repairrepair/repair.cc启用方式默认通过 RBNO 配置项启用在流式传输模式下源码还通过failure_detector_source_filter过滤掉 gossip 中不可达的节点这正对应文档中“替代数据中心/全部数据中心”的选取逻辑——不可达节点所在的数据中心会被视为“不安全”而避开。在 RBNO 模式下rebuild_with_repair()首先确认this_shard_id() 0修复协调在 shard 0 上执行若未显式指定 source_dc 则默认取本节点所在的数据中心const auto topology tmptr-get_topology(); if (!source_dc) { source_dc utils::optional_param(topology.get_datacenter()); }随后调用通用的do_rebuild_replace_with_repair()执行逐 range 的修复式重建并在完成后触发所有非系统表的 off-strategy compactiontrigger_offstrategy_compaction()确保重建进来的数据在后台被正确压缩整理。如何启用 RBNO 模式下的 rebuildRBNO 的启用方式详见 docs/operating-scylla/procedures/cluster-management/repair-based-node-operation.rst核心配置项包括enable_repair_based_node_opstrue|false总开关启用或禁用 RBNO指定为哪些节点操作启用 RBNO 机制的配置项rebuild、replace、decommission、removenode 等操作可分别配置。典型使用场景向已有集群添加新数据中心文档明确给出一个典型场景向已有的 ScyllaDB 集群添加新的数据中心DC时应使用 rebuild 命令。详细步骤参见 docs/operating-scylla/procedures/cluster-management/add-dc-to-existing-dc.rst。基本用法示例nodetool rebuild source-dc-name例如假设新数据中心的节点需要从已有的dc1拉取数据nodetool rebuild dc1新增 DC 后新节点会获得由NetworkTopologyStrategy分配的新 token 范围而这些范围的数据原本不存在于该节点上因此需要执行 rebuild 从源 DC 的副本节点流式传输数据。这也是 rebuild 与 bootstrap 最大的不同bootstrap 在新节点加入时就完成了范围分配与数据流式传输而 rebuild 用于已加入的节点在获得新范围后补齐数据。后台运行特性文档特别提醒ScyllaDB 的 rebuild 过程会继续在后台运行即使 nodetool 命令被杀掉或中断。这与源码实现一致nodetool 只是通过 REST APIPOST /storage_service/rebuild发起请求实际的拓扑请求与流式传输任务由 ScyllaDB 服务端storage_service的raft_rebuild 拓扑协调器接管并作为后台任务持续执行。因此运维人员不应通过“杀掉 nodetool 进程”来中止 rebuild而应通过nodetool netstats查看流式传输进度等手段观察其进展。与 tablet keyspace 的关系重要限制文档明确指出nodetool rebuild命令只适用于 vnode keyspace。对于 tablet keyspace应改用nodetool cluster repair。源码在 service/storage_service.cc 中对此做了显式处理——当存在 tablet 启用的 keyspace 时会记录一条警告日志“Rebuild is not supported for the following tablets-enabled keyspaces: ... Rebuild is not required for tablets-enabled keyspace after increasing replication factor. However, recovering from local data loss on this node requires running repair on all nodes in the datacenter”也就是说对 tablet keyspace提高副本因子replication factor后无需执行 rebuildtablet 负载均衡会自动处理新副本的数据迁移若 tablet keyspace 发生本地数据丢失需要在该数据中心的所有节点上运行 repair 来恢复而不是 rebuild。关于 tablet 与 vnode 的数据分布差异可进一步阅读 docs/architecture/tablets.rst文档中引用为 Data Distribution with Tablets。使用建议与注意事项综合文档与源码使用nodetool rebuild时的实践建议如下确认 keyspace 类型执行前先确认目标节点上的 keyspace 是否为 vnode 模式若包含 tablet keyspace则按上文说明改用nodetool cluster repair明确数据源 DC多数据中心环境下尽量显式指定source-dc-name避免 ScyllaDB 自动选择替代 DC 或全集群数据源带来的额外跨 DC 流量谨慎使用--force只有在明确了解源 DC 存在不可达节点风险、且接受可能的数据不一致时才使用--force不要中断命令进程rebuild 在后台持续运行杀掉 nodetool 进程不会中止重建结合 RBNO对数据一致性要求高的场景可启用 RBNO 使 rebuild 走 repair-based 路径从所有源副本交叉校验数据观察进度通过nodetool netstats观察流式传输进度确认重建完成。总结nodetool rebuild是 ScyllaDB 在“节点数据补齐”场景下的核心运维命令它先确定本地节点的 token 范围与持有相同范围的远端节点再通过流式传输默认单副本源或 RBNO 修复式重建多副本交叉校验将数据补齐。source-dc控制数据源数据中心--force则允许在不安全的情况下强制使用指定 DC。理解其背后的 topology 请求机制service/storage_service.cc、流式传输与 RBNO 双路径service/storage_service.cc、repair/repair.cc以及 vnode/tablet 的适用性差异是正确、安全使用该命令的关键。【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考