如何生成 HDR 直方图并计算 P99 延迟?

解读

在国内 CouchDB 运维与性能调优面试中,HDR 直方图(High Dynamic Range Histogram)是衡量长尾延迟的“硬通货”。
面试官真正想确认的是:

  1. 你能否在不停服的前提下,对 CouchDB 的单次请求延迟(如 _all_docs_find_bulk_docs)做微秒级采样;
  2. 你能否用低开销的方式把样本压缩成 HDR 直方图,并秒级算出 P99、P99.9;
  3. 你能否把结果对接到国内常用的监控体系(夜莺、Prometheus + Grafana、阿里云 SLS),让 SRE 在移动端即可收到阈值告警

知识点

  1. HDR 直方图核心原理
    指数桶 + 计数器数组,相对误差 < 1%,内存占用固定(默认最大 182 KB),支持动态范围 1 µs ~ 3600 s
  2. CouchDB 延迟采集点
    mochiweb 请求中间件、httpd 模块的 on_response 钩子、couch_stats 采样器。
  3. 国内可落地的 HDR 实现
    • Java:HdrHistogram 2.1.9(阿里中间件团队维护的国内镜像);
    • Erlanghdr_histogram_erl(开源,可直接嵌入 CouchDB 插件);
    • Go:CouchDB exporter 侧写,用circlhist 做无锁并发。
  4. P99 计算
    直方图内置 getValueAtPercentile(99.0)O(1) 时间,零额外内存
  5. 与 Prometheus 对接
    通过 text 格式 Exporter 暴露 couchdb_request_duration_seconds{quantile="0.99"}避免 Histogram bucket 膨胀(原生 Prometheus Histogram 在国内万级实例场景下, cardinality 爆炸,费用翻倍)。

答案

步骤 1:埋点
src/couch/src/couch_httpd.erlhandle_request 函数首尾打时间戳:

T0 = os:system_time(microsecond),
...
Latency = os:system_time(microsecond) - T0,
hdr_histogram:record(HdrRef, Latency).

HdrRef 是 ETS 表保护的进程字典,无锁并发写,对单次请求额外耗时 < 200 ns。

步骤 2:聚合
每 10 s 将直方图旋转(rotate)一次,老直方图序列化后通过 gen_server:call 落到本地 ets:tab2file,防止进程崩溃丢数据

步骤 3:计算 P99

P99 = hdr_histogram:percentile(HdrRef, 99.0),

单位自动换算为毫秒,保留两位小数,通过 couch_log 写入 JSON 格式日志,方便 Filebeat 采集到阿里云 SLS。

步骤 4:暴露指标
写一个 CouchDB 原生插件 hdr_exporter,监听 127.0.0.1:6986/metrics,返回:

# HELP couchdb_request_duration_seconds HDR 直方图 P99 延迟
# TYPE couchdb_request_duration_seconds gauge
couchdb_request_duration_seconds{quantile="0.99"} 0.023

夜莺可直接拉取,告警规则value > 0.05 持续 2 分钟则短信+飞书通知值班。

步骤 5:线上验证
wrk2 压测 10 k RPS,持续 5 min,对比 wrk2 输出的 P99 与 HDR 直方图结果,误差 < 1 ms 即算通过。

拓展思考

  1. 多维度下钻
    国内业务常按租户+表+副本节点三维拆分,可在 HDR 直方图 key 前拼接 {Tenant, Shard, Node}总内存仍可控(182 KB × 维度组合),但需LRU 淘汰冷门维度,防止内存泄漏。
  2. 跨数据中心复制延迟
    把 HDR 直方图序列化成 Base64 塞进 _local/shard-sync 文档,跟随 CouchDB 双向复制到对端机房,对端解析后可直接得到上游 P99,无需额外监控通道,符合国内金融级两地三中心要求。
  3. Serverless 场景
    在阿里云函数计算里跑 CouchDB 极简版,冷启动 100 ms 内需初始化 HDR 直方图,可用 mmap 把上一轮的直方图文件映射到内存,毫秒级恢复,保证 P99 数据断点续传