aliyun-qos插件是阿里云Elasticsearch团队自研的插件,能够提高集群的稳定性。该插件能够实现集群级别的读写限流,在关键时刻对指定索引降级,将流量控制在合适范围内。例如当上游业务无法进行流量控制时,尤其对于读请求业务,可根据aliyun-qos插件设置的规则,按照业务的优先级进行适当的降级,来保护Elasticsearch服务的稳定性。
前提条件
已升级插件版本至最新版本。
您可以登录目标Elasticsearch实例的Kibana控制台,通过GET /_cat/plugins?v命令查看该插件的版本。
7.10版本Elasticsearch实例的插件最新版本为7.10.0_ali1.6.0.2,其他版本为<实例版本>-rc4。如果插件版本不是最新版本,您可通过以下方式处理:
- 7.10版本Elasticsearch实例:在控制台将内核升级到1.6.0版本,具体操作请参见升级版本。 
- 非7.10版本Elasticsearch实例:提交工单联系阿里云Elasticsearch技术工程师升级插件版本。升级后,需要您手动重启Elasticsearch实例生效。 
- 使用aliyun-qos插件时,如果版本低于rc4,会出现 - unsupported_operation_exception的报错。
- 当前仅支持升级6.7.0及以上版本的Elasticsearch实例中的aliyun-qos插件,低于6.7.0版本的Elasticsearch实例需要先将实例版本升级到6.7.0及以上,再升级插件版本。 
注意事项
- aliyun-qos插件为预装插件,限流功能默认关闭,不支持卸载。该插件是为了保护集群,提高稳定性,并不会精准计量读写流量。  说明 说明- 使用aliyun-qos插件前,您可以在插件配置页面查看是否已安装该插件。如果未安装,可参见安装或卸载系统默认插件进行安装。插件安装成功后不可卸载。 
- 在将aliyun-qos插件升级至最新版本时,您需要注意: - 由于新旧版本实现机制不同,升级过程中可能出现短暂限流失效,待master节点上的限流插件升级完成后会自动恢复。 
- 在新旧数据转换过程中,可能存在部分限流器转换失败的情况。如果转换失败,您需要执行如下命令重新转换。如果执行命令后报错,可多次重试,直至hasError为false。 - POST /_qos/limiter/ops/upgrade说明- 如果执行以上命令长时间不返回,则说明实例中没有旧版限流器,可忽略。 
 
评估阈值
为了不影响读写请求的执行效率,aliyun-qos插件会在集群级别进行限流,但并不会对集群中所有节点的读写流量进行严格精准的计量,可能会导致实际的流量有所偏差。因此在使用aliyun-qos插件前,可先参考如下规则评估限流阈值:
- 查询请求 - 查询请求的限流阈值 = 客户端查询请求到达Elasticsearch的端到端QPS(Query Per Second) 说明- 端到端QPS仅指查询请求到达协调节点的每秒请求数。 
- 写入请求 - 写入请求的限流阈值的计算规则与查询请求类似,但还需要根据副本数进行调整。 - 例如集群中有2个数据节点、1个索引,该索引有1个shard、1个副本,每次写入10 MB大小的数据。因为存在副本,所以每个数据节点上都会被写入10 MB大小的数据。另外X-Pack自身的Monitor、Audit、Watcher等任务同样会占用写入流量,设置阈值时需要预留出该部分的大小。 
开启限流功能
aliyun-qos插件的限流功能默认关闭,使用时需要先开启该功能。不同版本的aliyun-qos插件,开启限流功能的代码不同,具体如下。
本文中的命令均可在Kibana控制台上执行,详情请参见登录Kibana控制台。
| 7.10最新版本 | 其他版本 | 
|  |  | 
关闭限流功能
您可以通过将限流参数设置为false或null,关闭限流功能。aliyun-qos插件的版本不同,关闭限流功能的代码不同,具体如下。
| 关闭限流方式 | 7.10最新版本 | 其他版本 | 
| 将限流参数设置为false |  |  | 
| 将限流参数设置为null |  |  | 
配置限流器(7.10最新版本)
- 以下配置限流器的内容仅适用于7.10版本实例的aliyun-qos插件。 
- 限流器主要由两部分组成,limiters定义和tags定义。通过tags定义资源限制,通过limiters定义具体的限流类型和限流阈值。 
- 限流器分为普通限流器和默认限流器。通过将tags设置为**可以实现默认限流器。例如默认每个shard的流量,默认每个应用的QPS等。 
- 当请求超过限流值之后,Elasticsearch会拒绝之后发送的请求。 
- 限流器配置的具体示例,请参见配置限流器示例。 
PUT /_qos/limiter/<limiterName>
{
  "limiters": {
     ${action}.${limiter_type}:${threshold}
  },
  "tags": {
    ${tagName}:${tagValue}
  },
  "priority":0,               
  "params":{  
      "watchMode":true
  }
}| 参数 | 说明 | 可选值 | 
| action | 限流的action,用于限制不同类型的请求。 | 
 | 
