如何避免与prometheus模块结合使用的metricbeat中的“超出总字段限制”错误?

Posted

技术标签:

【中文标题】如何避免与prometheus模块结合使用的metricbeat中的“超出总字段限制”错误?【英文标题】:How to avoid "Limit of total fields exceeded" error in metricbeat in conjunction with the prometheus module? 【发布时间】:2022-01-08 00:31:09 【问题描述】:

我正在使用来自 helm.elastic.co 的 helm 图表在 kubernetes 中运行 metricbeat。 这导致 metricbeat 将具有 3776 个字段的巨大索引模板加载到 elasticsearch 索引中。 但实际只使用了 633 个并将值发送到索引。

问题是,当 metricbeat-metricbeat-metrics pod 尝试将事件发送到 elasticsearch 时,我收到以下错误:

Cannot index event ..."reason":"Limit of total fields [5000] has been exceeded"

此错误发生在 metricbeat 实例中,其中使用了带有“收集器”度量集的 prometheus 模块。 我不确定是加载的模板是原因,还是从 prometheus 转发的事件实际上每个包含超过 5000 个字段。

尽管如此: elasticsearch 加载这么大的模板是常见的做法吗? 如果不是:将模板限制为实际使用的字段的方法是什么?

编辑:

进一步分析得出结论,elasticsearch模板的大小并没有导致这个错误: 仅当 metricbeat 中的 prometheus 模块处于活动状态时,才会发生索引错误。在这种情况下,模板大小保持不变。

prometheus 应该从正在运行的 pod 中抓取指标。 最初的指标数量是:

总共有 61274 个指标 (__name__!="") 956 个不同的指标名称。 (group by(__name__) (__name__!="")

我更改了prometheus的scrape设置,导致:

总共 118 个指标 (__name__!="") 55 个不同的指标名称。 (group by(__name__) (__name__!="")

metricbeat的prometheus模块配置为:

      - module: prometheus
        period: 30s
        metricsets: ["collector"]
        hosts: ["prometheus-server"]
        metrics_path: '/federate'
        query:
          'match[]': 'job="kubernetes-pods"'
        processors:
        - add_cloud_metadata: ~

该查询 job="kubernetes-pods" 的结果恰好是 118 系列。

但是:Cannot index event ... 错误仍然出现!

这是完整的错误日志行:

2021-12-03T07:15:07.227Z    WARN    [elasticsearch] elasticsearch/client.go:408 Cannot index event publisher.EventContent:beat.EventTimestamp:time.Timewall:0xc0628ede3b502221, ext:907213012182, loc:(*time.Location)(0x5862e80), Meta:null, Fields:"agent":"ephemeral_id":"e7ef097d-95c8-4f60-a63f-0de436c45195","hostname":"metricbeat-metricbeat-metrics-59c8d8b865-b2gqc","id":"2c17c983-631e-4f70-ab36-a56bc1b5b254","name":"metricbeat-metricbeat-metrics-59c8d8b865-b2gqc","type":"metricbeat","version":"7.10.0","cloud":"account":"id":"xxxx","availability_zone":"eu-central-1b","image":"id":"ami-xxxx","instance":"id":"i-xxxx","machine":"type":"t3a.xlarge","provider":"aws","region":"eu-central-1","ecs":"version":"1.6.0","event":"dataset":"prometheus.collector","duration":5888251,"module":"prometheus","host":"name":"metricbeat-metricbeat-metrics-59c8d8b865-b2gqc","metricset":"name":"collector","period":30000,"prometheus":"labels":"app_kubernetes_io_instance":"...","app_kubernetes_io_name":"my-pod-name","instance":"10.124.2.235:8080","job":"kubernetes-pods","kubernetes_namespace":"mynamespace","kubernetes_pod_name":"my-pod-85746d8c4f-wb4kq","name":"rabbit","pod_template_hash":"85746d8c4f","metrics":"rabbitmq_acknowledged_published_total":0.000000,"rabbitmq_acknowledged_total":9.000000,"rabbitmq_channels":2.000000,"rabbitmq_connections":1.000000,"rabbitmq_consumed_total":9.000000,"rabbitmq_failed_to_publish_total":0.000000,"rabbitmq_not_acknowledged_published_total":0.000000,"rabbitmq_published_total":0.000000,"rabbitmq_rejected_total":0.000000,"rabbitmq_unrouted_published_total":0.000000,"service":"address":"http://prometheus-server/federate?match%5B%5D=%7Bjob%3D%22kubernetes-pods%22%7D","type":"prometheus", Private:interface (nil), TimeSeries:true, Flags:0x0, Cache:publisher.EventCachem:common.MapStr(nil) (status=400): "type":"illegal_argument_exception","reason":"Limit of total fields [5000] has been exceeded"

使用查询api而不是federation会导致同样的错误:

      - module: prometheus
        period: 30s
        metricsets: ["collector"]
        hosts: ["prometheus-server"]
        metrics_path: /metrics
        metrics_filters:
          include: [".+"]

只有当我指定一个包含模式,它匹配一些指标——比如“jvm.*”——错误才会消失。 但我绝对想在 metricbeat 配置中明确包含我的所有指标。

【问题讨论】:

3776 个字段肯定很多。你试过overriding the template吗? 没有。但事实证明,模板大小实际上并没有导致这个错误。该错误仅在从 prometheus 服务器转发事件时发生。禁用prometheus后,模板大小不变,但报错消失了。 您在 Prometheus 中公开了多少指标?不正确的设置(例如,为每个客户创建一个新指标而不是使用标签)可能会导致指标爆炸,这也会影响 Elasticsearch。 prometheus 服务器的指标集非常有限。在 prometheus gui 中查询 group by(__name__) (__name__ != "") 仅返回 55 个系列。 我将 metricbeat 设置更改为使用查询 api 而不是联合(如 metricbeat 所建议的那样:这会导致相同的错误。当我在 include 中使用例如 "jvm.*" 的模式时没有错误子句(19系列匹配) 【参考方案1】:

我通过将index.mapping.total_fields.limit 增加到 10000 解决了这个问题。

只要 metricbeat 能够应用新的索引模板,错误就会消失。这意味着,我需要删除当前索引,metricbeat 在其中附加文档并重新启动 metricbeat 进程。

这并不令人满意。 但据我所知,大多数用户只是使用稍大的默认索引模板而没有任何问题。

【讨论】:

以上是关于如何避免与prometheus模块结合使用的metricbeat中的“超出总字段限制”错误?的主要内容,如果未能解决你的问题,请参考以下文章

prometheus 与 alertmanager 结合 发送邮件报警

Prometheus 中的 increase() 有时会使值翻倍:如何避免?

如何将 Testcontainers 与 @DataJpaTest 结合使用以避免代码重复?

按特定时间段删除时间序列指标 Prometheus

如何使用 Prometheus 轻松实现监控?

在Python 3中将Ctrl-D与sys.stdin.readlines()结合使用后,如何避免input()出现EOFError?