头图

本文将探讨如何使用 INFINI Gateway 阻止不合理的查询发送到 Elasticsearch,此方法同样适用于 Opensearch 和 Easysearch

在以往处理 Elasticsearch OOM(内存溢出)问题的经验中,我们发现许多案例是由于查询操作导致节点出现 OOM 的情况。经过调查,这些案例主要分为两类:一类是由于查询吞吐量超出了集群的处理能力,另一类则是在执行某些不合理的查询时触发了 OOM。

具体来说:

  • 查询吞吐量过高:当查询请求的频率或复杂度超过了集群的处理能力时,可能会导致节点内存耗尽,从而引发 OOM。
  • 执行不合理查询:某些特殊类型的查询(例如涉及大量嵌套、深度分页或复杂的聚合操作)可能需要大量的内存资源,在执行过程中也可能导致 OOM。

通过识别并优化这些查询模式,可以有效减少 OOM 事件的发生。针对查询吞吐量过高的情况,可以参考之前的文章来管理查询吞吐。接下来的内容将介绍如何阻挡不合理查询,保护集群稳定。

不合理查询

不合理查询是指那些消耗过多系统资源(如 CPU、内存)、设计复杂、执行时间过长或需要大量计算资源的查询。这类查询不仅会导致高负载和资源耗尽,影响整个集群的稳定性和响应速度,还可能对用户体验产生负面影响。

典型的不合理查询包括但不限于:

  • 嵌套聚合查询
  • 使用复杂的正则表达式进行模糊匹配
  • 深度分页查询(如 from: 10000, size: 10)
  • 脚本查询(Script Query)
  • 大规模嵌套聚合查询

为了防止这些查询对 Elasticsearch 集群造成影响,我们可以使用 INFINI Gateway 对这些查询进行阻断。

请求上下文

INFINI Gateway 运行环境中有非常多的信息可被利用,而请求上下文就是访问这些信息的入口。如请求来源、请求体信息等,都可使用关键字 \_ctx 作为前缀访问相应的上下文信息。

HTTP 请求内置的 \_ctx 上下文对象主要包括如下:

更多的上下文信息请访问文档

context_filter

Context Filter 是 INFINI Gateway 提供的一种在线过滤器,能够根据请求上下文来过滤流量。通过定义一组匹配规则,可以灵活地对流量进行筛选。该过滤器支持多种匹配模式,包括:

  • 前缀匹配
  • 后缀匹配
  • 模糊匹配
  • 正则匹配

对于匹配到的请求,可以直接阻断(拒绝)并返回自定义的消息。因此,关键点就是要明确不合理请求的关键字信息。

使用步骤

  1. 确定关键字信息:确定特殊查询请求中的关键特征或关键字。
  2. 配置匹配规则:在 context_filter 中定义相应的匹配规则,选择合适的匹配模式(如前缀、后缀、模糊或正则匹配)。
  3. 阻断请求:一旦匹配到这些关键字,INFINI Gateway 将自动阻断请求并返回指定的消息。

更多详细内容,请参阅相关 文档

举个例子

阻止 wildcard 查询(模糊匹配查询),我们先看一个 wildcard 查询的样子。

GET yf-test-1shard/_search
{
  "query": {
    "wildcard": {
      "path.keyword": {
        "value": "/a*"
      }
    }
  }
}

上面的查询,会查询 path 字段,所有以 /a 开头的文档。

第一步:我们可确定关键字是 wildcard,为了进一步限制是 wildcard 查询里的情况,我们可将关键字确定为 wildcard":,因为有时候查询 url 里会有 expand_wildcards 字样。

第二步:编辑 INFINI Gateway 默认配置文件,增加 context_filter 匹配规则。

- name: default_flow
  filter:
    - context_filter:
        context: _ctx.request.to_string
        message: "Request blocked. Reason: Forbidden. Please contact the administrator at 010-111111."
        status: 403
        action: deny
        must_not:
          contain:
            - 'wildcard":'

通过上面的修改,我们在 INFINI Gatway 的默认处理流程开头添加了 context_filter 过滤器,阻止查询请求种带关键字 wildcard": 的查询,并返回消息"Request blocked. Reason: Forbidden. Please contact the administrator at 010-111111."

第三步,测试 wildcard 请求能否被阻断。

可以看到,INFINI Gateway 成功阻止了 wildcard 查询,并返回了我们定义的信息。通过此方法,我们可以阻断高消耗类查询被发送到 ES 集群,避免引发集群性能问题。对业务上合理的需求,我们可以进一步沟通,确定合理的方案。


极限实验室
9 声望2 粉丝

极限科技,全称极限数据(北京)科技有限公司,是一家专注于实时搜索与数据分析的软件公司。旗下品牌极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。