写点什么

使用 INFINI Gateway 保护 Elasticsearch 集群之阻断不合理的查询

作者:极限实验室
  • 2025-02-19
    北京
  • 本文字数:1655 字

    阅读完需:约 5 分钟

使用 INFINI Gateway 保护 Elasticsearch 集群之阻断不合理的查询

本文将探讨如何使用 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 集群,避免引发集群性能问题。对业务上合理的需求,我们可以进一步沟通,确定合理的方案。

发布于: 刚刚阅读数: 4
用户头像

简单、易用、极致、创新 2021-11-22 加入

极限实验室(INFINI Labs)致力于打造极致易用的数据探索与分析体验。

评论

发布
暂无评论
使用 INFINI Gateway 保护 Elasticsearch 集群之阻断不合理的查询_elasticsearch_极限实验室_InfoQ写作社区