近期,突然要做一个大量数据聚合的任务,由于原始数据在ES里面,所以针对ElasticSearch的聚合能力进行了一个研究,里面有些比较好玩的内容,这里分享给大家
ElasticSearch的聚合任务
由于是多个对大量表进行聚合的任务,且耗时长,数据量大,用传统的方法:
ElasticSearch查询后,再写入,需要进行两次IO,所以优先看看ES自己有没有这样的能力
看了一下果然有,叫rollup,看名字就是可以聚合
这里把网上的资料整理下:
这要分为两个方法,一个是用语句创建,一个是用kibana的IDE创建
先看第一种
语句创建
前提条件
- 确保您已拥有manage或manage_rollup权限。 使用RollUp必须要有manage或manage_rollup权限,详情请参见Security Privileges。
背景信息
本文的需求场景如下:
- 每15分钟定时汇总整小时内instanceId的networkoutTraffic、networkinTraffic流量。
- 通过Kibana大图展示指定instanceId的入口流量和出口流量。
本文以monitordata-logstash-sls-*为前缀的索引为例,该索引以每天创建一个索引的规则切分索引。索引的Mapping格式如下。
代码语言:javascript复制"monitordata-logstash-sls-2020-04-05" : {
"mappings" : {
"properties" : {
"@timestamp" : {
"type" : "date"
},
"__source__" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"disk_type" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
}
},
"host" : {
"type" : "keyword"
},
"instanceId" : {
"type" : "keyword"
},
"metricName" : {
"type" : "keyword"
},
"monitor_type" : {
"type" : "keyword"
},
"networkinTraffic" : {
"type" : "double"
},
"networkoutTraffic" : {
"type" : "double"
},
"node_spec" : {
"type" : "keyword"
},
"node_stats_node_master" : {
"type" : "keyword"
},
"resource_uid" : {
"type" : "keyword"
}
}
}
}
}
操作流程
- 步骤一:创建RollUp作业
- 步骤二:启动RollUp作业并查看作业信息
- 步骤三:查询汇总索引的数据
- 步骤四:创建Rollup索引模式
- 步骤五:创建Kibana流量监控大图
- 步骤六:创建Kibana流量监控仪表板
步骤一:创建RollUp作业
RollUp作业配置包含该作业如何运行、何时索引文档及将来对汇总索引执行哪些查询的详情信息。以下示例通过PUT _rollup/job
命令定义1小时内汇总的作业。
PUT _rollup/job/ls-monitordata-sls-1h-job1
{
"index_pattern": "monitordata-logstash-sls-*",
"rollup_index": "monitordata-logstash-rollup-1h-1",
"cron": "0 */15 * * * ?",
"page_size" :1000,
"groups" : {
"date_histogram": {
"field": "@timestamp",
"fixed_interval": "1h"
},
"terms": {
"fields": ["instanceId"]
}
},
"metrics": [
{
"field": "networkoutTraffic",
"metrics": ["sum"]
},
{
"field": "networkinTraffic",
"metrics": ["sum"]
}
]
}
参数 | 是否必选 | 类型 | 说明 |
---|---|---|---|
index_pattern | 是 | string | 汇总的索引或索引模式。支持通配符(*)。 |
rollup_index | 是 | string | 汇总结果的索引。不支持通配符,必须是一个完整的名称。 |
cron | 是 | string | 执行汇总作业任务的时间间隔。与汇总数据的时间间隔无关。 |
page_size | 是 | integer | 汇总索引每次迭代中处理的存储桶的结果数。值越大,执行越快,但是处理过程中需要更多的内存。 |
groups | 是 | object | 为汇总作业定义分组字段和聚合。 |
└ date_histogram | 是 | object | 将date字段汇总到基于时间的存储桶中。 |
└field | 是 | string | 需要汇总的date字段。 |
└fixed_interval | 是 | time units | 数据汇总的时间间隔。例如设置为1h,表示按照1小时汇总field指定的时间字段。该参数定义了数据能够聚合的最小时间间隔。 |
terms | 否 | object | 无。 |
└fields | 是 | string | 定义terms字段集。此数组字段可以是keyword也可以是numerics类型,无顺序要求。 |
metrics | 否 | object | 无。 |
└field | 是 | string | 定义需要采集的指标的字段。例如以上示例是分别对networkoutTraffic、networkinTraffic进行采集。 |
└metrics | 是 | array | 定义聚合算子。设置为sum,表示对networkinTraffic进行sum运算。仅支持min、max、sum、average、value count。 |
index_pattern
中指定通配符时,请确保不会匹配到rollup_index
指定的汇总索引名,否则报错。- 由于汇总索引的Mapping是object类型,请确保集群中不存在与汇总索引相匹配的索引模板,否则报错。
- 字段分组聚合仅支持Date Histogram aggregation、Histogram aggregation、Terms aggregation,详细限制说明请参见Rollup aggregation limitations。
步骤二:启动RollUp作业并查看作业信息
启动RollUp作业。
查看RollUp作业的配置、统计和状态信息。 执行成功后,返回如下结果。
步骤三:查询汇总索引的数据
在Rollup内部,由于汇总文档使用的文档结构和原始数据不同,Rollup查询端口会将标准查询DSL重写为与汇总文档匹配的格式,然后获取响应并将其重写回给原始查询的客户端所期望的格式。
使用match_all获取汇总索引的所有数据。
使用聚合出口流量总数据。 支持常规的Search API特性子集:不可用功能包括:
UI创建
参考:喬叔教 Elastic - 12 - 管理 Index 的 Best Practice (4/7) - Rollup - iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天
建立Rollup Job
首先,进入Kibana > Stack Management 后,点选左侧Data 区块中的Rollup Jobs。
点Create rollup job 之后,会进入设定页面:
这边的设定基本上都蛮直觉的,依照旁边的说明设定即可。
- Name:帮Rollup Job取个名字。
- Data flow:指定Index pattern以及Rollup产生的Index名字。
- Schedule:这个Rollup Job执行的频率。
- Ho manay documents do you want to roll up at a time:执行时批次处理的大小,数字愈来处理速度愈快,但记忆体也耗的愈多。
- How long should the rollup job wait before rolling up new data:在执行Rollup时,可以设定一个Latency执,这个Latency指的是资料在ingest进入ES时,有可能会有一些延迟,一但设了这个Latency, Rollup Job就会多等到Latency的时间过了之后,才会处理这部份的资料。
这边有个要注意的
Index pattern
不应该包含到Rollup index name
,上图就是一个错误的例子,这样会造成处理逻辑上的错误,如果你设定了这样的配置,最终会看到以下这样的错误画面。
接下来要分别设定Date histogram 的时间颗粒度:
设定有哪些栏位会使用到Term bucketing:
哪些栏位可能会进行Histogram 的aggregation:
哪些栏位会使用到Metrics,这边请依照资料的特性来判断,有些没必要的就不用勾选了。
最后Review 完没问题时,就可以直接建立。
查看Rollup Jobs
当建立完成后,在Rollup Jobs 的选单中可以看到我们建立的这个Job。
点开后也可以看到他的Stats,包含目前已经处理了多少Documents、Pages、以及执行过多少次。
这时到Index Management 来查看Elasticsearch 中的Index,就可以看到由这个Rollup Job 所产生的Index 了。
记得要把上面
Include rollup indices
打勾,才会看得到。
这时Rollup Job 产生的资料已经可以使用了。
而且我们可以看到,rollup-logstash-daily
占用的是446mb的空间,比起整体logstash-1
~logstash-10
的总量,大约只占了1/10。
不足
这里这么好用,那岂不是都可以用了?!
不是的!
仔细研究发现这个功能有几个比较大的不足:
实验性质的功能
1.从Elasticsearch6.4开始,这个功能作为试验性的功能开发,一直到目前即Elasticsearch7.14,依然是实验性质的,所以会有这么一段话:
这意味着,平时玩一下可以,但用在生产项目上就不好了,而且,一个实验室的项目这么多年没有转正,只是库的位置换了一下( 即从商业版的X-Pack组件包里变为REST组件,变成了免费用品),这里的风险比较大
无法复杂正则匹配index
下图可以看到,正则只能用*,不能用其他的内容,很多时候项目数据按天/周/月分索引,但聚合的数据并不是这样,比如按天分索引的数据想聚合成周数据,就不能支持了,只能先创建周表,把数据迁移过来,再进行聚合任务,这里比较坑。。。
不能预先筛选
这里非常的坑,比如我只要原始表中的网络状态为200的数据作为待聚合数据,这里不支持。。。
本来我看到下图:
以为新的版本可以支持筛选了
但仔细一看,居然是吐槽的内容,
再向下看:
官方接受了这个建议?
打开issue看下
好吧,好消息是官方确实重视这个问题了,并重新开放了问题
坏消息是官方的开发者表示目前没什么思路。。。
坐等吧
ps:最后吐槽一下
Elasticsearch 7.14这种先发文档不给安装包的操作确实有点。。。
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=15mgfwpmnek25