📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

配置项作用 #

search.allow_expensive_queries 配置项控制是否允许执行被认为是"昂贵"(expensive)的查询操作。昂贵查询通常指那些可能消耗大量资源(CPU、内存)或执行时间过长的查询类型,如脚本查询、正则表达式查询等。

配置项类型 #

该配置项为动态配置,可以在运行时通过集群设置 API 进行修改。

默认值 #

true(允许昂贵查询)

是否必需 #

可选配置项(有默认值)

取值范围 #

true  - 允许昂贵查询
false - 禁止昂贵查询

配置格式 #

# 默认配置(允许)
search.allow_expensive_queries: true

# 禁止昂贵查询
search.allow_expensive_queries: false

相关配置项 #

配置项默认值说明
search.allow_expensive_queriestrue允许昂贵查询
search.max_buckets65535最大聚合桶数
indices.query.bool.max_clause_count1024最大布尔子句数

工作原理 #

昂贵查询检查机制:

┌─────────────────────────────────────────────────────────────────┐
│                    昂贵查询检查流程                               │
└─────────────────────────────────────────────────────────────────┘

查询请求到达
    │
    ▼
检查 allow_expensive_queries
    │
    ├── true(允许)
    │   │
    │   └── 执行所有类型查询
    │       - 脚本查询 ✓
    │       - 正则表达式查询 ✓
    │       - 复杂聚合 ✓
    │
    └── false(禁止)
        │
        └── 检查查询类型
            │
            ├── 非昂贵查询 → 执行 ✓
            │   - 简单 term 查询
            │   - 基本匹配查询
            │
            └── 昂贵查询 → 拒绝 ✗
                │
                └── 返回错误:
                    "queries of type [XXX] are not allowed"

昂贵查询类型 #

常见昂贵查询类型:

1. 脚本查询 (Script Query)
    - 需要运行脚本引擎
    - CPU 密集型
    - 可能执行复杂计算

2. 正则表达式查询 (Regexp Query)
    - 复杂的正则匹配
    - 可能回溯导致性能问题
    - 字符越长越慢

3. 模糊查询 (Fuzzy Query)
    - 模糊匹配算法
    - 计算相似度
    - 可能生成大量查询

4. 复杂脚本聚合
    - 脚本化聚合
    - 大量数据处理
    - 内存密集型

5. span 查询系列
    - 复杂的位置查询
    - 计算密集型

使用场景 #

1. 默认配置(推荐) #

search.allow_expensive_queries: true

适用场景:

  • 大多数生产环境
  • 需要复杂查询功能
  • 有性能监控和限制

2. 禁止昂贵查询 #

search.allow_expensive_queries: false

适用场景:

  • 资源受限环境
  • 防止滥用
  • 多租户环境
  • 需要保护集群稳定性

3. 临时禁止 #

# 临时禁止昂贵查询,进行集群保护
PUT /_cluster/settings
{
  "transient": {
    "search.allow_expensive_queries": false
  }
}

适用场景:

  • 集群负载过高
  • 紧急性能问题
  • 维护操作

推荐设置建议 #

环境推荐值说明
生产环境true根据需要使用
资源受限false保护集群
多租户false防止滥用
开发测试true方便调试
受控访问true配合其他限制

性能影响分析 #

允许昂贵查询的影响:

优点:
    ✓ 支持复杂查询功能
    ✓ 灵活性高
    ✓ 满足业务需求

缺点:
    ✗ 可能消耗大量资源
    ✗ 可能影响其他查询
    ✗ 可能导致集群不稳定

禁止昂贵查询的影响:

优点:
    ✓ 保护集群资源
    ✓ 防止滥用
    ✓ 提高稳定性

缺点:
    ✗ 限制查询能力
    ✗ 可能影响业务
    ✗ 需要替代方案

查询替代方案 #

昂贵查询的替代方案:

1. 脚本查询 → 使用 runtime field
    - 脚本查询慢
    - runtime field 更高效
    - 可以缓存

2. 正则表达式查询 → 使用 wildcard/edge_ngram
    - 正则查询可能很慢
    - wildcard 查询更快
    - edge_ngram 适合前缀匹配

3. 复杂聚合 → 预聚合/分区
    - 复杂聚合消耗资源
    - 使用 transform 预聚合
    - 使用分区聚合

4. 大范围查询 → 使用索引策略
    - 时间范围查询
    - 使用索引生命周期管理
    - 按时间分索引

动态配置示例 #

# 禁止昂贵查询
PUT /_cluster/settings
{
  "transient": {
    "search.allow_expensive_queries": false
  }
}

# 允许昂贵查询
PUT /_cluster/settings
{
  "transient": {
    "search.allow_expensive_queries": true
  }
}

# 查询当前配置
GET /_cluster/settings?filter_path=*.search.allow_expensive_queries

监控建议 #

# 查看当前配置
GET /_cluster/settings?filter_path=*.search.allow_expensive_queries

# 查看慢查询
GET /_tasks?actions=*search&detailed=true&pretty

# 查看正在执行的查询
GET /_tasks?group_by=parents&pretty

# 查看查询性能统计
GET /_nodes/stats/indices/search?filter_path=**.query_total,**.query_time_in_millis

错误示例 #

禁止昂贵查询后的错误信息:

# 尝试执行脚本查询
GET /_search
{
  "query": {
    "script": {
      "script": {
        "source": "doc['field'].value > 100"
      }
    }
  }
}

# 错误响应
{
  "error": {
    "root_cause": [
      {
        "type": "illegal_argument_exception",
        "reason": "queries of type [script] are not allowed"
      }
    ]
  }
}

安全考虑 #

多租户环境的安全考虑:

问题:
    - 恶意用户可能执行昂贵查询
    - 可能消耗所有资源
    - 影响其他租户

保护措施:
    1. 禁止昂贵查询
       search.allow_expensive_queries: false

    2. 限制查询复杂度
       indices.query.bool.max_clause_count: 500

    3. 限制聚合桶数
       search.max_buckets: 10000

    4. 使用查询超时
       timeout: 30s

    5. 使用字段数据缓存限制
       indices.fielddata.cache.size: 20%

注意事项 #

  1. 动态更新:此配置为动态配置,可在线修改
  2. 查询类型:影响多种查询类型
  3. 业务影响:禁用可能影响业务功能
  4. 替代方案:考虑使用更高效的查询方式
  5. 监控配合:配合慢查询日志使用
  6. 渐进调整:可以先监控,再决定是否禁止