ClickHouse performance.ci API 参考:基于 REST 接口与 Dashboard 的 PR 性能回归分析指南
ClickHouse performance.ci API 参考基于 REST 接口与 Dashboard 的 PR 性能回归分析指南【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse在 ClickHouse 开源仓库的日常开发中评估一个 PR 是否引入性能回归需要回答一个核心问题这个性能结果是真实的、还是噪声/偶发、抑或是 master 历史上已知的波动ci-api.md 正是为回答该问题而编写的performance.ciAPI 与 Dashboard 操作参考——它系统性地覆盖了 Run 发现、Run 概览、置信度、趋势/历史、覆盖率/PR 交集、火焰图、master 状态统计以及 CI 产物兜底等全部数据通道。阅读完本文你将掌握以performance.ci.clickhouse.com/api/v1为基址的完整 HTTP 调用模式并能结合仓库内的辅助脚本 perf_api.py 与判定规则 verdict-rules.md对任意 PR 的性能结果给出有据可查的结论。数据源优先级先看 Dashboard/API再看历史与产物该参考文档是 perf-comparison 技能SKILL.md的组成部分。技能层面对数据源规定了严格的优先级理解这一点才能正确使用本文的各个 APIperformance.ci API/Dashboard 优先用于当前 PR 的 Run 列表、变更行清单changed-row inventory、置信度、查询详情、趋势/历史图、覆盖率交集与 flamegraph-diff。ClickHouse Playdefault.checks表当需要对每一行变更统计过去 30 天 master 上同样测试/查询出现slower/faster/unstable的次数时使用。CI 产物/日志仅在 Dashboard/API 无法提供根因数据时兜底例如 server 日志、raw trace、raw ProfileEvents TSV、精确二进制版本/build ID。本地perf.py仅在显式提供 old/new 二进制并做本地验证时使用且必须声明不等价于 CI。这种证据阶梯evidence ladder的设计保证了每个结论都建立在最可靠的数据源上raw 产物永远只是 artifact fallback evidence不能反过来覆盖 Dashboard 的分类结果。API 基础基址与 Run 发现所有接口共用一个基址BASEhttps://performance.ci.clickhouse.com/api/v1查找某个 PR 的全部性能 RunPR104350 curl -fsS $BASE/runs?q$PR | jq .返回的items[]中每个元素代表一次完整的性能对比 Run文档要求重点关注以下身份与摘要字段字段含义identity.runIdRun 的唯一标识后续所有/runs/$RUN_ID/...接口的参数identity.prNumber关联的 PR 编号identity.oldSha基线master/参考二进制 commit SHAidentity.newSha候选被测试 PR二进制 commit SHAidentity.runTimeRun 的执行时间arches本次 Run 覆盖的架构如amd、armchangedQueries判定为已变更的查询数slowdownQueries变慢查询数speedupQueries加速改善查询数unstableQueries高噪声/不稳定查询数重要约定搜索可能返回超出预期的结果必须始终用identity.prNumber PR二次过滤。辅助脚本中对应的过滤逻辑可参考 perf_api.py 的fetch_pr_runs()。实测中观察到的 API 陷阱参考文档专门记录了 live testing 中发现的四条 caveat直接决定数据如何解读unstableQueries[]可能包含高噪声/高阈值行即使汇总卡片显示Unstable queries: 0。它们应被当作 flakiness/噪声上下文除非同时超过阈值否则不应视为 changed rows。当fileSetintersecting无交集文件时totals.intersectingFiles可能被省略此时回退用len(files)作为零交集计数。趋势响应中的selectedRunPoint.value可能是标记用的0该 PR 的真实测量值应以 query detail 的 old/new 值为准。Flamegraph 端点即使在查询确实变更时也可能返回 404——缺少 flamegraph 数据不代表任何方向既不能证明有变化也不能证明是噪声。Run 概览一次 Run 的完整对比清单拿到runId后首先获取该 Run 的概览。通过metrics参数可以控制返回哪些指标维度惯例为client_time,real_time,cpu_time,memorycurl -fsS $BASE/runs/$RUN_ID?metricsclient_time,real_time,cpu_time,memory | jq .值得使用的顶层结构slowdowns[]—— 判定变慢的对比行speedups[]—— 判定改善的对比行unstableQueries[]—— 高噪声/高阈值行testSummaries[]—— 各测试摘要assets[]、reports[]—— 关联的产物与报告ComparisonRow 字段每一条变更对比行的核心字段如下字段含义test性能测试名对应tests/performance/*.xml的测试文件基名queryIndex测试内的查询序号queryDisplayName查询展示名metric指标名client_time/real_time/cpu_time/memory等arch架构amd/armoldValue基线测量值newValue候选测量值diffPercent变化百分比statThreshold统计判定阈值direction方向slowdown/speedupseverity严重度confidence置信度信息数值单位陷阱在已观察到的示例中API 的diffPercent与statThreshold以小数/分数形式返回——例如0.232表示约23.2%。不确定展示格式时应按分数处理并在展示时转换为百分比。这一点在 perf_api.py 的change_pct()中同样被注释为Observed API values are fractional。判断一行是否超过阈值参考脚本采用abs(diffPercent) 1e-6 abs(statThreshold)容忍二进制/十进制舍入误差见 perf_api.py。Confidence置信度如何把 raw change 转化为可对外表述的证据Confidence 模块回答这一行变更到底可信多少。它可以按 Run 或按单个 Test 拉取# Run 级置信度 curl -fsS $BASE/runs/$RUN_ID/confidence?metricsclient_time,real_time,cpu_time,memory | jq . # Test 级置信度更常用 curl -fsS $BASE/runs/$RUN_ID/tests/$TEST/confidence?metricsclient_time,real_time,cpu_time,memory | jq .使用规范写入报告时必须遵守始终汇报confidence.tier与confidence.reason当存在时。模块细节使用modules[].title、modules[].status、modules[].interpretation以及有用的modules[].rows[]事实。严禁把M1:downgrade, M2:neutral这类 Dashboard 内部简写直接写进报告——那只是内部代号不是面向评审的结论。辅助脚本在 perf_api.py 中会对 speedup 行做措辞校正不打印 slowdown/regression 语义。对 speedup 行要格外小心当前 tier 名称/原因可能以 slowdown 为导向不要在加速行上打印confirmed_regression只有当周边证据支持时才称之为 stable speedup/change。推荐的对外表述示例tiernoise; reasonchange is smaller than recent-history adaptive threshold; History Adaptive Threshold downgraded because observed 47.2% adaptive 94.8%.Test 与 Query 详情定位到具体查询与火焰图资产从 Run 概览定位到可疑的(test, queryIndex, metric, arch)组合后下钻到最细粒度# 单个 Test 详情 curl -fsS $BASE/runs/$RUN_ID/tests/$TEST?metricsclient_time,real_time,cpu_time,memory | jq . # 单个 Query 详情最常用 curl -fsS $BASE/runs/$RUN_ID/tests/$TEST/queries/$QUERY_INDEX?metricsclient_time,real_time,cpu_time,memory | jq .Query detail 是证据收集的核心入口用于采集queryText—— 实际执行的 SQL 文本该查询的全部 metric rows跨 arch/方向flamegraphAssets—— 火焰图资产引用report links。结合 perf_api.py 的cmd_query()实现可以看到脚本正是通过该端点过滤 metric 与 arch 后输出匹配的 metric 行表格并据此进一步拼接 confidence/trend/history/coverage/flamegraph-diff 参数。Trend 与 History用历史分布判断越界还是噪声单次 PR Run 的数值没有意义必须放进历史分布中解读。文档提供两个互补接口# 选定 Run 附近的趋势 curl -fsS $BASE/runs/$RUN_ID/tests/$TEST/trend?metric$METRICqueryIndex$QUERY_INDEXarch$ARCH | jq . # 更长历史 curl -fsS $BASE/history/$TEST/$QUERY_INDEX?metric$METRICarch$ARCH | jq .可用结构points[]/centerTrend[]正常散布与选定 Run 的上下文changePoints[]已知的历史跳变点periodComparisons[]较大的历史区间变化。报告必须满足的摘要形状趋势/历史部分仅给 min/max 是不合格的。规范的摘要必须包含说明 points 覆盖的时间段给出分位数而不仅是 min/maxp05/p25/p50/p75/p95展示近期窗口的散布例如最近 30 个点及其时间跨度把选定 Run 的 old/new 值分别与p50、p95对比对 change points 去重列出最近相关条目的日期/方向/SHA。例如 verdict-rules.md 中给出的合格措辞模板History center trend: 976 points over 2026-04-24 → 2026-06-15; all p05/p50/p95 ...; recent 30 points over 22.7h p05/p50/p95 ...; candidate is 3.06x p95.对应的辅助实现见 perf_api.pypercentile()计算线性插值分位数summarize_points()自动生成全量分布 最近 30 点分布selected_value_context()计算选定行相对 p50/p95 的倍数change points 的去重与排序在change_points_summary()中完成。解读规则选定 Run 远超出近期 p95 且多次 PR Run 重复出现 → 证据更强选定 Run 落在近期正常散布内 → 很可能噪声/不稳定master 近期存在已知 change point → 该 PR 可能只是在继承 master 自身的波动而非它引起的变化。Coverage / PR 交集判断测试是否执行了 PR 修改的代码Coverage 接口回答的问题是这个 perf test 有没有执行到 PR 触碰的代码它不能证明因果关系只能评估 PR/测试关系的 plausible合理性curl -fsS $BASE/runs/$RUN_ID/tests/$TEST/coverage?fileSetintersecting | jq .fileSet支持的其他取值fileSetpr # PR 触碰的文件 fileSetcovered # 测试覆盖的文件 fileSetall # 全部关键字段coverageAvailable、messagetotals.touchedFilesPR 触碰文件数、totals.coveredFiles测试覆盖文件数、totals.intersectingFiles交集数files[].path、files[].status、files[].patch、files[].coverageRanges[]辅助脚本 perf_api.py 在totals.intersectingFiles缺失时自动用len(files)兜底与文档 caveat 一致。当 coverage 不可用时可以退回到gh pr diff结合查询文本人工判断相关子系统。Flamegraphs从采样栈增量定位热点文档强调面向评审者的链接应首先指向 UI 的 query 页面该页面内含 Flamegraphs 卡片https://performance.ci.clickhouse.com/runs/$RUN_ID/tests/$TEST/queries/$QUERY_INDEX只有需要机器可读的栈/增量时才使用 raw API。单侧 collapsed stackscurl -fsS $BASE/runs/$RUN_ID/tests/$TEST/queries/$QUERY_INDEX/flamegraph?metric$METRICarch$ARCHsidecandidatetraceTypeCPU | jq -r .collapsedside可取candidate被测试 PR 侧或基线侧配合arch指定架构。差分火焰图数据curl -fsS $BASE/runs/$RUN_ID/tests/$TEST/queries/$QUERY_INDEX/flamegraph-diff?metric$METRICarch$ARCHtraceTypeCPU | jq .Flamegraph diff 的字段为stack、baselineSamples、candidateSamples。traceType 语义traceType含义CPU计算时间REAL_TIME墙钟时间适合观察等待、锁、I/O、调度器噪声MEMORY内存相关的采样如可用建议的摘要表格Leaf/subsystemBaseline samplesCandidate samplesDeltaInterpretation根因声明约束不能仅因为某个 frame 有 samples 就声称根因它必须与 metric/query 匹配且与 PR 修改的 plausibility 吻合。评审可用的火焰图证据必须包含① 精确的 UI query-page 链接优先② 仅在有价值时附 raw API 链接③ 顶部采样增量表格④ 与查询关联的简短解读若无数据则明确写no frames returned/not available。30 天 Master 状态计数通过 ClickHouse Play 的default.checksDashboard/API 偏重图表与趋势当需要同一测试/查询在 master 上 30 天内出现过多少次slower/faster/unstable这类直接计数时走 ClickHouse Play 的default.checks表。该表记录了每次 master 性能检查的状态。推荐直接使用封装好的 helperpython3 scripts/perf_api.py master-checks --pr $PR --limit 50等价的 HTTP SQL 查询模式curl -fsS https://play.clickhouse.com/?userexplorer --data-binary - SQL SELECT replaceRegexpOne(test_name, ::(new|old)$, ) AS test, countIf(test_status slower) AS slower_count, countIf(test_status faster) AS faster_count, countIf(test_status unstable) AS unstable_count, count() AS total_runs FROM default.checks WHERE pull_request_number 0 AND check_name LIKE %Performance%arm% AND check_start_time now() - INTERVAL 30 DAY AND test_name IN (fixed_hash_table_parallel_merge #1::new) GROUP BY test FORMAT JSONEachRow SQL注意关键过滤条件pull_request_number 0只统计 master 自身运行check_name LIKE %Performance%arm%与待分析行保持同架构test_name需写成test #queryIndex::new形式时间窗INTERVAL 30 DAY由--days参数控制默认 30。计数结果用于分类new in PR、rarely on master、flaky/slower on master、unstable on master、new improvement、fixes known master regression。具体分类规则可在 perf_api.py 的classify_with_master_counts()中看到例如unstable 5或比例 1% 判为 unstable on masterslowdown 行在 master 上 slow 比例 1% 或次数 ≥3 判为 flaky/slower on master1~2 次判为 rarely slowermaster 总样本 ≥50 且从未出现则判为 new in PR — investigate。TSV/raw 产物清单Dashboard 缺失时的次选证据当 Dashboard/API 无法提供所需 artifact 级数据例如某分片、某 run 的原始逐次运行值时使用 raw TSV。可用数据源包括all-query-metrics.tsvraw按当前 CI 列序、无表头fetch_perf_report.py --tsv输出带命名字段。两者按 per-shard 行提供old/newraw 文件中叫left/right、diff、times_change、stat_threshold、test、query_index、查询展示文本fetch_perf_report.py --tsv额外携带arch、shard、is_changed、is_unstable、direction。使用 helper 解析python3 scripts/perf_api.py tsv-inventory --tsv pr_${PR}_amd.tsv pr_${PR}_arm.tsv --limit 20解析器 perf_api.py 同时支持命名 TSV 与无表头的 rawall-query-metrics.tsv当前 CI 列序定义在RAW_ALL_QUERY_METRICS_COLUMNS并且能透明解压 zstd/gzip 压缩的文本产物与 CI 对超过阈值文本产物做 zstd 压缩的策略一致见read_text_maybe_compressed()。判定规则复刻自 compare.sh 中的changed_failabs(diff) changed_threshold abs(diff) stat_threshold默认changed_threshold 0.15unstable_fail非 changed 且stat_threshold unstable_threshold默认0.25。边界TSV 行只是 artifact fallback evidence不得用来推翻 Dashboard 的分类结论。Artifact/日志兜底需要根因时的最终落点当 Dashboard/API 无法解释为什么时下载 CI 产物。文档给出清晰的产物地图产物用途logs.tar.zst/job.log.zstJob 上下文、server 配置、警告/错误、机器争用left/server.log、right/server.log精确的 old/new 二进制 revision、build ID、启动设置、查询执行计时、后台活动report/stacks.left.tsv、report/stacks.right.tsv每个查询的 symbolized collapsed stacksCPU/Real/Memory优先于*-trace-log.tsvanalyze/tmp/{test}_{queryN}.tsv每次运行的 raw profile eventsDashboard 只显示汇总指标时使用预构建的.svgflamegraphsDashboard flamegraph-diff 缺失或不完整时使用注意*-trace-log.tsv并不随logs.tar.zst一起发布且只包含query_id, trace, trace_type, size原始地址、无符号。这些 trace/addresses 类文件的产生逻辑可以对照 compare.sh 中的get_profiles()——它只 dumpsystem.trace_log的四列并把符号解析任务交给独立的*-addresses.tsv。使用顺序必须是优先 Dashboard flamegraph/query API仅在需要 raw logs、raw traces、精确 build 元数据或 Dashboard 未 profile 的查询/run 时才回退到产物。实战集成把 API 组合成一份可评审的性能结论单独的接口只是数据真正的价值在于如何组合成结论。建议按以下工作流使用本文接口Run 发现与身份核对GET /runs?q$PR过滤prNumber记录oldSha/newSha/arch/runTime变更行全量盘点GET /runs/$RUN_ID分离slowdowns/speedups/unstableQueries三张表且改善行必须与回归行一起列出pr-inventory命令会自动输出Top likely signal/Top likely noise/Top improvements摘要层重复性检查同一(test, queryIndex, metric, arch)跨多个 PR Run 是否反复出现同向变化方向是否翻转置信度取证按 test 拉confidence翻译 tier/reason 为自然语言证据历史/趋势定位用 trend/history 分位数判断是否越界master 计数分类master-checks给出new in PR/flaky/unstable/fixes known regression等标签覆盖率与火焰图coverage?fileSetintersecting判断相关性UI query 页的 Flamegraphs 卡片定位热点产物兜底必要时解包logs.tar.zst与server.log核对构建与计时细节。所有步骤都有现成命令封装在 perf_api.py 中runs、pr-inventory、run/changes、query、pr-query-history、master-checks、tsv-inventory。各判定标签的取舍标准real regression、likely noise、needs rerun、unstable test、real improvement、local-only evidence、not enough evidence以及禁止/推荐的报告措辞均在 verdict-rules.md 中有完整定义。报告措辞红线不得用dashboard 表说 slower 所以是 regression这类一句式结论不得输出M1:downgrade, M2:neutral这类未解释的内部代号历史部分不得只写min/max/median/last必须给出分位数与时间窗新 Run 数据出来后被推翻的旧测量必须显式声明被更新的结果取代而不是直接展示旧表火焰图表述必须落到顶部采样增量 与查询/PR 的关系而不是笼统的flamegraph diff exists and contains relevant samples。延伸阅读perf-comparison/SKILL.md本 API 参考所属的技能总入口定义核心原则、证据阶梯与数据源优先级verdict-rules.md判定标签与报告措辞的权威规则local-perf.md本地perf.py与可选 server 启动、数据集、profile 流程当 CI 证据不足需本地复现时使用perf_api.py上述全部 API 的 stdlib-only 封装实现test_perf_api.py对 TSV 解析与 compare.sh 判定规则一致性的回归测试compare.sh性能对比 CI 的底层实现阈值判定、profile 采集、change 确认机制perf.py性能测试执行脚本本地复现与 CI 均依赖它。【免费下载链接】ClickHouseClickHouse® is a real-time analytics database management system项目地址: https://gitcode.com/GitHub_Trending/cli/ClickHouse创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考