技术5/28/2026·7 min

为什么业务总量不能从采样 histogram 还原

我们对遥测做采样来控制成本。比值和分位数在采样下是免费的——但业务总量不是,而「除以采样率还原」会悄悄骗你。本文讲清这个救了我们仪表盘的区分。

为什么要采样

我们的分析管道从每个安装收集 events 和 histogram。规模上来后,100% 全量既不便宜也无必要,于是我们采样——按 install 采样,让某台设备要么一直在采样集里、要么一直不在,而不是每个请求翻硬币。

采样是那种「看起来无害,直到仪表盘上某个数字悄悄错了」的决定。

踩的坑:一个偏低的总量

有个仪表盘用 histogram 的 count 字段显示「总请求数」。开了采样后,这个数偏低——大约差一个采样率。看起来显而易见的修法也很显然:除以采样率「还原回去」。

这个还原对某些指标是对的,对另一些则微妙而顽固地错。这个差别,正是全文的重点。

比值是免费的,总量不是

把你算的每个指标分成两族:

  • 比值与形状——错误率、平均延迟、P50/P99、缓存命中率。这些是相对量。
  • 绝对总量——总请求数、总营收、做了某事的安装数。这些是外延量。

采样下,这两族的行为完全不同。

为什么 P99 和错误率在采样下安然无恙

分位数或比率是分布的属性,与你抽了多少样本无关。均匀采样下,样本分布(期望上)和全量同形状:样本的 P99 ≈ 总体的 P99。错误率——错误数除以总数、分子分母同被采样率缩放——采样率直接约掉。

最妙的是:你甚至不需要知道采样率就能正确读出它们,天然无偏、免费。

为什么总量依旧错——哪怕数据很多

还原绝对总量要反着来:拿样本的 count 乘以 1 / 采样率。这是个估计量,它的误差不取决于你收了多少 event,而取决于你采样了多少 install、以及业务量在 install 间分布得多均匀。

按 install 采样是整群采样:你一次性保留或丢弃整台设备的流。如果业务量是重尾的——少数重度用户贡献了大部分流量——那你的估计准不准,几乎完全取决于这几条「鲸鱼」是否恰好落进样本。要么进了(你高估)、要么没进(你低估)。多收 event 没用,只有更多 install 才缩小误差;而重尾之下,即便 install 数很大,估计依然有偏。

所以「除以采样率」给出的数看着精确,实则悄悄偏离——有时偏得很多。

修法:总量靠计数,形状靠采样

我们定下的规则:

  • 业务总量走 always-on、全保真的 events,绝不从采样 histogram 还原。
  • 采样 histogram 只用于比值与形状——分位数、比率、分布——这里采样无偏且便宜。

在 dbt 模型里这体现为两个刻意不同的列:sample_count(样本量,用于方差/置信)与 request_count(真实业务量,来自全量 events)。它们不可互换——混用正是我们当初踩的 bug。一个跨仓 contract lint 现在断言这两列保持分离、来源正确,于是语义是被强制的,而不是靠记忆。

小结

采样对比值和分位数是免费的,对总量是陷阱。在你「除以采样率」之前,先问这个量是相对的还是外延的。如果它是对业务重要的总量,别采样它——去计数它——并给列起好名字,让下一个人丢不掉这个区分。