简体   繁体   English

Flink Metrics 名称冲突

[英]Flink Metrics name collision

My Flink (1.6) job listens to a stream and performs some aggregation.我的 Flink (1.6) 作业侦听流并执行一些聚合。 I want to collect metrics after the aggregation but am having some difficulties.我想在聚合后收集指标,但遇到了一些困难。

My metrics look like this:我的指标如下所示:

id_1, 0.1
id_2, 0.3
...

The ids will be variable and the values will increase and decrease over time so it looked like a Gauge was most appropriate. id 将是可变的,并且值会随着时间的推移而增加和减少,因此看起来Gauge是最合适的。

I created this map function to capture these metrics in a gauge:我创建了这个地图函数来在仪表中捕获这些指标:

class MetricsMapper extends RichMapFunction[MyObject, Double] {
  override def map(obj: MyObject): Double = {
    val metricVal = obj.metricVal
    getRuntimeContext.getMetricGroup.gauge[Double, ScalaGauge[Double]](obj.id, ScalaGauge[Double](() => metricVal))
    metricVal
  }
}

As this shows, I'm using the id property of my object to register the gauge.如图所示,我使用对象的 id 属性来注册仪表。

The problem I am having is that I receive this warning when I run the job:我遇到的问题是我在运行作业时收到此警告:

Name collision: Group already contains a Metric with the name "x" Metric will not be reported

I interpret this as we have already created this gauge earlier in the stream and the new value is ignored.我将其解释为我们已经在流中较早地创建了此仪表,并且忽略了新值。 Is there a way to overcome this?有没有办法克服这个问题?

Thanks谢谢

Are you sure you want to use metrics here?您确定要在此处使用指标吗? Metrics are usually used as a means to look at how the job is performing.指标通常用作查看工作执行情况的手段。 Usual values that you want to use metrics for are:您要使用指标的通常值是:

  • records per seconds,每秒记录,
  • late events迟到的事件
  • number of corrupted events etc.损坏事件的数量等。

In your case I would rather go with some side pipeline producing those aggregates.在你的情况下,我宁愿使用一些生产这些聚合的辅助管道。

You should be following the pattern shown in the documentation :您应该遵循文档中显示的模式:

new class MyMapper extends RichMapFunction[MyObject, Double] {
  @transient private var valueToExpose = 0.0

  override def open(parameters: Configuration): Unit = {
    getRuntimeContext()
      .getMetricGroup()
      .gauge[Double, ScalaGauge[Double]]("MyGauge", ScalaGauge[Double]( () => valueToExpose ) )
  }

  override def map(obj: MyObject): String = {
    valueToExpose = obj.metricval
    valueToExpose
  }
}

In other words, register the gauge once in the open() method, and update the value each time map() is called.换句话说,在 open() 方法中注册一次仪表,并在每次调用 map() 时更新值。

In your case you are wanting a separate gauge for each unique object id.在您的情况下,您需要为每个唯一的对象 ID 使用单独的仪表。 If you really want to do this with metrics, you'll have to keep around something like a hashmap of gauges, creating new ones as needed, and updating the value of the relevant gauge in the map() function.如果你真的想用度量来做这件事,你必须保留一些像仪表的哈希图,根据需要创建新的,并在 map() 函数中更新相关仪表的值。 Or better, key your stream by the id.或者更好的是,通过 id 来键入您的流。

Another factor to keep in mind when considering whether using metrics is appropriate is that metrics are not checkpointed.在考虑使用指标是否合适时要记住的另一个因素是指标没有设置检查点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM