ElasticSearch Rollup的那些事

2022-08-02 15:09:49 浏览数 (1)

近期,突然要做一个大量数据聚合的任务,由于原始数据在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"
        }
      }
    }
  }
}

操作流程

  1. 步骤一:创建RollUp作业
  2. 步骤二:启动RollUp作业并查看作业信息
  3. 步骤三:查询汇总索引的数据
  4. 步骤四:创建Rollup索引模式
  5. 步骤五:创建Kibana流量监控大图
  6. 步骤六:创建Kibana流量监控仪表板

步骤一:创建RollUp作业

RollUp作业配置包含该作业如何运行、何时索引文档及将来对汇总索引执行哪些查询的详情信息。以下示例通过PUT _rollup/job命令定义1小时内汇总的作业。

代码语言:javascript复制
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

0 人点赞