ScyllaDB Nodetool getstreamthroughput 详解:查看 SSTables 流式传输吞吐上限
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
nodetool getstreamthroughput是 ScyllaDB 运维中用于查询当前节点 SSTables 流式传输(streaming)吞吐上限的命令。它直接读取节点上stream_io_throughput_mb_per_sec配置项的实时值,帮助运维人员确认限速是否生效、是否已按预期关闭,并可与setstreamthroughput配套完成"查询—调整—复验"的完整链路。读完本文,你将掌握该命令的语法、--mib选项背后的单位换算原理,以及从 nodetool 客户端到 REST API、再到流管理器与配置系统的完整调用链。
命令用途:确认流式传输的限速状态
在 ScyllaDB 中,"streaming" 指节点之间传输 SSTables 数据的过程,典型场景包括:
- 新节点加入集群(bootstrap)时的数据迁移;
- 节点退役(decommission)、移除节点(removenode)等拓扑变更;
- repair(修复)过程中跨节点的数据对账与补齐。
这些操作会进行大量顺序 I/O,可能占满网络带宽从而影响客户端 RPC 性能。为此,ScyllaDB 允许为 streaming 设置吞吐上限(throughput cap)。getstreamthroughput的作用就是打印系统中当前生效的 SSTables 流式传输吞吐上限:
If zero is printed, it means throughput is uncapped (如果输出为 0,表示吞吐未设置上限)
也就是说,输出0是正常的、合法的状态——它表示限速被禁用,streaming 不受吞吐约束;而非错误结果。这一设计保证运维人员可以通过返回值直观判断节点当前处于"限速"还是"不限速"状态。
语法与参数
nodetool [options] getstreamthroughput [--mib]其中[options]为 nodetool 通用选项(如指定连接主机、端口、认证信息等),[--mib]是该命令唯一的专属选项。
--mib选项:切换输出单位
| 选项 | 作用 | 输出示例(当上限为 100 MiB/s 时) |
|---|---|---|
| (不带选项) | 以**兆比特每秒(megabits per second, Mbit/s)**打印 | 838 |
--mib | 以MiB/s(每秒 Mebibyte,即 2^20 字节)打印 | 100 |
从源码 tools/scylla-nodetool.cc 可以清晰地看到两种输出路径的实现:
void getstreamthroughput_operation(scylla_rest_client& client, const bpo::variables_map& vm) { auto res = client.get("/storage_service/stream_throughput"); uint32_t throughput_mb_per_sec = res.GetInt64(); if (vm.contains("mib")) { fmt::print("{}\n", throughput_mb_per_sec); } else { fmt::print("{}\n", (((uint64_t)throughput_mb_per_sec) << 23) / 1'000'000); } }单位换算原理
值得注意,REST API/storage_service/stream_throughput返回的内部值throughput_mb_per_sec始终是MiB/s单位(见下文源码分析)。命令输出时:
- 指定
--mib:直接原样打印内部值,即 MiB/s; - 不指定
--mib:执行value * 2^23 / 1_000_000转换为兆比特每秒。其中左移 23 位相当于乘以 2^23(即 1 MiB = 2^20 字节 = 2^23 位),把 MiB/s 换算成 bit/s,再除以 1,000,000 得到十进制兆位(Mbit/s)。
因此两者不是简单的 8 倍关系,而是二进制前缀(MiB,2^23 bit)与十进制前缀(Mbit,10^6 bit)之间的换算。实际使用中,若想直接得到与配置文件一致的数值,推荐加--mib参数查看;若习惯网络带宽的 Mbit/s 口径,则可不加参数。
该命令在 nodetool 中的注册信息位于 tools/scylla-nodetool.cc,帮助文本为 "Print throughput cap for streaming in the system in megabits",其typed_option<>("mib", ...)描述为 "Print the throughput cap for streaming in MiB/s"。
调用链源码剖析:从命令到配置的完整路径
getstreamthroughput虽然只是一条查询命令,但其背后贯穿了 nodetool 客户端、HTTP REST API、流管理器(stream_manager)和配置系统四个层面,理解这条链路有助于排查"查询值与实际限速不符"的问题。
第一层:nodetool 客户端发起 REST 请求
如上所示,getstreamthroughput_operation通过 scylla_rest_client 向本地节点的/storage_service/stream_throughput端点发起 HTTP GET 请求,并解析返回的整数值。
第二层:REST API 处理器读取流管理器状态
该端点的 GET 处理器定义在 api/stream_manager.cc:
ss::get_stream_throughput_mb_per_sec.set(r, &sm { auto value = sm.local().throughput_mbs(); return make_ready_future<json::json_return_type>(value); });它调用本 shard 上stream_manager的throughput_mbs()方法获取当前限速值。对应的 API 描述(含 GET/POST 两种方法、type: long)记录在 api/api-doc/storage_service.json 中,nickname 为get_stream_throughput_mb_per_sec。
第三层:stream_manager 持有可热更新的配置值
stream_manager在构造时从数据库配置中取得初始值,并保存为一个支持热更新的值对象:
- 构造处(streaming/stream_manager.cc):
_io_throughput_mbs(cfg.stream_io_throughput_mb_per_sec) - 读取方法(streaming/stream_manager.hh):
uint32_t throughput_mbs() const noexcept { return _io_throughput_mbs.get(); }_io_throughput_mbs的类型是utils::updateable_value<uint32_t>(见 streaming/stream_manager.hh),意味着当配置在运行时被修改后,这里读到的值会同步更新——这正是getstreamthroughput总是返回当前实时生效值的原因。
第四层:配置项与运行时更新入口
底层配置项定义在 db/config.cc:
, stream_io_throughput_mb_per_sec(this, "stream_io_throughput_mb_per_sec", liveness::LiveUpdate, value_status::Used, 0, "Throttles streaming I/O to the specified total throughput (in MiBs/s) across the entire system. Streaming I/O includes the one performed by repair and both RBNO and legacy topology operations such as adding or removing a node. Setting the value to 0 disables stream throttling. It is recommended to set the value for this parameter to be 75% of network bandwidth")关键事实:
- 默认值为
0,即默认不限速; - 该配置为
liveness::LiveUpdate,支持运行时热更新; - 限速范围覆盖整个系统的 streaming I/O,包括 repair,以及 RBNO 与 legacy(旧式)拓扑操作(如增删节点)中的流式传输;
- 配置注释明确建议:该参数值设置为网络带宽的 75%较为合适。
而setstreamthroughput之所以能热更新限速值,正是因为它的 REST 处理器(api/config.cc)会将新值写回配置系统:
ss::set_stream_throughput_mb_per_sec.set(r, &cfg mutable { api::req_param<uint32_t> value(*req, "value", 0); cfg.stream_io_throughput_mb_per_sec(value.value, utils::config_file::config_source::API); return make_ready_future<json::json_return_type>(json::json_void()); });由此形成完整闭环:setstreamthroughput写入配置 →stream_manager的值对象热更新 →getstreamthroughput读出最新值。
典型使用场景
场景一:确认限速是否生效
$ nodetool getstreamthroughput --mib 0输出0表示当前未限速。若此前通过setstreamthroughput设置了限速,此处应输出对应数值。
场景二:以网络带宽口径查看
$ nodetool getstreamthroughput 838当内部限速为 100 MiB/s 时,不带--mib输出约838(100 × 2^23 / 10^6 ≈ 838.86),表示约 838 Mbit/s。
场景三:与 setstreamthroughput 配套使用
getstreamthroughput与setstreamthroughput是一对配套命令。设置命令的语法为(详见 setstreamthroughput 文档):
nodetool [options] setstreamthroughput <value_in_mb>设置0同样表示禁用限速。典型运维流程为:
# 1. 查看当前限速状态 nodetool getstreamthroughput --mib # 2. 设置限速(假设 200 MiB/s) nodetool setstreamthroughput 200 # 3. 复验是否生效 nodetool getstreamthroughput --mib 200两条命令均作用于同一底层配置stream_io_throughput_mb_per_sec,因此getstreamthroughput是验证setstreamthroughput是否生效的最直接手段。
注意事项与最佳实践
- 0 的含义:输出
0代表"未设置上限",不是故障。若希望为 streaming 限速以保护客户端 RPC 性能,需主动通过setstreamthroughput或配置stream_io_throughput_mb_per_sec设置非零值。 - 单位口径:默认输出为 Mbit/s(十进制兆位),
--mib输出为 MiB/s;两者换算系数为 2^23 / 10^6,而非简单的 8 倍。与配置文件数值对比时建议使用--mib。 - 限速范围:该限速覆盖整个系统的 streaming I/O(repair、RBNO 及 legacy 拓扑变更),属于节点级全局限速。
- 推荐取值:官方配置注释建议将
stream_io_throughput_mb_per_sec设置为网络带宽的 75%,可作为初始调优参考;实际应结合集群网络状况观察客户端延迟后微调。 - 运行时生效:由于配置支持热更新(LiveUpdate),
getstreamthroughput查询到的始终是当前实时值,无需重启节点。
相关文档
- Nodetool setstreamthroughput(配套的设置命令)
- Nodetool 命令总索引(原文档通过 include 引入命令列表)
- 底层配置项定义:db/config.cc
- nodetool 客户端实现:tools/scylla-nodetool.cc
- REST API 处理器:api/stream_manager.cc、api/config.cc
- 流管理器实现:streaming/stream_manager.cc、streaming/stream_manager.hh
- API 描述文件:api/api-doc/storage_service.json
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考