理解Storm Metrics

在hadoop中,存在對應的counter計數器用於記錄hadoop map/reduce job任務執行過程中自定義的一些計數器,其中hadoop任務中已經內置了一些計數器,例如CPU時間,GC時間等。
 
Storm中也存在類似counter的功能,metrics,詳細介紹可以參考下面的文檔:
 
 
 
Storm exposes a metrics interface to report summary statistics across the full topology. It's used internally to track the numbers you see in the Nimbus UI console: counts of executes and acks; average process latency per bolt; worker heap usage; and so forth.
 
 
 
所有的Metric都需要實現IMetric接口,該接口中只有一個方法用來表示取出現有的counter值,並將其清零。
 
 
public interface IMetric {
    public Object getValueAndReset();
}
 
 
 
以提供的實例CountMetric, MultiCountMetric和ReduceMetric爲例,類圖方式展示如下:
 
 


 
 
在CountMetric中,只是記錄了一個long值,在每次incr和incrBy時進行遞增記錄;
 
MultiCountMetric中,其中內置了Map<String, CountMetric>用來記錄多個CountMetric,scope方法用來以key的方式圈定範圍,在每次getValueAndSet時,都會直接清掉Map中所有的CountMetric;
 
ReducedMetric是比較特殊的一個,因爲它不僅僅記錄了一個維度,還可以以reduce的方式來計算一段時間來的平均值,比如Storm中提供的實現MeanReducer,在ReducedMetric中的實現,其中_accumlator作爲累積數據(從字面意思上理解),類型爲Object,可以用任何類型來表示:
 
 
public class ReducedMetric implements IMetric {
    private final IReducer _reducer;
    private Object _accumulator;
 
    public ReducedMetric(IReducer reducer) {
        _reducer = reducer;
        _accumulator = _reducer.init();
    }
 
    public void update(Object value) {
        _accumulator = _reducer.reduce(_accumulator, value);
    }
 
    public Object getValueAndReset() {
        Object ret = _reducer.extractResult(_accumulator);
        _accumulator = _reducer.init();
        return ret;
    }
}
 
 
 
MeanReducer中,就記錄兩個維度 count和總和,通過這兩個維度,我們可以輕易計算出一段時間內的平均值。
 
 
class MeanReducerState {
    public int count = 0;
    public double sum = 0.0;
}

public class MeanReducer implements IReducer<MeanReducerState> {
    public MeanReducerState init() {
        return new MeanReducerState();
    }
 
    public MeanReducerState reduce(MeanReducerState acc, Object input) {
        acc.count++;
        if(input instanceof Double) {
            acc.sum += (Double)input;
        } else if(input instanceof Long) {
            acc.sum += ((Long)input).doubleValue();
        } else if(input instanceof Integer) {
            acc.sum += ((Integer)input).doubleValue();
        } else {
            throw new RuntimeException(
                "MeanReducer::reduce called with unsupported input type `" + input.getClass()
                + "`. Supported types are Double, Long, Integer.");
        }
        return acc;
    }
 
    public Object extractResult(MeanReducerState acc) {
        if(acc.count > 0) {
            return acc.sum / (double) acc.count;
        } else {
            return null;
        }
    }
}
 
 
 
所有的Metrics都需要在Spout/Bolt初始化之前記錄,對應Spout.open(), Bolt.prepare方法,註冊時需要指定指標的名稱,對應實例,以及間隔時間(以秒爲單位)。
 
 
context.registerMetric("execute_count", countMetric, 5);
context.registerMetric("word_count", wordCountMetric, 60);
context.registerMetric("word_length", wordLengthMeanMetric, 60);
 
 
 
 

IMetricsConsumer

 

