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 堆大小设置为 Xms16gXmx16g。每个节点机器有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 获取产品。由mustmust_notfilter[=组成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. 1 Primary shard是指单次搜索,Elasticsearch只创建一个线程和一个请求,这样可以更好地利用资源。
  2. 因为你有 5 个数据节点,有 4 个副本意味着分片在每个数据节点上正确分布,所以你的吞吐量和性能将是最佳的。

进行此更改后,测量性能,我相信在此之后,您可以再次将搜索队列大小减少到 1k,因为您知道队列大小过高只会延迟问题,并不能解决手头的问题.

来到你的搜索慢日志,我感觉你的门槛很高,查询阶段1 seconds一个查询对于面向用户的应用来说真的很高,尽量降低~ 100 毫秒,而不是关闭这些查询并进一步优化它们。