第五阶段 45 · percentiles 与 cardinality 精度(近似聚合的真相)

发布时间:2026/8/5 8:25:48
第五阶段 45 · percentiles 与 cardinality 精度(近似聚合的真相) 45 · percentiles 与 cardinality 精度近似聚合的真相阶段第五阶段 / 进阶第 20 篇指标聚合的深入ESpercentiles/percentile_ranks/cardinality| PostgreSQLpercentile_cont/COUNT(DISTINCT)1. 概念ES 的分位数和去重计数是“近似”的为了在海量数据、多分片下还能快ES 用了近似算法聚合算法特点cardinality去重计数HyperLogLog内存固定有误差可控percentiles分位数TDigest或 HDR极值附近更准中间近似它们不是精确值。数据量小时几乎无差量大时要理解误差来源别当精确数用于对账。2. PostgreSQL 对照-- 精确分位数PG 精确ES 近似SELECTpercentile_cont(0.95)WITHINGROUP(ORDERBYlatency)FROMreq;-- 精确去重PG 精确ES cardinality 近似SELECTCOUNT(DISTINCTuser_id)FROMreq;PG 是精确计算ES 用近似换性能。要精确去重且量不大可用terms桶数或 composite。3. ES DSL3.1 percentiles分位数GET req_idx/_search { size: 0, aggs: { latency_pct: { percentiles: { field: latency_ms, percents: [50, 90, 95, 99] } } } }3.2 percentile_ranks反查某值排在第几百分位aggs: { rank: { percentile_ranks: { field: latency_ms, values: [200, 500] } } }3.3 cardinality近似去重 精度阈值aggs: { uv: { cardinality: { field: user_id, precision_threshold: 3000 } } }precision_threshold低于此基数时几乎精确越大越准但越占内存上限 40000。4. Spring Boot 实现ComponentpublicclassDoc45Percentiles{AutowiredprivateElasticsearchClientelasticsearchClient;/** P50/P90/P95/P99 延迟 */publicMapString,DoublelatencyPercentiles(StringindexName)throwsIOException{SearchResponseVoidrespelasticsearchClient.search(s-s.index(indexName).size(0).aggregations(pct,a-a.percentiles(p-p.field(latency_ms).percents(50.0,90.0,95.0,99.0))),Void.class);// percentiles 结果是 key(分位)-value(值) 的 mapreturnresp.aggregations().get(pct).tdigestPercentiles().values().keyed();}/** 近似 UV指定精度阈值 */publiclongapproxUv(StringindexName)throwsIOException{SearchResponseVoidrespelasticsearchClient.search(s-s.index(indexName).size(0).aggregations(uv,a-a.cardinality(c-c.field(user_id).precisionThreshold(3000))),Void.class);returnresp.aggregations().get(uv).cardinality().value();}}percentiles 默认 TDigest读取用.tdigestPercentiles()用 HDR 时读.hdrPercentiles()。keyed()返回MapString,Doublekey 是 “95.0” 这样的字符串。5. 坑与最佳实践近似 ≠ 精确cardinality/percentiles别用于财务对账等要求精确的场景。cardinality调precision_threshold按可接受误差和内存权衡别无脑拉满。percentiles 极值更准P99/P1 比 P50 更可靠这是 TDigest 的特性。高延迟要 P99 而非 avg平均值会被掩盖SLO 看高分位。要精确去重小基数用terms桶计数大基数只能接受近似或离线精确算。