註冊metrics後,只是在定時進行記錄metrics,但metrics該如何顯示,這就取決於IMetricsConsumer,在Config中可以手動進行註冊自定義的metricsConsumer,也可以直接使用storm中提供的記錄日誌的LoggingMetricsConsumer,該consumer會以日誌的形式記錄統計指標,下面是對其介紹:
 
 
Listens for all metrics, dumps them to log To use, add this to your topology's configuration: ```java conf.registerMetricsConsumer(org.apache.storm.metrics.LoggingMetricsConsumer.class, 1); ``` Or edit the storm.yaml config file: ```yaml topology.metrics.consumer.register: - class: "org.apache.storm.metrics.LoggingMetricsConsumer" parallelism.hint: 1
  
 
這表示,在config中可以通過手動註冊的方式將LoggingMetricsConsumer註冊上去,第二個參數爲並行度:
 
 
config.registerMetricsConsumer(LoggingMetricsConsumer.class, 2);
  
 
此時Config對象(類似HashMap)會將topology.metrics.consumer.register屬性註冊,記錄其class, parallelism.hint並行度,以及argument參數。
 



 
 
 
在Config中註冊後,通過內置的特殊Bolt:MetricConsumerBolt來執行handleDataPoints方法,其中handleDataPoints賦給的兩個參數taskInfo, dataPoints如下所示,給定了source task的一些狀態,以及傳輸過來的彙總數據:
 


 
 
在應用後,就可以在storm的日誌目錄下查看到metrics日誌文件:
 
/usr/local/apache-storm-1.0.1/logs/workers-artifacts/FirstTopo-46-1468485056/6703
 
-rw-rw-r-- 1 java java  55K 7月  14 18:47 gc.log.0
-rw-rw-r-- 1 java java  28K 7月  14 18:47 worker.log
-rw-rw-r-- 1 java java    0 7月  14 16:31 worker.log.err
-rw-rw-r-- 1 java java 1.2M 7月  14 18:47 worker.log.metrics
-rw-rw-r-- 1 java java    0 7月  14 16:31 worker.log.out
-rw-rw-r-- 1 java java    5 7月  14 16:31 worker.pid
-rw-rw-r-- 1 java java  120 7月  14 16:31 worker.yaml
 
 
 
 
在worker.log.metrics中就可以查看到所有metrics的相關信息,注意不僅僅包含我們自定義的bolt類型,一些system類型的信息也會在上面顯示出來:
 
 
2016-07-14 16:31:40,700 31721    1468485098       192.168.1.127:6702      6:bolt        execute_count           5
2016-07-14 16:31:45,702 36723    1468485103       192.168.1.127:6702      6:bolt        execute_count           5
2016-07-14 16:31:50,702 41723    1468485108       192.168.1.127:6702      6:bolt        execute_count           5
2016-07-14 16:32:10,705 61726    1468485128       192.168.1.127:6702      6:bolt        execute_count           5
2016-07-14 16:32:15,708 66729    1468485133       192.168.1.127:6702      6:bolt        execute_count           5
2016-07-14 16:32:25,699 76720    1468485143       192.168.1.127:6702      6:bolt        __ack-count             {spout:default=60}
2016-07-14 16:32:25,701 76722    1468485143       192.168.1.127:6702      6:bolt        __sendqueue             {sojourn_time_ms=0.0, write_pos=10, read_pos=10, arrival_rate_secs=0.10267994660642776, overflow=0, capacity=1024, population=0}
2016-07-14 16:32:25,701 76722    1468485143       192.168.1.127:6702      6:bolt        word_count              {happy=18, angry=19, excited=14}
2016-07-14 16:32:25,702 76723    1468485143       192.168.1.127:6702      6:bolt        __receive               {sojourn_time_ms=817.6666666666666, write_pos=62, read_pos=61, arrival_rate_secs=1.222992254382389, overflow=0, capacity=1024, population=1}
 
 
 
 
 
 
 
 
 
 
  • e28a28ff-17b9-303d-a1da-d962644c2aed-thumb.png
  • 大小: 37 KB
  • f2ee581b-a5ab-3928-b808-63673a7a7d26-thumb.png
  • 大小: 32.4 KB
  • 36046f95-6dee-33da-9db3-4f2e42d5be09-thumb.png
  • 大小: 46.4 KB
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章