實踐指路明燈,源碼剖析flink-metrics

1


通過上期的分享,我們對 Metrics 類庫有了較深入的認識,並對指標監控的幾個度量類型瞭如指掌。


實踐指路明燈,源碼剖析flink-metrics


本期,我們將走進當下最火的流式處理框架 flink 的源碼,一同深入並學習一下別人家的代碼。


實踐指路明燈,源碼剖析flink-metrics


2


會當凌絕頂,一覽眾山小。先從全局瞭解個梗概,然後再採用剝洋蔥的方式逐層去解密。


我本地的源碼是 flink-1.8.1 版本,打開源碼,進入 flink-metrics 模塊,發現很多以 flink-metrics-開頭的系列模塊。


實踐指路明燈,源碼剖析flink-metrics


映入眼簾的 flink-metrics 系列模塊雖然很多,不用發愁。其實主要分為指標監控基礎核心模塊(flink-metrics-core),以及指標數據監控組件集成模塊(flink-metrics-xxx)兩大類。


2.1


flink-metrics-core 模塊剖析。


開篇提到 Metrics 的幾種度量類型,來看看 flink 是咋定義的?


打開指標監控基礎核心模塊 flink-metrics-core 看個梗概。


實踐指路明燈,源碼剖析flink-metrics


不出我們所料,flink 定義了 Metrics 監控中常見的幾種度量規範(Meter、Gauge、Counter、Histogram),畫個簡易的類圖再看的明白些。


實踐指路明燈,源碼剖析flink-metrics


不過為了便於管理和區分 Metric,於是就有了 MetricGroup 的定義,那麼編碼時可以直接與 MetricGroup 交互就可以啦。


實踐指路明燈,源碼剖析flink-metrics


到這,瞭解了全局,不妨採用剝洋蔥的方式,再去看看每個接口定義的都是啥規範?逐一進行解密。


Meter 定義 getRate() 方法,用於統計系統中某一個事件的速率,定義 getCount() 方法,用於系統中事件的計數統計。


實踐指路明燈,源碼剖析flink-metrics


Gauge 是最簡單的度量指標,只有一個簡單的返回值,定義 getValue() 方法,用來獲取一些對象或者事物的瞬時值。


實踐指路明燈,源碼剖析flink-metrics


Counter 累計型的度量指標,定義 inc() 累加方法,以及 dec() 累減等方法。


實踐指路明燈,源碼剖析flink-metrics


Histogram 是一種非常常見的統計圖表,統計數據的分佈情況,其中定義的 getStatistics() 方法,提供了最小值,最大值,中間值等對應的計算支撐。


實踐指路明燈,源碼剖析flink-metrics


其中 HistogramStatistics 定義如下。


實踐指路明燈,源碼剖析flink-metrics


指標對外披露,flink 是咋定義的?


是否還記得上期的分享中,如何把指標數據披露出去的?沒錯,那就是有一系列的 Reporter 來完成的事情,接下來看看 flink 有沒有類似的規範定義呢?


實踐指路明燈,源碼剖析flink-metrics


也是沒出我們所料,flink 定義了專門用於指標報告的規範,畫個簡易的類圖,從全局上稍微看的明白些。


實踐指路明燈,源碼剖析flink-metrics


如上圖示意,flink 定義了 MetricReporter 用於規定指標披露規範,其中 AbstractReporter 提供了 MetricReporter 接口的簡單的實現。Scheduled 接口用於定義數據披露方案,提供定期性的披露當前數據的支持。


那麼,不妨採取剝洋蔥的方式,逐個再去看看都是啥,能意會就行啦。


實踐指路明燈,源碼剖析flink-metrics


MetricReporter 是 flink 定義的指標披露的接口規範,方法名字其實已經很明確啦,再解說一二。其中 open() 方法主要用於初始化相關操作;close() 主要是關閉 Reporter,用於釋放資源;notifyOfAddedMetric()/notifyOfRemovedMetric() 定義新指標註冊以及指標刪除時通知。


實踐指路明燈,源碼剖析flink-metrics


如上圖示意,AbstractReporter 抽象類實現了接口 MetricReporter,並擁有 gauges、counters、histograms、meters 四個度量類型的 Map 容器,並對接口 MetricReporter 中定義的 notifyOfAddedMetric()/notifyOfRemovedMetric() 提供了簡單實現。


實踐指路明燈,源碼剖析flink-metrics


Scheduled 接口很簡單,定義了 report() 方法,用於定期披露當前指標數據。


上面對 flink-metrics-core 指標監控核心定義模塊,有了初步的認識,那麼看看這些規範到底是怎麼用的?


2.2


flink-metrics-prometheus 模塊剖析。


實踐指路明燈,源碼剖析flink-metrics


