Elasticsearch&Kibana改进TopHits的设想
背景
大家在使用ES和Kibana的时候,应该都遇到过这样的场景:
假设有一个主机监控的任务,收集的数据格式为:时间戳、主机名、当前内存占用量,收集周期为每分钟收集一次。那么在Kibana中可能需要提供这样的报表,当前所有主机总体内存占用量。大家动手试试,在Kibana报表中,应该是做不到的。
我这里实际动手,作为示例解释下:
1、进入Kibana的DevTools页面,导入模拟数据
如上图,4条数据,两条是主机AAA的不同时间上报的内存占用量,另外两条是主机BBB的。
思考下,我们如何从这些数据中求出AAA、BBB的总内存占用?思考可得知,先需要求得AAA和BBB主机分别的最后一条上报数据,即图中第二条和第四条数据。然后将这两条数据的mem_used_mb相加。
顺着这个思路,我们继续。
2、用分组aggregation和TopHits aggregation求出AAA和BBB的最后一条上报数据
上图中,涉及到两个Aggregation,一个是terms agg,在ES中属于Buckets Agg,是可以携带子agg的。一个是top_hits agg,属于Metric Agg,是不可以携带子agg的。组合起来含义就是,按照host的值进行分组,每个分组中取按照@timestamp字段值倒排序的前一条文档
执行返回结果:
我们在kibana中看看是怎么图形化构造这个语句的(注意先在kibana中创建monitor索引对应的Pattern):
上图中,我们可以看到Kibana中和ES原生语法相比TopHits的内容多了个Field和一个Aggregate with需要填,这是Kibana界面上的一个优化,确保得出来的值是一个数字,而不是一条条记录。意思就是在求出来的记录上挑选一个字段求聚合的值,以便得到一个数字从而生成指标图。
好了,已经得到了每个主机的最后一条记录,如何求两个主机的mem_used_mb只和呢?ES有提供相关的Agg,叫sum_bucket agg,用于求其他bucket类型agg的多个分组数值只和。我们先看一个样例。
求得结果:
大家可以注意,上图中分组agg里面嵌套的是一种叫做max的agg,用于求mem_used_mb的最大值,而整个语句的效果相当于,求出每个主机记录中mem_used_mb字段最大一次的值,然后相加。这样很明显不是我们所需要的结果。那么为什么不用top_hits呢?
3、为什么top_hits不可以和sum_bucket配合
大家看看我们把max agg替换为top_hits agg后的结果,输入命令:
结果:
出错了!为什么呢?由解释可知sum_bucket只能接受分组中的值为一个单数字,并且结果字段名称要叫做”value”,而top_hits agg的结果只是一行行文档,不符合这个条件。
Kibana也知道ES这个限制,从而在sum_buket的构造页面中根本不提供接入top_hits的选项。
4、如何解决呢?
设想应该可以增加一个ES插件,扩展top_hits agg的行为,增加类似kibana界面优化上的aggregate with选项,将top_hits的输出变为一个单值,叫做”value”。同时kibana界面上开放相关适配。
这个能力已经在华为云云搜索服务中实现了,云搜索服务是基于开源的elasticsearch的一款云服务,并且做了很多增强,欢迎前往官网使用华为云CSS服务官网:
关于云搜索服务的其他功能介绍可以参考:
https://support.huaweicloud.com/usermanual-css/css_01_0007.html
- 点赞
- 收藏
- 关注作者
评论(0)