最近收到一位读者的技术求助:如何精准统计Elasticsearch集群每小时/每天的新增文档数和存储量?
一开始我也没有意识这个问题是可能有优雅的解法的,但读者后续的思路,给了我一个很好的提示:
无独有偶,就在同一天,另一位客户也向我咨询了类似的问题。一下子调动起了我的兴趣,让我决心深入研究一番,看看能否找到最佳解决方案。
因此,本文中结合使用.monitoring-es-*
索引的思路,为你揭秘最实用的,最优雅解决方案!
首先,为什么会有那么多同学来问类似的问题?
其实日增数据是在日志分析里,是做集群规划数非常重要的一个数据指标。想象一下,在一个大型的企业级日志系统中,每天产生的日志数据量通常都在TB级别。基础架构的同学们需要依据这些日增数据,合理规划集群的硬件资源,例如服务器的数量、存储容量等。如果不能准确掌握日增数据,就很容易导致资源配置不合理,要么造成资源浪费,要么因资源不足而影响系统性能。
但这个数据的统计工作,却也常常让基础架构的同学们头疼不已。一方面,ES 本身并不直接提供 “日增数据” 的 API,这就意味着他们无法通过简单的调用接口来获取所需数据。另一方面,总不能对每个接入的业务系统都逐一进行问卷调查,询问其每天产生的数据量,或者去统计的原始日志,因为这显然既耗时又费力,而且极易出错。
而ES本身的监控功能,为这个需求提供了一个很好的解决方案的基础。
Elasticsearch每10秒自动采集集群状态快照,存储于.monitoring-es-*
索引中。这些时序数据为日增统计提供了完美的数据基础:
{
"index_stats.primaries.docs.count": 1200000, //当天主分片文档数(真实数据量)
"index_stats.total.docs.count": 2400000, //当天总分片文档数(含副本)
"index_stats.primaries.store.size_in_bytes": 5368709120, //当天主分片存储
"index_stats.total.store.size_in_bytes": 10737418240 //当天总分片存储
}
但需要注意的是,这些字段记录的是某段时间内的状态数据,并且该值会持续记录。如果我们直接对其进行聚合操作,那必然得到的每个状态值的和。例如,我们执行以下查询语句:
POST /.monitoring - es - 7 - 2025.03.30/_search
{
"size": 0,
"aggs": {
"storage_per_day": {
"date_histogram": {
"field": "source_node.timestamp",
"calendar_interval": "day"
},
"aggs": {
"total_storage": {
"sum": {
"field": "node_stats.indices.store.size_in_bytes"
}
}
}
}
}
}
这显然是错的,因为,我们需要的只是最终值。
但是,这个错误的聚合却为我们打开了一扇新的大门。因为这个字段的值是累加的,所以当天的最大值,实际上就等同于今天数据的写入个数和存储量。有了这个关键的思路,我们就离解决问题不远了。
有了上面的思路,我们已经能够得出一个初始的解决方案。我们需要做的,就是更正聚合方式,并用更直观的数据来展示。
为了得出一个赏心悦目的表格,冗长的DSL以及返回的阅读不便的JSON,显然无法满足我们的需求。
而借助Elasticsearch上最新的ES|QL所提供的各种定制数据的能力,我们可以非常优雅的处理这个问题:
FROM .monitoring-es-*
| STATS
daily_docs = MAX(index_stats.primaries.docs.count),
daily_size_gb = ROUND(MAX(index_stats.primaries.store.size_in_bytes)/1073741824, 2)
BY date = BUCKET(source_node.timestamp, 1 day)
| SORT date
相信稍微有点数据库基础的同学都能快速读懂上面的 ES|QL:从以 .monitoring-es-*
开头的索引中获取数据,然后进行统计操作。
具体来说,它通过
index_stats.primaries.docs.count
(主分片文档数)取最大值得到出每日的文档数量(daily_docs),; index_stats.primaries.store.size_in_bytes
(主分片存储大小)取最大值,计算每日的存储大小(daily_size_gb),再除以 1073741824 并保留两位小数得到 GB 单位的值。将这段代码在Dev Tools或者Discovery界面中运行,你将的到一个统计的图表和表格:
如果要更进一步,我们不仅可以使用ES|QL处理数据,还可以使用更多的Elastic Stack中自带的能力来丰富解决方案:
通过本文的介绍,相信你已经掌握了使用 ES|QL 精准统计 ES 集群日增数据的方法,如果你觉得这个方案解决了你的痛点,或者有更好的实现思路,欢迎在评论区交流!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。