從全局上了解個梗概,畫個簡易的類圖,稍微看的更清晰。


實踐指路明燈,源碼剖析flink-metrics


很顯然,針對 Prometheus 做了支撐,沒有使用 flink-metrics-core 包中的 AbstractReporter 類,而是對 MetricReporter 進行了單獨實現,不妨我們去看個梗概。


見名知意,AbstractPrometheusReporter 是對 Prometheus 輪子單獨定義的,實現了 MetricReporter 接口定義的方法,肯定少不了去迎合 Prometheus 的代碼,摘取部分核心代碼剖析一下。


實踐指路明燈,源碼剖析flink-metrics


如上圖所示,notifyOfAddedMetric() 方法主要按照 Prometheus 的規範進行封裝成 io.prometheus.client.Collector,以及調用 Prometheus 提供的方法對 Metric 進行轉換封裝(說白了,就是按照 Prometheus 的規範進行轉換,不懂也沒關係,因為每個輪子的實現均不同)。


再去看 AbstractPrometheusReporter 實現類 PrometheusPushGatewayReporter 的源碼之前,不妨先扒拉出以往分享 Prometheus 實戰中的一張圖,解說一二。


實踐指路明燈,源碼剖析flink-metrics


如圖示意,要完成數據源層的 AppService 的指標監控,需要對應用納入一個 Client lib 來支撐指標產生、輸出,然後通過 push 的形式,主動推送數據到 PushGateway,然後 Prometheus Server 會定期性的從 PushGateway 上拉取指標數據。


知道了流程,我們再去看 flink-metrics-prometheus 的源碼,可能會更清晰。


實踐指路明燈,源碼剖析flink-metrics


如源碼所示,PrometheusPushGatewayReporter 類持有 PushGateway 的引用,進而可以使用 Prometheus 提供的 API 進行 push 數據,以及創建連接和釋放資源。


代碼很簡單,open() 方法主要讀取配置文件,進行實例化 PushGateway;report() 方法會調用 PushGateway 提供的 push 方法進行推送數據;close() 方法主要用於釋放資源,從 PushGateway 上把 jobName 對應的 metrics 刪除。


如果你一直追隨一猿小講的腳步的話,那麼會想起之前 flink 監控實踐的一段配置,結合上段代碼,再去看這段配置,就知道這個配置咋回事啦。


實踐指路明燈,源碼剖析flink-metrics


搞定了監控數據如何披露出去的,唯獨有一點,還是沒有搞明白?那就是 PrometheusPushGatewayReporter 什麼時候實例化的呢?也就是流程怎麼串起來的呢?


2.3


flink-runtime 模塊中部分代碼剖析。


首先找到flink-runtime 目錄下的 metrics 包中 org.apache.flink.runtime.metrics.MetricRegistryImpl 一探究竟。

實踐指路明燈,源碼剖析flink-metrics

截圖為 MetricRegistryImpl 構造方法的部分代碼,其中標註 1 代碼,主要是依據配置內容,構建配置的 Reporter 對象;標註 2 的代碼,調用其 open() 方法,完成初始化動作;標註 3 的代碼,主要是判斷 Reporter 對象有沒有實現 Scheduled 接口,如果實現了,則會通過 executor 進行定期調用 reporter.report() 方法進行報送數據。


瞭解到指標數據如何對外披露,但是 Metric 在哪兒添加的呢?

實踐指路明燈,源碼剖析flink-metrics


我們知道 MetricGroup 設計的目的,是為了方便對 Metric 管理,而 AbstractMetricGroup 則對添加 Metric 等相關方法進行了定義實現。


實踐指路明燈,源碼剖析flink-metrics


如圖示標註 2 代碼,AbstractMetricGroup 類中會調用 registry.register(metric, name, this) 完成指標的註冊添加,進而會調用 MetricRegistryImpl 的 register 方法。


實踐指路明燈,源碼剖析flink-metrics


如圖中標註 2 代碼,會調用對應的 Reporter 的 notifyOfAddedMetric() 方法完成添加指標通知。


實踐指路明燈,源碼剖析flink-metrics


此時,代碼懵懵懂,再去看以往實戰的效果圖(Granfna 展示 flink-metrics)的背後,腦海裡應該會清晰不少。


3


flink-metrics 源碼剖析就到這兒,flink 與 prometheus 監控集成剖析也刨到這兒,其實 flink-metrics 與其它輪子集成也是這麼一回事兒,掌握脈略就行了。


另外,flink 作為當下最流行的開源流式處理框架,那麼 flink 定義的指標度量接口規範,勢必會對我們應用監控有建設性的參考意義。


好了,本次分享就到這兒,希望你們能夠喜歡。


分享到:


相關文章: