ScyllaDB nodetool proxyhistograms 命令详解:解析协调者延迟直方图与慢操作诊断
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
导读
nodetool proxyhistograms是 ScyllaDB 提供的一项节点诊断命令,用于输出由协调者(coordinator)记录的各类请求延迟直方图,帮助运维人员在节点操作变慢时快速定位读、写、范围扫描等路径上的延迟分布。本文以官方文档 docs/operating-scylla/nodetool-commands/proxyhistograms.rst 为主体,结合 tools/scylla-nodetool.cc 的实现、api/api-doc/storage_proxy.json 的 REST API 定义以及 test/nodetool/test_proxyhistograms.py 的测试用例,系统讲解命令输出格式、百分位含义、底层数据来源与实战解读方法。
命令概述与适用场景
proxyhistograms命令的作用是:提供由协调者记录的延迟请求(latency request)统计。ScyllaDB 采用去中心化架构,任何节点都可以作为请求的协调者,负责将读写请求路由到持有数据的副本节点并汇总结果。因此,"协调者视角"的延迟包含网络往返、副本处理、协调与聚合等完整链路开销,能真实反映客户端实际感受到的端到端延迟。
官方文档明确指出该命令的典型适用场景:
This command is helpful if you encounter slow node operations.
即当节点出现慢操作(慢查询、慢写入、范围扫描耗时异常)时,proxyhistograms可以帮助判断延迟主要集中在哪一类操作上,是后续进一步排查(如查看 Compaction、GC、热点分区等)的入口。在 tools/scylla-nodetool.cc 中,该命令注册的描述为"Print statistic histograms for network operations",帮助文本与文档一致。
基本用法与输出格式
在 ScyllaDB 节点上直接执行(无需额外参数):
nodetool proxyhistograms输出示例(来自官方文档):
proxy histograms Percentile Read Latency Write Latency Range Latency (micros) (micros) (micros) 50% 353.50 1214.50 4103.00 75% 972.50 2969.25 5073.25 95% 4832.85 15394.80 14981.50 98% 8181.18 21873.00 27640.50 99% 8356.63 21873.00 31843.79 Min 22.00 207.00 499.00 Max 8365.00 21873.00 208960.00所有延迟单位均为微秒(micros)。输出由若干行组成:
| 行 | 含义 |
|---|---|
50% | 中位数延迟,50% 的请求低于该值 |
75% | 75% 分位延迟 |
95% | 95% 分位延迟(P95) |
98% | 98% 分位延迟(P98) |
99% | 99% 分位延迟(P99) |
Min | 采样到的最小延迟 |
Max | 采样到的最大延迟 |
列的含义
官方文档给出的参数说明如下:
| 参数 | 描述 |
|---|---|
| Percentile | 延迟排名(latency rank),即百分位 |
| Read Latency | 读延迟 |
| Write Latency | 写延迟 |
| Range Latency | 该节点的范围扫描(Range scan)延迟 |
命令实现与真实输出列(源码级解析)
需要特别说明的是:当前仓库中的proxyhistograms实现输出的列比官方文档示例更多。查看 tools/scylla-nodetool.cc 中proxyhistograms_operation的实现,它依次从 REST API 拉取 6 组直方图数据:
Read Latency:来自/storage_proxy/metrics/read/moving_average_histogramWrite Latency:来自/storage_proxy/metrics/write/moving_average_histogramRange Latency:来自/storage_proxy/metrics/range/moving_average_histogramCAS Read Latency:来自/storage_proxy/metrics/cas_read/moving_average_histogramCAS Write Latency:来自/storage_proxy/metrics/cas_write/moving_average_histogramView Write Latency:来自/storage_proxy/metrics/view_write/moving_average_histogram
也就是说,实际执行时输出为 6 列,形如:
proxy histograms Percentile Read Latency Write Latency Range Latency CAS Read Latency CAS Write Latency View Write Latency (micros) (micros) (micros) (micros) (micros) (micros) 50% 32.00 31.50 32.00 33.00 33.00 4.00 ...其中:
- CAS Read / CAS Write Latency:轻量级事务(Compare-And-Set / LWT,基于 Paxos)的读、写延迟;
- View Write Latency:物化视图(Materialized View)异步更新写入的延迟。
该 6 列输出与测试用例 test/nodetool/test_proxyhistograms.py 中断言的标准输出完全一致,测试同时验证了 6 个 REST API 端点的调用顺序与响应解析逻辑。
百分位计算:buffer_samples
输出中的百分位值并非直接来自服务端,而是由客户端对采样样本计算得出。tools/scylla-nodetool.cc 中的buffer_samples类(注释标明其实现参考了 Apache Cassandra 的org.apache.cassandra.tools.NodeProbe.BufferSamples)完成这一工作:
retrieve_from_api向指定 REST 路径发起 GET 请求,从响应的hist.sample字段取出原始延迟样本数组;- 构造函数对样本进行升序排序;
value(quantile)采用线性插值法计算指定分位数:pos = quantile * (samples.size() + 1),若pos落在两个相邻样本之间,则按比例线性插值(见 tools/scylla-nodetool.cc);min()与max()分别返回排序后样本的首尾元素;- 当样本为空时,
min/max/value均返回0.0。
命令主循环对{0.5, 0.75, 0.95, 0.98, 0.99}五组百分位逐一计算并格式化输出(tools/scylla-nodetool.cc),随后输出Min、Max两行。
数据来源:协调者延迟直方图与移动平均
proxyhistograms展示的是moving average(移动平均)直方图,数据由 ScyllaDB 协调者(storage_proxy 层)在服务请求时持续记录。可以从以下两个层面印证:
1. REST API 定义
api/api-doc/storage_proxy.json 中定义了/storage_proxy/metrics/read/moving_average_histogram等 6 个端点(write、range、cas_read、cas_write、view_write 同理),响应结构为rate_moving_average_and_histogram,包含吞吐率(meter)与直方图(hist)两部分。
2. 底层直方图实现
服务端使用 utils/histogram.hh 中的定时器指标类采集延迟:
timed_rate_moving_average_and_histogram:聚合时序持续时间并提供持续时间统计与吞吐统计(utils/histogram.hh);timed_rate_moving_average_summary_and_histogram:统一封装直方图、速率与摘要,其注释明确说明"The API requires a moving average and its kind of histogram (ihistogram)",即 API 层需要移动平均与直方图数据(utils/histogram.hh)。
在 replica/database.hh 中可以看到协调者相关统计成员,包括reads、writes、cas_prepare、cas_accept、cas_learn等直方图对象,这些正是 CAS 读/写延迟与普通读/写延迟的数据来源。
使用注意与输出解读
空直方图场景
当节点近期没有对应类型的请求时,直方图样本为空,所有百分位与 Min/Max 均显示0.00。测试用例 test/nodetool/test_proxyhistograms.py 专门验证了空直方图场景,期望输出全部为0.00:
Percentile Read Latency Write Latency Range Latency CAS Read Latency CAS Write Latency View Write Latency (micros) (micros) (micros) (micros) (micros) (micros) 50% 0.00 0.00 0.00 0.00 0.00 0.00 ... Max 0.00 0.00 0.00 0.00 0.00 0.00输出解读要点
- 关注 P95/P99 与 Min/Max 的差距:若 P99 远高于 P50,说明存在明显的长尾延迟,可能有热点分区、Compaction 干扰或慢副本;
- 对比三类延迟:读、写、范围扫描分别对应不同的底层路径,范围扫描延迟偏高往往与宽分区、索引扫描或全表扫描有关;
- CAS 延迟与 View 延迟:若业务使用了 LWT(
INSERT ... IF NOT EXISTS等)或物化视图,这两列能直观反映其额外协调开销,CAS 延迟高通常意味着 Paxos 多轮 RTT 开销或提案冲突; - 数值为协调者视角:包含网络与副本等待,因此通常高于单副本本地延迟指标(如
cfstats中的本地读延迟),两者对比可帮助区分瓶颈在协调层还是副本层。
运行前提
- 命令由 ScyllaDB 自带的管理工具
scylla-nodetool提供(实现位于 tools/scylla-nodetool.cc),通过 REST API 与本地 ScyllaDB 进程交互,执行时无需额外参数; - 底层数据由协调者(storage_proxy)在服务请求期间持续累积,节点启动后无请求则显示全 0;
- 直方图样本为移动平均窗口内的采样数据(采样掩码默认
0x80,见 utils/histogram.hh),反映的是近期窗口的延迟分布而非自启动以来的累计分布。
与其他诊断命令的配合
nodetool cfstats:查看单个表的本地读写延迟与 SSTable 统计,与proxyhistograms的协调者视角互补;nodetool tpstats:查看线程池待处理/丢弃任务,判断是否因队列堆积导致协调者延迟上升;nodetool proxyhistograms定位到具体慢操作类型后,可结合 ScyllaDB 指标(如 per-shard 直方图)进一步下钻到副本与分片级别。
小结
nodetool proxyhistograms是 ScyllaDB 排查节点慢操作的首选诊断命令:它从协调者视角输出读、写、范围扫描、CAS 读写与视图写入 6 类延迟的百分位直方图,数据经 REST API(/storage_proxy/metrics/*/moving_average_histogram)获取并由客户端buffer_samples做排序与线性插值计算。理解输出中的每一列与百分位含义,结合底层直方图实现(utils/histogram.hh),即可在慢节点场景下快速定位延迟瓶颈所在的操作类型。
【免费下载链接】scylladbNoSQL data store using the Seastar framework, compatible with Apache Cassandra and Amazon DynamoDB项目地址: https://gitcode.com/GitHub_Trending/sc/scylladb
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考