我的申请有一个要求:以识别应用程序中昂贵的ElasticSearch查询。
我只知道有ElasticSearch的查询DSL。(https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl.html
我需要在elasticsearch的反向代理中识别每个elasticsearch查询(反向代理是用java开发的,只是为了限制对ES的请求并做一些用户统计),如果它是昂贵的查询,只有有限的用户可以在特定的速率限制下执行。
对我来说困难的是如何识别昂贵的查询。我知道有一个开关的ElasticSearch,可以禁用/启用昂贵的查询通过设置这个参数。我读了ElasticSearch的源代码,但我不能找到ElasticSearch如何识别不同类型的昂贵的查询。
如果您知道:
1.有没有任何elasticsearch API(来自elasticsearch客户端sdk)可以识别昂贵的查询?然后我可以直接在我的应用程序中调用API。
1.如果没有,你知道什么是有效的方法来识别昂贵的查询,通过分析查询体?通过一些AST(抽象语法树)解析器?或通过在查询体中搜索特定的关键字?
我真的很感激你的帮助!
2条答案
按热度按时间e0uiprwp1#
在Elasticsearch中没有一个很好的“原生”方法来做这件事,但是你有一些可能会有所帮助的选项
设置超时或terminate_after
此选项从不同的Angular 考虑您的需求。
来自ElasticSearch文档:search-your-data
您可以通过查看结果中返回的
took
字段来保存用户执行每个查询所用的时间记录。通过这种方式,您可以记录用户在一个时间窗口内执行了多少次“扩展”查询(花费的时间超过X)。
对于该用户,您可以开始添加
timeout
或terminate_after
参数,以尝试限制查询执行。这不会阻止用户执行扩展查询,但它会在“超时”过期后尝试取消长时间运行的查询,并将部分或空结果返回给用户。这将限制由该用户执行的扩展查询对集群的影响。
旁注; this stackoverflow answer声明,某些查询仍然可以绕过timeout/terminate_after标志,例如
script
.terminate_after
限制了在每个碎片上搜索的文档数量,这可能是一个备用选项,或者如果超时太高或由于某种原因被忽略,甚至是另一个备份。长期分析
这个答案可能需要更多的工作,但是您可以保存有关执行的查询和所用时间的统计信息。
在这种情况下,您可能应该使用queryDSL的json表示,将它们保存在一个ElasticSearch索引中,沿着查询所用的时间,并保持类似查询所用的平均时间的聚合。
您可能会使用rollup特性来预先聚合所有平均值,并根据此索引检查查询(如果它是“可能扩展的查询”)。
这里的问题是要保存查询的哪一部分,以及哪些查询足够“相似”,可以考虑用于此聚合。
在查询中搜索关键字
DSL查询最终会转换为一个带有JSON主体的REST调用,因此使用JsonNode,您可以查找您“认为”会使查询扩展甚至限制“桶数量”等内容的特定子元素。
使用ObjectMapper,您可以将查询写入字符串,然后只查找关键字,这将是最简单的解决方案。
我们知道有一些特定的功能需要Elasticsearch的大量资源,并且可能需要很长时间才能完成,所以这些功能可以通过这个答案作为“第一道防线”来限制。
示例:突出显示脚本search_analyzers等...
因此,虽然这个答案是最天真的,但它可能是一个快速的胜利,而你的工作是一个长期的解决方案,需要分析。
k3fezbri2#
除了Dima给出的答案和一些很好的建议之外,下面是一个昂贵/缓慢查询的常见嫌疑犯列表:https://blog.bigdataboutique.com/2022/10/expensive-queries-in-elasticsearch-and-opensearch-a83194
一般来说,我们会将讨论分为三部分:
1.这是慢的查询吗?请参阅上面的列表了解常见的问题。顺便说一下,其中一些问题可以通过在群集设置中将
search.allow_expensive_queries
设置为false
来禁用。1.还是聚合请求?
1.也许是集群不堪重负而使查询变慢,而不是实际的查询。
解决这个问题的唯一方法是查看一段时间内的集群指标,并将其与慢速查询相关联。您也可以收集所有查询并分析它们以找出可疑的问题,并将其与延迟相关联。通常这会突出一些可以改进的地方(例如更好地使用缓存等)。