--- title: "允许昂贵查询配置" date: 2026-02-22 lastmod: 2026-02-22 description: "控制是否允许执行昂贵查询的配置项说明" tags: ["搜索配置", "性能保护", "查询控制"] summary: "配置项作用 # search.allow_expensive_queries 配置项控制是否允许执行被认为是"昂贵"(expensive)的查询操作。昂贵查询通常指那些可能消耗大量资源(CPU、内存)或执行时间过长的查询类型,如脚本查询、正则表达式查询等。 配置项类型 # 该配置项为动态配置,可以在运行时通过集群设置 API 进行修改。 默认值 # true(允许昂贵查询) 是否必需 # 可选配置项(有默认值) 取值范围 # true - 允许昂贵查询 false - 禁止昂贵查询 配置格式 # # 默认配置(允许) search.allow_expensive_queries: true # 禁止昂贵查询 search.allow_expensive_queries: false 相关配置项 # 配置项 默认值 说明 search.allow_expensive_queries true 允许昂贵查询 search.max_buckets 65535 最大聚合桶数 indices.query.bool.max_clause_count 1024 最大布尔子句数 工作原理 # 昂贵查询检查机制:" --- ## 配置项作用 `search.allow_expensive_queries` 配置项控制是否允许执行被认为是"昂贵"(expensive)的查询操作。昂贵查询通常指那些可能消耗大量资源(CPU、内存)或执行时间过长的查询类型,如脚本查询、正则表达式查询等。 ## 配置项类型 该配置项为**动态配置**,可以在运行时通过集群设置 API 进行修改。 ## 默认值 ``` true(允许昂贵查询) ``` ## 是否必需 **可选配置项**(有默认值) ## 取值范围 ``` true - 允许昂贵查询 false - 禁止昂贵查询 ``` ## 配置格式 ```yaml # 默认配置(允许) search.allow_expensive_queries: true # 禁止昂贵查询 search.allow_expensive_queries: false ``` ## 相关配置项 | 配置项 | 默认值 | 说明 | |-------|-------|------| | `search.allow_expensive_queries` | true | 允许昂贵查询 | | `search.max_buckets` | 65535 | 最大聚合桶数 | | `indices.query.bool.max_clause_count` | 1024 | 最大布尔子句数 | ## 工作原理 昂贵查询检查机制: ``` ┌─────────────────────────────────────────────────────────────────┐ │ 昂贵查询检查流程 │ └─────────────────────────────────────────────────────────────────┘ 查询请求到达 │ ▼ 检查 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. 默认配置(推荐) ```yaml search.allow_expensive_queries: true ``` **适用场景:** - 大多数生产环境 - 需要复杂查询功能 - 有性能监控和限制 ### 2. 禁止昂贵查询 ```yaml search.allow_expensive_queries: false ``` **适用场景:** - 资源受限环境 - 防止滥用 - 多租户环境 - 需要保护集群稳定性 ### 3. 临时禁止 ```bash # 临时禁止昂贵查询,进行集群保护 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. 大范围查询 → 使用索引策略 - 时间范围查询 - 使用索引生命周期管理 - 按时间分索引 ``` ## 动态配置示例 ```bash # 禁止昂贵查询 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 ``` ## 监控建议 ```bash # 查看当前配置 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. **渐进调整**:可以先监控,再决定是否禁止