Flink源码剖析:Metrics运作机制

本文介绍了Flink的Metrics系统,包括Metrics的类型如Counter、Gauge、Meter和Histogram,以及Metric Group的层级结构。详细阐述了Metrics的运行机制,包括初始化Reporter如PrometheusReporter和PrometheusPushGatewayReporter,注册Reporter,收集Metrics到内存,以及通过push或pull模式发送到第三方存储。了解这些机制有助于更好地监控和理解Flink作业和集群的性能状态。
摘要由CSDN通过智能技术生成

1. Metrics简介

1.1 什么是 Metrics?

Flink 提供的 Metrics 可以在 Flink 内部收集一些指标,通过这些指标让开发人员更好地理解作业或集群的状态。由于集群运行后很难发现内部的实际状况,跑得慢或快,是否异常等,开发人员无法实时查看所有的 Task 日志,比如作业很大或者有很多作业的情况下,该如何处理?此时 Metrics 可以很好的帮助开发人员了解作业的当前状况。

1.2 Metric Types

Metrics 的类型如下:

  1. Counter,对一个计数器进行累加,即对于多条数据和多兆数据一直往上加的过程。
  2. Gauge,Gauge 是最简单的 Metrics,它反映一个值的大小。
  3. Meter,Meter 是指统计吞吐量和单位时间内发生“事件”的次数。它相当于求一种速率,即事件次数除以使用的时间。理解为滚动窗口求平均值即可。
  4. Histogram,Histogram 比较复杂,也并不常用,Histogram 用于统计一些数据的分布,比如说 Quantile、Mean、StdDev、Max、Min 等。

1.3 Metric Group

Metric 在 Flink 内部有多层结构,以 Group 的方式组织,它并不是一个扁平化的结构,Metric Group + Metric Name 是 Metrics 的唯一标识。

Metric Group 的层级有 TaskManagerMetricGroup 和TaskManagerJobMetricGroup,每个 Job 具体到某一个 task 的 group,task 又分为 TaskIOMetricGroup 和 OperatorMetricGroup。Operator 下面也有 IO 统计和一些 Metrics,整个层级大概如下图所示。Metrics 不会影响系统,它处在不同的组中,并且 Flink支持自己去加 Group,可以有自己的层级。

•TaskManagerMetricGroup
 •TaskManagerJobMetricGroup
  •TaskMetricGroup
   •TaskIOMetricGroup
   •OperatorMetricGroup
    •${User-defined Group} / ${User-defined Metrics}
    •OperatorIOMetricGroup
 •JobManagerMetricGroup
  •JobManagerJobMetricGroup

JobManagerMetricGroup 相对简单,相当于 Master,它的层级也相对较少。

2. Metrics运行机制

系统或自定义的Metrics如何存入第三方存储呢?一般由两种模式,推(push)和拉(poll)。接下来,我们通过分析PrometheusReporterPrometheusPushGatewayReporter两种Reporter,来深入理解Metrics的运行机制和pushpull的区别。

2.1 初始化Reporter

做一些与第三方存储相关的初始化工作

2.1.1 PrometheusReporter

启动本地Rest服务器,Prometheus与其通信,并pull metrics

public class PrometheusReporter extends AbstractPrometheusReporter {
   
	// 初始化一些与第三方存储相关的工作
  @Override
	public void open(MetricConfig config) {
   
		super.open(config);

		String portsConfig = config.getString(ARG_PORT, DEFAULT_PORT);
		Iterator<Integer> ports = NetUtils.getPortRangeFromString(portsConfig);

		while (ports.hasNext()) {
   
			int port = ports.next();
			try {
   
				// internally accesses CollectorRegistry.defaultRegistry
                // 针对PrometheusReporter,启动一个本地Rest服务器,以供Prometheus拉取数据;
                // 而如果是PrometheusPushGatewayReporter,这里就是根据host+port新建一个PushGateway客户端,来往PushGateway发送数据
				httpServer = new HTTPServer(port);
				this.port = port;
				log.info("Started PrometheusReporter HTTP server on port {}.", port);
				break;
			} catch (IOException ioe) {
    //assume port conflict
				log.debug("Could not start PrometheusReporter HTTP server on port {}.", port, ioe);
			}
		}
		if (httpServer == null) {
   
			throw new RuntimeException("Could not start PrometheusReporter HTTP server on any configured port. Ports: " + portsConfig);
		}
	}
}
2.1.2 PrometheusPushGatewayReporter

新建一个PushGateway客户端,主动向PushGateway push metrics

public class PrometheusPushGatewayReporter extends AbstractPrometheusReporter implements Scheduled {
   
	@Override
	public void open(MetricConfig config) {
   
		super.open(config);

		String host = config.getString(HOST.key(), HOST.defaultValue());
		int port = config.getInteger(PORT.key(), PORT.defaultValue());
		String configuredJobName = config.getString(JOB_NAME.key(), JOB_NAME.defaultValue());
		boolean randomSuffix = config.getBoolean(RANDOM_JOB_NAME_SUFFIX.key(), RANDOM_JOB_NAME_SUFFIX.defaultValue());
		deleteOnShutdown = config.getBoolean(DELETE_ON_SHUTDOWN.key(), DELETE_ON_SHUTDOWN.defaultValue());

		if (host == null || host.isEmpty() || port < 1) {
   
			throw new IllegalArgumentException("Invalid host/port configuration. Host: " + host + " Port: " + port);
		}

		if (randomSuffix) {
   
			this.jobName = configuredJobName + new AbstractID();
		} else {
   
			this
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值