映射爆炸
编辑映射爆炸
编辑Elasticsearch 的搜索和 Kibana 的 Discover Javascript 渲染依赖于搜索的底层索引的总 映射字段数量,包含所有映射深度。当这个总数过高或呈指数级增长时,我们称之为“映射爆炸”。字段数量达到如此高的程度并不常见,通常表明上游文档格式存在问题,此博客文章对此进行了说明。
映射爆炸可能表现为以下性能症状:
- CAT 节点 报告主节点和/或承载索引分片的节点上的高堆内存或 CPU 使用率。这可能会升级为节点暂时无响应和/或主节点过载。
- CAT 任务 报告仅与该索引或这些索引相关的长时间搜索时长,即使是简单的搜索也是如此。
- CAT 任务 报告仅与该索引或这些索引相关的长时间索引时长。这通常与挂起的集群任务相关,这些任务报告协调节点正在等待所有其他节点确认它们已收到映射更新请求。
- Discover 的 通配符字段 页面加载 API 命令或 Dev Tools 页面刷新的自动完成 API 命令花费很长时间(超过 10 秒)或在浏览器的开发者工具网络选项卡中超时。更多信息,请参考我们的 Discover 故障排除指南。
- Discover 的 可用字段 在浏览器的开发者工具性能选项卡中花费很长时间编译 Javascript。这可能会升级为浏览器页面暂时无响应。
- Kibana 的 告警 或 安全规则 可能出现错误
内容长度 (X) 大于允许的最大字符串长度 (Y)
,其中X
是尝试的有效负载,Y
是 Kibana 的server-maxPayload
。 - Elasticsearch 启动时长过长。
预防或准备
编辑映射 初始化后无法减少字段。Elasticsearch 索引默认使用 动态映射,除非它与覆盖 index.mapping.total_fields.limit
结合使用,否则通常不会造成问题。默认的 1000
限制被认为是相当宽松的,虽然覆盖为 10000
不会根据用例产生明显的影响。但是,举个不好的例子,如果覆盖为 100000
并且此限制被映射总数达到,则通常会产生严重的性能影响。
如果您的索引映射字段预计包含一组大型的任意键,您可以考虑:
- 将
index.mapping.total_fields.ignore_dynamic_beyond_limit
设置为true
。此设置不会拒绝超过字段限制的文档,而是在达到限制后忽略动态字段。 - 使用 扁平化 数据类型。但是,请注意,扁平化对象在 Kibana 中尚不支持。例如,这可以应用于子映射,例如 {
host.name
,host.os
,host.version
}。仍然可以通过 运行时字段 访问所需的字段。 - 禁用 动态映射。这不会影响当前的索引映射,但可以通过 索引模板 应用于未来的索引。
修改为 嵌套 数据类型无法解决核心问题。
检查问题
编辑要确认索引的字段总数以检查映射爆炸:
- 检查 Elasticsearch 集群日志中是否存在错误
索引 [Y] 中的总字段数限制 [X] 已超过
,其中X
是index.mapping.total_fields.limit
的值,Y
是您的索引。相关的摄取源日志错误将是添加新字段 [Z] 时超过总字段数限制 [X]
,其中Z
是尝试添加的新字段。 - 对于顶级字段,轮询 字段功能 以获取
fields=*
。 - 搜索 获取映射 的输出以查找
"type"
。 -
如果您倾向于使用 第三方工具 JQ,您可以处理 获取映射
mapping.json
输出。$ cat mapping.json | jq -c 'to_entries[]| .key as $index| [.value.mappings| to_entries[]|select(.key=="properties") | {(.key):([.value|..|.type?|select(.!=null)]|length)}]| map(to_entries)| flatten| from_entries| ([to_entries[].value]|add)| {index: $index, field_count: .}'
您可以使用 分析索引磁盘使用情况 来查找从未或很少填充的字段,作为简单的解决方案。
复杂的爆炸
编辑映射爆炸还包括单个索引字段总数在限制范围内,但组合索引字段总数非常高的情况。通常情况下,症状首先会在 数据视图 上被注意到,并通过 解析索引 API 追溯到单个索引或索引子集。
但是,虽然不太常见,但仅在底层索引组合上才会出现映射爆炸的情况也是可能的。例如,如果 数据流 的底层索引都达到了字段总数限制,但每个索引都包含彼此唯一的字段。
这种情况最容易通过添加 数据视图 并检查其 字段 选项卡中的总字段计数来发现。此统计信息确实会告诉您总字段数,而不仅仅是 index:true
的位置,但它可以作为良好的基线。
如果您的问题仅通过 数据视图 出现,如果您没有使用 多字段,您可以考虑此菜单的 字段过滤器。或者,您可以考虑更具针对性的索引模式或使用否定模式来过滤掉有问题的索引。例如,如果 logs-*
的字段计数过高是因为有问题的底层索引 logs-lotsOfFields-*
,则您可以更新为 logs-*,-logs-lotsOfFields-*
或 logs-iMeantThisAnyway-*
。
解决方法
编辑映射爆炸不容易解决,因此最好通过上述方法进行预防。遇到这种情况通常表示上游数据更改或规划失败。如果遇到这种情况,我们建议您检查您的数据架构。以下选项是对本页前面讨论的选项的补充;应根据最佳用例适用。
拆分索引 无法解决核心问题。