| limiter_type | 限流类型。支持三大类: 
 | 
 | 
| threshold | 限流阈值。 | int范围内的整数,>=-1。 说明  部分类型支持带单位的字符串,具体请参见limiter_type说明。 | 
| tagName | tag名称。 | 
 | 
| tagValue | tag的值。 | 字符串,可为数组。如果为数组,则对应tag匹配数组中任意一个value即可。支持精确匹配、模糊匹配和任意值,例如: 
 | 
| priority | 优先级。 | int整数,默认为0。 说明  优先级越大,排序越靠前。当有多个默认限流器同时命中时,只有优先级最大的默认限流器会生效。 | 
| params | 高级参数。 | watchMode:是否启用观察模式,支持true和false(默认)。如果为true,Elasticsearch只会在metric中记录拒绝数,但不会实际限流。您可以通过API查看指标监控信息,用于提前验证限流效果,避免由于配置错误造成错误的限流。API的详细信息,请参见常见问题。 | 
配置限流器示例
设置查询QPS限流
通过设置查询索引每秒请求次数,限制协调节点每秒接收的查询请求数。当每秒接收的查询请求数超过限流值之后,Elasticsearch会拒绝接收请求。
index和index_patterns的值支持完整索引名称和索引通配符。aliyun-qos插件的版本不同,设置查询QPS限流的代码不同,具体如下。
| 操作 | 7.10最新版本 | 其他版本 | 
| 设置单个索引的查询QPS限流 |  |  | 
| 设置指定名称前缀的索引的查询QPS限流 |  |  | 
| 设置任意索引的查询QPS限流 | 说明  
 | 不支持。 | 
| 设置所有索引的查询总QPS限流 | 说明  
 |  | 
