ES实战-trying to create too many buckets
场景
es查询报错,报错如下:
trying to create too many buckets. must be less than or equal to: [10000] but was [10001].
问题分析
显示网上搜索了一番,大都给出了问题原因,那就是ES聚合查询的聚合桶查询默认为10000,查询超过的时候,就会报错,导致查询失败。由于Bucket aggregations查询操作比较消耗内存,如果聚集桶过多,频率较大时,很容易导致集群JVM内存不足,进而产生查询熔断。
我们看下官网描述,确实是这么回事:

问题复现
注意官网的这一句话:
Requests that attempt to return more than this limit will return an error.
翻译:试图返回超过此限制的请求将返回错误。
那么我们来验证一下,复现一下问题:
环境说明:本人采用的是es7.8.1的版本进行演示测试,使用postman进行测试
创建测试聚合桶查询的索引库(PUT请求)
localhost:9200/testbuckets
{
"mappings": {
"properties": {
"name": {
"type": "keyword"
},
"price": {
"type": "long"
},
"color": {
"type": "keyword"
},
"size": {
"type": "long"
},
"category": {
"type": "keyword"
},
"label": {
"type": "keyword"
},
"release_date": {
"type": "date"
}
}
}
}
====返回====
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "testbuckets"
}
构建测试数据,为了模拟分桶数据,我将创建一些手机测试数据用于演示。
创建数据(PUT请求)
localhost:9200/testbuckets/_bulk
{"index":{}}
{"name":"小米13","price":3400,"color":"白色","size":6.21,"category":"小米","label":"高端","release_date":"2022-02-06"}
{"index":{}}
{"name":"小米13","price":3400,"color":"黑色","size":6.21,"category":"小米","label":"高端","release_date":"2022-02-06"}
{"index":{}}
{"name":"小米12","price":2400,"color":"黑色","size":6.21,"category":"小米","label":"快充","release_date":"2021-02-06"}
{"index":{}}
{"name":"苹果13","price":3400,"color":"黑色","size":6.21,"category":"苹果","label":"性能","release_date":"2022-02-06"}
{"index":{}}
{"name":"苹果14","price":2400,"color":"远峰蓝色","size":6.21,"category":"苹果","label":"性能","release_date":"2021-02-06"}
{"index":{}}
{"name":"华为Mate 50","price":5200,"color":"白色","size":6.21,"category":"华为","label":"鸿蒙OS","release_date":"2021-05-06"}
{"index":{}}
{"name":"华为Mate 50","price":5200,"color":"黑色","size":6.21,"category":"华为","label":"鸿蒙OS","release_date":"2021-05-06"}
{"index":{}}
{"name":"华为Mate 40 Pro","price":5900,"color":"黑色","size":6.21,"category":"华为","label":"商务","release_date":"2022-02-06"}
{"index":{}}
{"name":"华为Mate 40 Pro","price":5900,"color":"白色","size":6.21,"category":"华为","label":"商务","release_date":"2022-02-06"}
ps:使用postman批量插入测试数据,最后一条记录后面需要换行,否则会插入失败
修改es最大分桶配置参数(PUT请求)
http://127.0.0.1:9200/_cluster/settings
{
"persistent": {
"search.max_buckets": 2 //为了演示,设值为2,官方默认此值为10000
}
}
构造聚合查询,在上面,我们创建了测试使用的手机索引库,此时,我们按照手机颜色进行数据聚合分组查询:
查询数据(GET请求)
http://127.0.0.1:9200/testbuckets/_search
{
"aggs": {
"by_color": { // 按照颜色合聚合
"terms": {
"field": "color" // 聚合字段
}
}
},
"size": 0 //不显示原始数据,只看分组数据
}
===返回结果===
{
"error": {
"root_cause": [
{
"type": "too_many_buckets_exception",
"reason": "Trying to create too many buckets. Must be less than or equal to: [2] but was [3]. This limit can be set by changing the [search.max_buckets] cluster level setting.",
"max_buckets": 2
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"phase": "query",
"grouped": true,
"failed_shards": [
{
"shard": 0,
"index": "testbuckets",
"node": "UuMcBk37TNWHjY4hVtzyVA",
"reason": {
"type": "too_many_buckets_exception",
"reason": "Trying to create too many buckets. Must be less than or equal to: [2] but was [3]. This limit can be set by changing the [search.max_buckets] cluster level setting.",
"max_buckets": 2
}
}
]
},
"status": 503
}
可以看到错误已经复现了,为什么呢,因为我们刚才将search.max_buckets配置参数改成了2,而实际上我们的测试数据里,如果根据color来分桶查询,会有黑色,白色,远峰蓝色这3种颜色,查询结果超过了限制值,就报错了,就证明了官方的Requests that attempt to return more than this limit will return an error的说法
我们将search.max_buckets改大一点再看(PUT请求)
http://127.0.0.1:9200/_cluster/settings
{
"persistent": {
"search.max_buckets": 3
}
}
===返回结果===
{
"acknowledged": true,
"persistent": {
"search": {
"max_buckets": "3"
}
},
"transient": {}
}
再次执行查询(GET请求),就会发现不报错了。
http://127.0.0.1:9200/testbuckets/_search
{
"aggs": {
"by_color": { // 按照颜色合聚合
"terms": {
"field": "color" // 聚合字段
}
}
},
"size": 0 //不显示原始数据,只看分组数据
}
===返回结果===
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 9,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"by_color": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "黑色",
"doc_count": 5
},
{
"key": "白色",
"doc_count": 3
},
{
"key": "远峰蓝色",
"doc_count": 1
}
]
}
}
}
解决方案
方案一
修改配置(PUT请求):
// 临时修改,es重启失效
http://127.0.0.1:9200/_cluster/settings
{"transient": {"search.max_buckets": 50000}}
// 永久修改,esc重启依旧生效
http://127.0.0.1:9200/_cluster/settings
{"persistent": {"search.max_buckets": 50000}}
服务器上可使用curl命令:
// 临时修改,es重启失效
curl -X PUT "http://127.0.0.1:9200/_cluster/settings" -H 'Content-Type: application/json' -d '{"transient":{"search.max_buckets": 50000}}'
// 永久修改,esc重启依旧生效
curl -X PUT -k "http://127.0.0.1:9200/_cluster/settings" -H 'Content-Type: application/json' -d '{"persistent":{"search.max_buckets": 1000000}}'
说明:es一些配置修改,有两种方式,上面我修改最大分桶参数使用到了persistent,二者区别如下。
transient 临时:这些设置在集群重启之前一直会生效。一旦整个集群重启,这些设置就会被清除。
persistent 永久:这些设置永久保存,除非再次被手动修改。是将修改持久化到文件中,重启之后也不影响。
弊端:由于Bucket aggregations查询操作比较消耗内存,如果聚集桶过多,频率较大时,很容易导致集群JVM内存不足,进而产生查询熔断,所以不能无限制的扩大分桶数参数,需要结合实际服务器能力与业务需求来考量一个合适的值。
方案二
整改业务,大多场景下,对于查询结果是想获取到自己想要的精确少量结果,es 默认设置 10000 的上限是有原因的,这块需要对你的服务器性能有一个评估,考虑你的 es 服务是否能撑得住这种大量的聚合计算,冒然扩大限制可能导致服务的崩溃。如果预计的 buckets 数量级别过大,就需要结合具体场景分析在查询层面进行优化。
比如还拿我上面的手机测试库来看,如果非要不改配置而实现查询不报错,那么我们可以这样来优化一下查询业务。
此处仅做个参考思路演示,具体实际生产场景需要结合具体业务考虑。
http://127.0.0.1:9200/testbuckets/_search
{"query":{
"match":{
"category":"小米" // 限制查询手机类别,缩小数据范围,此处以小米品牌为例
}
},
"aggs": {
"by_color": {
"terms": {
"field": "color"
}
}
},
"size": 0 //不显示原始数据,只看分组数据
}
===返回结果====
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3,
"relation": "eq"
},
"max_score": null,
"hits": []
},
"aggregations": {
"by_color": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "黑色",
"doc_count": 2
},
{
"key": "白色",
"doc_count": 1
}
]
}
}
}
ES实战-trying to create too many buckets的更多相关文章
- es实战之数据导出成csv文件
从es将数据导出分两步: 查询大量数据 将数据生成文件并下载 本篇主要是将第二步,第一步在<es实战之查询大量数据>中已讲述. csv vs excel excel2003不能超过6553 ...
- 1W字|40 图|硬核 ES 实战
前言 上篇我们讲到了 Elasticsearch 全文检索的原理<别只会搜日志了,求你懂点检索原理吧>,通过在本地搭建一套 ES 服务,以多个案例来分析了 ES 的原理以及基础使用.这次我 ...
- es实战之查询大量数据
背景 项目中已提供海量日志数据的多维实时查询,客户提出新需求:将数据导出. 将数据导出分两步: 查询大量数据 将数据生成文件并下载 本文主要探讨第一步,在es中查询大量数据或者说查询大数据集. es支 ...
- Spring Boot & ES 实战,值得参考!
作者:废物大师兄 cnblogs.com/cjsblog/p/9756978.html 1. 前言 1.1. 集成方式 Spring Boot中集成Elasticsearch有4种方式: REST C ...
- Spark2.2+ES6.4.2(三十二):ES API之index的create/update/delete/open/close(创建index时设置setting,并创建index后根据avro模板动态设置index的mapping)
要想通过ES API对es的操作,必须获取到TransportClient对象,让后根据TransportClient获取到IndicesAdminClient对象后,方可以根据IndicesAdmi ...
- 2017 ES GZ Meetup分享:Data Warehouse with ElasticSearch in Datastory
以下是我在2017 ES 广州 meetup的分享 ppt:https://elasticsearch.cn/slides/11#page=22 摘要 ES最多使用的场景是搜索和日志分析,然而ES强大 ...
- ElasticStack系列之十六 & ElasticSearch5.x index/create 和 update 源码分析
开篇 在ElasticSearch 系列十四中提到的问题即 ElasticStack系列之十四 & ElasticSearch5.x bulk update 中重复 id 性能骤降,继续这个问 ...
- es与hive整合
在hive classpath中添加elasticsearch-hadoop.jar,以下方法任一种均可: 1.启动hiveserver2 前,在hive-site.xml文件中更改hive.aux. ...
- Ceph RGW 创建默认的pool
使用Ceph-deploy完成RGW服务部署后(最好是在部署RGW服务前建立如下这些pool),使用sudo ceph osd lspools 命令,会发现RGW自动以默认参数创建了N个rgw相关的p ...
- manage account
#!/bin/bash # #Delete_user - Automates the steps to remove an account # ############################ ...
随机推荐
- Windows IIS下运行.NET Core程序
IIS下运行.NET Core程序 1.服务器上必须要安装 WindowsHosting WindowsHosting 下载地址:https://dotnet.microsoft.com/downlo ...
- MySQL8.0 高可用集群化 · mysql-shell · mysql-router · docker · 单主多从
高可用集群的基本特点 负载均衡 / 读写分离 / 故障转移本文以此为目标,利用 mysql-shell.mysql-router,基于 docker 的环境架构(篇幅太长,内容多了点儿). 一.名词及 ...
- OpenMP Sections Construct 实现原理以及源码分析
OpenMP Sections Construct 实现原理以及源码分析 前言 在本篇文章当中主要给大家介绍 OpenMP 当中主要给大家介绍 OpenMP 当中 sections construct ...
- BAL数据集详解
详细格式:https://grail.cs.washington.edu/projects/bal/ Bundle Adjustment in the Large Recent work in Str ...
- CSU2022-2023C语言期中考试机试
卡在出线概率了.40%,没想到遍历时反了,我去. 1.时钟加法 题目描述 小南最近迷上了各种形式的加法,例如时钟加法,时钟加法是指给定一个当前时间,其形式为h:m:s,计算加上n秒后新的时间.你能帮他 ...
- cmd数字雨原代码
转自:https://www.xitongtiandi.net/wenzhang/xp/29290.html
- 计算属性报错:Maximum recursive updates exceeded.
计算属性或普通函数中有对相关依赖的响应式数据进行一次以上的更新就可能导致达到最大执行的限制: const calcSurplus = computed(() => (k: string) =&g ...
- 在Unity中对森林植被进行优化
https://www.163.com/dy/article/DP6665QP0526E124.html
- 【HTML】HTML特殊字符大全
使用方法:这些字符属于unicode字符集,所以,你的文档需要声明为UTF-8:下面符号列表的后面有两列编号,它们并不太一样,第一列是用于html的,你需要在前面加上&#符号:第二列可以用于C ...
- rsut 字节数组和字符串转换
一.字符串转换为字节数组 let s = String::from("str"); let v = s.as_bytes(); // &[u8] println!(&quo ...