你是否曾经查看你的索引,想要了解更多关于存储消耗的细节?或者你使用默认设置导入了自定义数据,想知道数据建模的哪些部分可以产生最大的影响?在这篇博客文章中,我们将探讨如何使用 Elastic 最近推出的 磁盘使用 API 来回答这些问题。
在 Elastic,我们与客户合作时,最常改进的领域之一就是索引映射配置。缺乏映射或使用错误的类型会增加你的 Elastic 部署的存储使用量。本文将帮助你理解哪些字段对存储占用影响最大,以及如何通过最佳实践配置来优化存储消耗。
如果你还没有使用 Elastic,可以通过 Elastic Cloud 创建一个托管的 Elasticsearch 服务部署。部署包括一个用于存储和搜索数据的 Elasticsearch 集群,以及一个用于可视化和管理数据的 Kibana 实例。有关更多信息,请参阅 启动 Elastic Stack。我建议在开发或测试环境中进行本次练习。
你还需要一些数据存储在 Elasticsearch 索引中进行分析。如果你刚创建了一个新的集群,可以通过 使用 Kibana 添加一些示例数据。在我的例子中,我使用了一些通过 Filebeat 导入的日志数据。
如果你使用 Elastic 的 Beats 或 Elastic Agent 索引数据,这些数据很可能已经按照 Elastic 的最佳实践进行了建模。当然,这非常棒,但也使得这个练习变得不那么有趣。幸运的是,我们可以通过将数据模型复制到没有映射配置的索引中来轻松丢弃数据模型。我选择了我的一个索引,并使用 Kibana 开发工具执行了以下重索引操作:
POST _reindex/
{
"source": {
"index": "filebeat-7.16.2-2022.01.06-000001"
},
"dest": {
"index": "nomapping-filebeat"
}
}
注意,我选择了一个以不匹配任何 Elastic 标准索引模式的前缀开头的目标索引名称。这确保不会从我的索引模板自动应用映射。
有了两个索引副本,一个有适当的映射,另一个没有,我们将能够在后面的博客文章中进行并排比较。
最后的前提是 jq,这是一个非常棒的 JSON 操作工具。我们将使用 jq 将 API 响应转换为文档列表,然后可以轻松地使用 Kibana 导入到 Elasticsearch 中。这将使得使用 Kibana 的 Discover 界面分析 API 响应变得更容易。
调用 磁盘使用 API 非常简单,只需前往 Kibana 开发工具并发出类似的请求:
POST nomapping-filebeat/_disk_usage?run_expensive_tasks=true
注意,run_expensive_tasks
参数是必需的,通过提供它,我承认我正在给集群增加额外的负载。这也是我之前建议在非生产集群中进行此练习的原因。
这是我的响应的顶部部分:
{
"_shards" : {
"total" : 1,
"successful" : 1,
"failed" : 0
},
"nomapping-filebeat" : {
"store_size" : "23.3mb",
"store_size_in_bytes" : 24498333,
"all_fields" : {
"total" : "22.7mb",
"total_in_bytes" : 23820161,
"inverted_index" : {
"total" : "9.9mb",
"total_in_bytes" : 10413531
},
"stored_fields" : "8mb",
"stored_fields_in_bytes" : 8404459,
"doc_values" : "3.1mb",
"doc_values_in_bytes" : 3284983,
"points" : "1.1mb",
"points_in_bytes" : 1237784,
"norms" : "468.1kb",
"norms_in_bytes" : 479404,
"term_vectors" : "0b",
"term_vectors_in_bytes" : 0
}
响应提供了整个索引的存储使用情况的详细信息。我们可以看到倒排索引是最大的因素,其次是存储字段和文档值。
在响应的进一步部分,我得到了每个字段的详细信息,包括 host.name
字段。
"fields" : {
…
"host.name" : {
"total" : "23.2kb",
"total_in_bytes" : 23842,
"inverted_index" : {
"total" : "23.2kb",
"total_in_bytes" : 23842
},
…
我们可以很容易地对 API 结果感到满意。通过在响应标签中使用 CTRL-F 功能并搜索“mb”(即兆字节),我们可以快速识别索引中的几个大字段。不过,让我们更进一步,看看如何快速重新格式化响应并使用 Kibana 进行分析。
将 API 结果复制粘贴到你喜欢的文本编辑器中,并将其保存为文件,在我的例子中是 disk-usage-filebeat.json
。然后运行以下命令,替换 nomapping-filebeat
为你的索引名称,替换 disk-usage-filebeat.json
为你最近保存的文件:
jq -c '.["nomapping-filebeat"].fields | to_entries | map({field: .key} + .value) | .[]' disk-usage-filebeat.json > disk-usage-ld.json
该命令将 JSON 转换为对象列表,每个对象包括字段名称和相关的使用数据,并输出换行符分隔的 JSON。有关更多信息,请参阅 jq 手册。
现在我们可以使用 Kibana 中的 数据可视化工具 上传数据,找到机器学习 -> 数据可视化工具。导航到可视化工具,点击导入文件并上传你的 disk-usage-ld.json
文件。结果页面应包括类似于以下截图的字段,与 API 响应中的字段分析相匹配。
向下滚动,点击导入并命名存储磁盘使用数据的索引。确保选中“创建索引模式”复选框。
正如你所见,我命名我的索引为 disk-usage
。在下一个屏幕上点击索引模式管理。你也可以通过主菜单导航:堆栈管理 -> 索引模式。
我们将使用 Kibana 中的 格式化功能 来提高字节字段的可读性。对于以下字段,点击编辑并选择字节作为格式:
doc_values_in_bytes
inverted_index.total_in_bytes
stored_fields_in_bytes
total_in_bytes
提示:在搜索字段中输入 bytes 可以快速找到这些字段,如下图所示。
现在我们准备好可视化我们的字段数据了。导航到 Discover 并选择 disk-usage 索引模式。添加以下列:
按 total_in_bytes 降序排序。
正如你所见,我最大的字段是 _source。这是一个内置字段,存储原始文档,我们几乎总是想保留它。接下来的两个字段是 host.mac 和 host.ip。进一步向下看,我们还可以看到相同字段带有 .keyword 后缀。根据 Elasticsearch 的 动态映射默认值,这些字段被设置为带有关键字多字段的文本字段。我还注意到,文本字段的存储空间被倒排索引占用,而关键字字段主要由文档值占用,这些文档值用于聚合和排序。
将文本和关键字大小加在一起,总大小为:
让我们导航到 开发工具 并查看原始的 filebeat 索引。这个索引已经应用了 Elastic Common Schema 映射。
我使用以下命令获取原始索引的磁盘使用信息:
POST filebeat-7.16.2-2022.01.06-000001/_disk_usage?run_expensive_tasks=true
从响应中,我读取到 host.ip 和 host.mac 字段的以下信息:
"host.ip" : {
"total" : "1.3mb"
…
"host.mac" : {
"total" : "492.1kb",
…
可以看出,存储使用量减少了 2-5 倍。要查看映射,我们可以使用以下命令获取:
GET filebeat-7.16.2-2022.01.06-000001/_mapping/field/host.ip,host.mac
我可以看到 host.ip 被映射为 ip 类型,host.mac 被映射为关键字类型。在大多数情况下,存储在这些字段中的数据类型将用于精确过滤、聚合和排序,这意味着将它们映射为文本字段对分析没有额外价值,并且在集群中占用了额外的存储空间。
在这篇博客文章中,我们看到了如何使用磁盘使用 API 来了解哪些字段在存储利用率方面最昂贵。我们使用 jq 格式化 API 响应,并使用数据可视化工具将其重新导入 Elastic,以便在 Discover 中分析数据。我们还看到了适当的映射如何显著减少存储占用。那么,如何优化我们索引中的存储使用呢?
通过使用 Elastic 的 集成,无论是通过 Beats 还是 Elastic Agent,字段映射都会在数据导入时自动创建。请注意,如果你不直接将数据发送到 Elasticsearch,例如通过 Logstash 发送 Filebeat 数据,则可能需要手动加载索引模板。
如果你使用的是自定义数据,通常需要手动配置映射。为了确保你的映射被应用,将其定义在具有适当索引模式的 索引模板 中。
快速映射单个字段会变得繁琐。对于大多数机器生成的数据,我们通常希望将大部分字符串映射为关键字类型,因此包括如下示例的 动态模板 将节省大量时间。不要忘记为 IP 和用于自由文本搜索的文本(如标准字段“message”)添加特定映射。
"mappings": {
"dynamic_templates": [
{
"strings_as_keyword" : {
"match_mapping_type" : "string",
"mapping" : {
"ignore_above" : 1024,
"type" : "keyword"
}
}
}
]
}
在命名和分配字段类型时,我们建议参考 Elastic Common Schema。它将帮助你构建一致的数据模型,并允许你在 Kibana 的应用程序中查看自定义数据。
一个稍微偏离主题但重要的工具是 数据层。通过使用数据层,你可以在数据老化时将其移动到更便宜的硬件中。我们的冷冻层甚至允许你 将数据存储在 Blob 存储中,这显著降低了成本,并且适用于不常访问的数据或在较慢查询响应可以接受时。使用 Elastic Cloud 管理数据层是最简单的方式,请查看我们的 数据管理最佳实践 以开始使用。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有