按用户维度做 terms 聚合,请求返回 429,报 circuit_breaking_exception: [parent] Data too large, data for [<receiver>] would be larger than [40gb]。同一查询在测试集群正常。日志里能对上时间点,这种反而好排。
terms 聚合要把每个桶的计数和排序状态放在堆里,桶数量跟着字段基数走。用户 id 基数两千万,size 又写了 10000,内存一下顶到父熔断线。熔断是保护动作,不是故障本身。这一点先确认清楚,后面就不用反复试。
GET orders/_search
{"size": 0, "aggs": {"u": {"terms": {"field": "user_id", "size": 200}}}}
围绕「聚合熔断」排查时,命令行跑一遍比在面板里点十次有用,面板会替你做掉不少隐式操作。先做最小复现,能稳定跑出来的问题,排查成本会低一个数量级。
别只看报错的最后一行,往上看几行,真正的起因通常在上面。同类问题如果隔一段时间又出现,多半是某个定时任务或重启流程把改动冲掉了。
处理上按这个顺序:把 terms 的 size 从 10000 降到实际需要的几百;高基数字段改用 composite 聚合分页取;聚合前加 filter 缩小时间范围 别全量扫;调大熔断线只能救急 堆不够还是会被打回。
结果对不对很好判断,同一请求返回 200,took 从超时降到几百毫秒,节点堆内存不再冲高。