您可以定义多条不同的规则,只要请求命中任意一条规则,就会触发限流。
当您在客户端或Kibana控制台上执行数据查询操作时,如果查询QPS超过您设置的限流值,系统会显示如下报错信息。请根据报错信息适当减少查询QPS限流。aliyun-qos插件的版本不同,显示的报错信息不同,具体如下:
- 7.10最新版本 - { "error": { "root_cause": [ { "type": "status_exception", "reason": "search blocked, limited by [<limiterName>][search.qps](<limiterId>) threshold:[x]" } ], "type": "status_exception", "reason": "search blocked, limited by [<limiterName>][search.qps](<limiterId>) threshold:[x]" }, "status": 429 }
- 其他版本 - { "error": { "root_cause": [ { "type": "rate_limited_exception", "reason": "request indices:data/read/search rejected, limited by [l1:t*:1.0]" } ], "type": "rate_limited_exception", "reason": "request indices:data/read/search rejected, limited by [l1:t*:1.0]" }, "status": 429 }
设置写入TPS限流
通过设置写入索引每秒请求次数,限制协调节点每秒接收的写入请求数。当每秒接收的写入请求数超过限流值之后,Elasticsearch会拒绝接收请求。
index和index_patterns的值支持完整索引名称和索引通配符。aliyun-qos插件的版本不同,设置写入TPS限流的代码不同,具体如下。
| 7.10最新版本 | 其他版本 | 
|  | 不支持 | 
设置Bulk每秒写入大小限流
通过设置Bulk每秒写入的总字节数,限制协调节点每秒接收的写入字节数。当每秒接收的写入字节数超过限流值之后,Elasticsearch会拒绝接收请求。
index和index_patterns的值支持完整索引名称和索引通配符。aliyun-qos插件的版本不同,设置Bulk每秒写入大小限流的代码不同,具体如下。
| 7.10最新版本 | 其他版本 | 
|  |  | 
您可以定义多条不同的规则,只要请求命中任意一条规则,就会触发限流。
设置Bulk单次请求大小限流
通过设置Bulk单次请求的最大值,限制协调节点接收单次请求的写入字节数。当单次请求的写入字节数超过限流值之后,Elasticsearch会拒绝接收请求。
index和index_patterns的值支持完整索引名称和索引通配符。aliyun-qos插件的版本不同,设置Bulk单次请求大小限流的代码不同,具体如下。
| 7.10最新版本 | 其他版本 | 
|  |  | 
您可以定义多条不同的规则,只要请求命中任意一条规则,就会触发限流。
当您在客户端或Kibana控制台上执行数据写入操作时,如果单次请求的写入字节数超过设置的限流值,系统会显示如下报错信息。请根据报错信息适当减少单次请求的写入字节数。aliyun-qos插件的版本不同,显示的报错信息不同,具体如下:
- 7.10最新版本 - { "error" : { "root_cause" : [ { "type" : "status_exception", "reason" : "write_size blocked, limited by [<limiterName>][write.max_size_per_request](<limiterId>) threshold:[x] try acquire [x]" } ], "type" : "status_exception", "reason" : "write_size blocked, limited by [<limiterName>][write.max_size_per_request](<limiterId>) threshold:[x] try acquire [x]" }, "status" : 400 }
- 其他版本 - { "error": { "root_cause": [ { "type": "rate_limited_exception", "reason": "request indices:data/write/bulk rejected, limited by [b2:ByteSizePreSeconds:992.0]" } ], "type": "rate_limited_exception", "reason": "request indices:data/write/bulk rejected, limited by [b2:ByteSizePreSeconds:992.0]" }, "status": 413 }
设置查询shard并发个数限流
通过设置并发查询shard数,来降低集群压力。index和index_patterns的值支持完整索引名称和索引通配符。aliyun-qos插件的版本不同,设置查询shard并发个数限流的代码不同,具体如下。
| 7.10最新版本 | 其他版本 | 
|  | 不支持 | 
您可以定义多条不同的规则,只要请求命中任意一条规则,就会触发限流。
设置多个限流器配置
支持同时设置限流器的多个配置。index和index_patterns的值支持完整索引名称和索引通配符。aliyun-qos插件的版本不同,设置多个限流器配置的代码不同,具体如下。
| 7.10最新版本 | 其他版本 | 
|  | 不支持 | 
您可以定义多条不同的规则,只要请求命中任意一条规则,就会触发限流。
获取限流配置
aliyun-qos插件的版本不同,获取限流配置的代码不同,具体如下。
| 操作 | 7.10最新版本 | 其他版本 | 
| 获取所有限流配置 |  |  | 
| 获取单个指定的限流配置 |  |  | 
| 获取多个指定的限流配置 说明  多个限流器之间用英文逗号(,)分隔,不支持通配符。 |  |  | 
删除限流配置
aliyun-qos插件的版本不同,删除限流配置的代码不同,具体如下。
| 操作 | 7.10最新版本 | 其他版本 | 
| 删除单个指定的限流配置 |  |  | 
| 删除多个指定的限流配置 说明  多个限流器之间用英文逗号(,)分隔,不支持通配符。 |  |  | 
常见问题
Q:如何获取限流相关的指标监控信息?
A:可以通过以下API获取:
- 获取当前指标数据 - 获取当前所有指标数据 - GET /_qos/limiter/nodes/stats
- 获取当前指定{node}指标数据 - GET /_qos/limiter/nodes/{nodeId}/stats
- 获取当前指定{node}和{limiter}指标数据 - GET /_qos/limiter/nodes/{nodeId}/stats/{limiterIds}
 
- 获取历史指标数据 - 获取历史所有指标数据 - GET /_qos/limiter/metric
- 获取历史指定{limiter}指标数据 - GET /_qos/limiter/metric/{limiterId}