Elasticsearch:QueueResizingEsThreadPoolExecutor 异常
Elasticsearch: QueueResizingEsThreadPoolExecutor exception
在我的 java Web 应用程序从 Elasticsearch 获取静态数据的 35k 耐久负载测试中的某个时候,我开始遇到以下 Elasticsearch 异常:
Caused by: org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution of org.elasticsearch.common.util.concurrent.TimedRunnable@1a25fe82 on QueueResizingEsThreadPoolExecutor[name = search4/search, queue capacity = 1000, min queue capacity = 1000, max queue capacity = 1000, frame size = 2000, targeted response rate = 1s, task execution EWMA = 10.7ms, adjustment amount = 50, org.elasticsearch.common.util.concurrent.QueueResizingEsThreadPoolExecutor@6312a0bb[Running, pool size = 25, active threads = 25, queued tasks = 1000, completed tasks = 34575035]]
Elasticsearch 详情:
Elasticsearch 版本6.2.4.
集群由5个节点组成。每个节点的 JVM 堆大小设置为 Xms16g
和 Xmx16g
。每个节点机器有16个处理器。
NOTE:最初,当我第一次得到这个异常时,我决定增加elasticsearch.yml
中的thread_pool.search.queue_size
参数,设置为10000
。是的,我明白了,我只是把问题推迟到以后再发生。
Elasticsearch 指标详情:
目前,大约有20个指标,其中只有6个在使用。未使用的是创建新索引后未删除的旧索引。索引本身非常小:
红色矩形内的索引是我的网络应用程序使用的索引。它的分片和副本设置分别为 "number_of_shards": "5" 和 "number_of_replicas": "2"。
它的碎片详细信息:
在这个 article 我发现
Small shards result in small segments, which increases overhead. Aim
to keep the average shard size between at least a few GB and a few
tens of GB. For use-cases with time-based data, it is common to see
shards between 20GB and 40GB in size.
从上面的屏幕截图可以看出,我的分片大小比上面提到的小得多。
因此,问: 在我的案例中,正确的分片数量是多少?是 1 还是 2?
随着时间的推移,该指数不会增长太多。
测试期间发出的 ES 查询。负载测试模拟用户导航到页面以搜索某些产品的场景。用户可以使用相应的过滤器(例如名称、城市等)来过滤产品。使用复合查询从 ES 索引中获取唯一过滤器值。所以这是第一种查询类型。另一个查询是从 ES 获取产品。由must、must_not、filter、[=组成70=] 查询,size 属性等于 100.
我设置了慢速搜索记录,但没有记录任何内容:
"index": {
"search": {
"slowlog": {
"level": "info",
"threshold": {
"fetch": {
"debug": "500ms",
"info": "500ms"
},
"query": {
"debug": "2s",
"info": "1s"
}
}
}
}
我觉得我缺少一些简单的东西来最终完成它并能够处理我的负载。感谢,如果有人可以帮助我解决问题。
对于这么小的尺寸,你使用了 5 个主分片,我觉得,由于你的 ES 版本 6.X(默认为 5),你从未改变过它,但总之有很高的数量小索引的主分片,有严重的性能损失,请参考我在 my blog.
中介绍的非常相似的用例(我也有 5 PS )
正如您已经提到的,您的索引大小将来不会显着增长,我建议拥有 1 个主分片和 4 个副本分片
- 1 Primary shard是指单次搜索,Elasticsearch只创建一个线程和一个请求,这样可以更好地利用资源。
- 因为你有 5 个数据节点,有 4 个副本意味着分片在每个数据节点上正确分布,所以你的吞吐量和性能将是最佳的。
进行此更改后,测量性能,我相信在此之后,您可以再次将搜索队列大小减少到 1k,因为您知道队列大小过高只会延迟问题,并不能解决手头的问题.
来到你的搜索慢日志,我感觉你的门槛很高,查询阶段1 seconds
一个查询对于面向用户的应用来说真的很高,尽量降低~ 100 毫秒,而不是关闭这些查询并进一步优化它们。
在我的 java Web 应用程序从 Elasticsearch 获取静态数据的 35k 耐久负载测试中的某个时候,我开始遇到以下 Elasticsearch 异常:
Caused by: org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution of org.elasticsearch.common.util.concurrent.TimedRunnable@1a25fe82 on QueueResizingEsThreadPoolExecutor[name = search4/search, queue capacity = 1000, min queue capacity = 1000, max queue capacity = 1000, frame size = 2000, targeted response rate = 1s, task execution EWMA = 10.7ms, adjustment amount = 50, org.elasticsearch.common.util.concurrent.QueueResizingEsThreadPoolExecutor@6312a0bb[Running, pool size = 25, active threads = 25, queued tasks = 1000, completed tasks = 34575035]]
Elasticsearch 详情:
Elasticsearch 版本6.2.4.
集群由5个节点组成。每个节点的 JVM 堆大小设置为 Xms16g
和 Xmx16g
。每个节点机器有16个处理器。
NOTE:最初,当我第一次得到这个异常时,我决定增加elasticsearch.yml
中的thread_pool.search.queue_size
参数,设置为10000
。是的,我明白了,我只是把问题推迟到以后再发生。
Elasticsearch 指标详情:
目前,大约有20个指标,其中只有6个在使用。未使用的是创建新索引后未删除的旧索引。索引本身非常小:
红色矩形内的索引是我的网络应用程序使用的索引。它的分片和副本设置分别为 "number_of_shards": "5" 和 "number_of_replicas": "2"。
它的碎片详细信息:
Small shards result in small segments, which increases overhead. Aim to keep the average shard size between at least a few GB and a few tens of GB. For use-cases with time-based data, it is common to see shards between 20GB and 40GB in size.
从上面的屏幕截图可以看出,我的分片大小比上面提到的小得多。 因此,问: 在我的案例中,正确的分片数量是多少?是 1 还是 2? 随着时间的推移,该指数不会增长太多。
测试期间发出的 ES 查询。负载测试模拟用户导航到页面以搜索某些产品的场景。用户可以使用相应的过滤器(例如名称、城市等)来过滤产品。使用复合查询从 ES 索引中获取唯一过滤器值。所以这是第一种查询类型。另一个查询是从 ES 获取产品。由must、must_not、filter、[=组成70=] 查询,size 属性等于 100.
我设置了慢速搜索记录,但没有记录任何内容:
"index": {
"search": {
"slowlog": {
"level": "info",
"threshold": {
"fetch": {
"debug": "500ms",
"info": "500ms"
},
"query": {
"debug": "2s",
"info": "1s"
}
}
}
}
我觉得我缺少一些简单的东西来最终完成它并能够处理我的负载。感谢,如果有人可以帮助我解决问题。
对于这么小的尺寸,你使用了 5 个主分片,我觉得,由于你的 ES 版本 6.X(默认为 5),你从未改变过它,但总之有很高的数量小索引的主分片,有严重的性能损失,请参考我在 my blog.
中介绍的非常相似的用例(我也有 5 PS )正如您已经提到的,您的索引大小将来不会显着增长,我建议拥有 1 个主分片和 4 个副本分片
- 1 Primary shard是指单次搜索,Elasticsearch只创建一个线程和一个请求,这样可以更好地利用资源。
- 因为你有 5 个数据节点,有 4 个副本意味着分片在每个数据节点上正确分布,所以你的吞吐量和性能将是最佳的。
进行此更改后,测量性能,我相信在此之后,您可以再次将搜索队列大小减少到 1k,因为您知道队列大小过高只会延迟问题,并不能解决手头的问题.
来到你的搜索慢日志,我感觉你的门槛很高,查询阶段1 seconds
一个查询对于面向用户的应用来说真的很高,尽量降低~ 100 毫秒,而不是关闭这些查询并进一步优化它们。