更新时间:2023-06-20 GMT+08:00

内存流控

背景信息

Elasticsearch内部有熔断器机制,可以配置内存使用的阈值,当节点内存超过指定值,触发熔断,请求操作终止。但是Elasticsearch在调用API时没有判断当前的堆内存使用量,如果在请求处理过程中计算,即使熔断也会造成堆内存的消耗,频繁熔断会导致节点不可用,同时熔断器不支持单个请求的熔断阈值配置。但是,当在Rest请求入口处设置堆内存使用限制时,可以阻断API的请求,达到保护节点的目的。而内存流控可以配置节点全局流控和基于单个请求Path的精细化内存控制,其中单个请求Path的流控通过配置请求Path和堆内存阈值,在请求处理前判断配置的堆内存阈值,超过阈值中断当前的请求Path。

  • 开启内存流控会消耗部分请求性能。
  • 开启内存流控会导致Kibana的部分search请求失败。
  • ES 551版本开启内存流控会导致_mget请求被拦截,Kibana访问异常,可以把_mget请求加入请求白名单规避。

在开启或关闭集群的内存流控时,执行命令涉及的配置参数如下:

表1 内存流控的配置参数说明

配置名

类型

说明

flowcontrol.memory.enabled

Boolean

内存流控开关,默认关闭,开启内存流控对节点性能有些许影响。

取值范围:true、false

默认值:false

flowcontrol.memory.allow_path

List<String>

内存流控白名单Path。

配置的路径不参与内存流控,可以支持通配符配置。集群控制的查询类接口默认放通,不参与内存流控,避免内存达到阈值,不能查询集群信息。

例如:

  • "flowcontrol.memory.allow_path": "/index/_search",
  • "flowcontrol.memory.allow_path": "/index*/_search",
  • "flowcontrol.memory.allow_path": ["/index/_search", "/index1/_bulk"],

支持最大配置10个Path,每个Path最大长度限制小于32。

默认值为为空。

flowcontrol.memory.heap_limit

String

限制节点全局堆内存的最大使用率。不能低于堆内存的10%。

取值范围:10%-100%

默认值:90%

flowcontrol.memory.*.filter_path

String

配置需要进行内存流控的访问Path,控制单个请求Path的堆内存使用阈值。

默认值 "**", 表示匹配所有的路径。如果只配置了单路径“flowcontrol.memory.heap_limit”,没有配置“flowcontrol.memory.*.filter_path”,表示除去白名单外的所有path都影响。白名单规则优先于单路径规则,如果一个路径同时配置了“flowcontrol.memory.allow_path”和“flowcontrol.memory.*.filter_path”, 此请求路径会被允许。

例如同时配置了“flowcontrol.memory.allow_path”和“flowcontrol.memory.*.filter_path”,其中flowcontrol.memory.*.filter_path="abc/_search"且flowcontrol.memory.allow_path="abc/_search",此种情况abc/_search将不被流控。

最大长度:32

flowcontrol.memory.*.heap_limit

String

配置请求Path的堆内存阈值,堆内存超过阈值触发流控。

取值范围:0%-100%

默认值:90%

操作步骤

  1. 登录云搜索服务管理控制台。
  2. “集群管理”页面选择目标集群,单击操作列“Kibana”,登录Kibana界面。
  3. 单击左侧导航栏的“Dev Tools”,执行命令开启或关闭内存流控。
    • 开启内存流控
      PUT /_cluster/settings
      {
        "persistent": {
          "flowcontrol.memory.enabled": true,
          "flowcontrol.memory.allow_path": "/index/_search",
          "flowcontrol.memory.heap_limit": "85%"
        }
      }
    • 开启单个请求Path的内存流控

      基于单个索引和请求Path设置堆内存使用阈值,可以基于此规则做优先级调度。

      PUT /_cluster/settings
      {
        "persistent": {
          "flowcontrol.memory.enabled": true,
          "flowcontrol.memory": {
            "flowcontrol_search": {
              "filter_path": "index1/_search",
              "heap_limit": "50%"
            },
            "flowcontrol_bulk": {
              "filter_path": "index*/_bulk",
              "heap_limit": "50%"
            }
          }
        }
      }
    • 删除单个请求Path的内存流控配置
      PUT /_cluster/settings
      {
        "persistent": {
          "flowcontrol.memory.enabled": true,
          "flowcontrol.memory": {
            "flowcontrol_search": {
              "filter_path": null,
              "heap_limit": null
            }
          }
        }
      }
    • 关闭集群内存流控
      PUT /_cluster/settings
      {
        "persistent": {
          "flowcontrol.memory.enabled": false
        }
      }