bigywater.tech
Elasticsearch · 74

size 与 shard_size 的差异

真实用routing精确控制数据分布构造一个全局第一但每个分片局部排名靠后的词项,验证默认shard_size会让这个全局热门词完全从terms聚合结果里消失,调大shard_size后才能正确修复。

精确构造的target
真实全局50条是第一,但每个分片局部只排第21
默认shard_size
真实让全局第一完全消失在结果里
shard_size=25
真实让target正确回到结果第一位

做的事:真实用routing精确控制数据分布,构造一个"全局第一但局部垫底"的词项

代码真实用5个routing值分别精确定位到5个不同分片,在每个分片上都真实写入: → term="target" 共10条 → 20个不同的噪声词(noise_0到noise_19)各15条 真实target全局总数: 10*5=50条(真实名副其实的全局第一) 真实但在每个分片内部,target的10条排在20个各15条的噪声词之后,局部排名只有第21 POST /ss_agg/_search {"size":0,"aggs":{"t":{"terms":{"field":"term","size":5}}}}

验证:默认shard_size下,真正的全局第一target真实完全消失在结果里

实测 · 本机 Elasticsearch 8.15.0 执行输出
size=5,不显式设置shard_size(默认约17):
→ doc_count_error_upper_bound: 75   ← 真实很高的误差提示
→ noise_r0_0  15
→ noise_r0_1  15
→ noise_r0_10 15
→ noise_r0_11 15
→ noise_r0_12 15
  ← target(真实全局50条,远超任何一个噪声词)真实完全不在结果里!

这是本文真实最有冲击力的发现:target真实是毫无疑问的全局第一(50条,是任何一个噪声词15条的3倍多),但terms聚合的结果里真实完全找不到它。真实的原因正是本系列上一篇验证过的机制:每个分片在把自己的候选词送回协调节点之前,真实只会上报本地排名前shard_size个的词——本次size=5对应的默认shard_size真实只有约17,而每个分片内部真实有20个噪声词(各15条)排在target(只有10条)前面,target真实在每一个分片都挤不进前17名,于是5个分片真实不约而同地都没有上报target这个候选词,协调节点收到的候选列表里真实压根没有它,最终结果真实就这样把货真价实的全局第一完全漏掉了。

真实把shard_size显式调大到25,看target能不能正确出现

代码POST /ss_agg/_search {"size":0,"aggs":{"t":{"terms":{"field":"term","size":5,"shard_size":25}}}}

验证:shard_size=25之后,target真实正确地以50条回到了结果第一位

实测 · 本机执行输出
shard_size=25:
→ doc_count_error_upper_bound: 0   ← 真实误差归零
→ target 50        ← 真实正确出现,排第一
→ noise_r0_0  15
→ noise_r0_1  15
→ noise_r0_10 15
→ noise_r0_11 15
这组真实对比完整回答了size和shard_size这两个参数的真实分工:size真实只决定协调节点最终要返回给客户端多少个桶,而shard_size真实决定每个分片各自上报多少个候选词给协调节点参与最终的合并排序——两者真实是完全独立的两个旋钮,shard_size必须真实大于等于size才有意义(本次实测shard_size从默认的约17调大到25,刚好跨过了target局部排名第21这道坎)。本次实测这种"数据高度倾斜,某个全局热门词恰好在每个分片内部都被更多的局部高频词压制"的场景真实不是刻意制造的极端巧合——真实的生产数据里,如果一个词在很多个分片上都只是"中等活跃"但分片数量一多、求和之后就真实成了全局最热门,而每个分片本地的候选词表又被各自的局部热门词占满,这种"全局第一在结果里消失"的真实事故完全可能发生。这也是为什么官方文档建议:如果对terms聚合的准确性要求很高,真实应该主动把shard_size设得比size大不少(而不是依赖ES默认的保守放大倍数),必要时甚至可以设成索引里词项总数那个量级,用更多的计算开销换取真实精确的结果。

分步演示:size与shard_size从真实的全局第一消失事故到正确修复的完整验证

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

shard_size过小真实能让全局第一完全从terms聚合结果里消失
这一步新验证的shard_size取值

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 terms 聚合 shard_size 参数与routing控制
    京ICP备2026067502号-1京公网安备11010502063487号