Hadoop學習筆記—7.計數器與自定義計數器


一、Hadoop中的計數器

計數器:計數器是用來記錄job的執行進度和狀態的。它的作用可以理解為日志。我們通常可以在程序的某個位置插入計數器,用來記錄數據或者進度的變化情況,它比日志更便利進行分析。

  例如,我們有一個文件,其中包含如下內容:

hello you
hello me

  它被WordCount程序執行后顯示如下日志:

  在上圖所示中,計數器有19個,分為四個組:File Output Format CountersFileSystemCountersFile Input Format CountersMap-Reduce Framkework

  分組File Input Format Counters包括一個計數器Bytes Read,表示job執行結束后輸出文件的內容包括19個字節(空格、換行都是字符),如下所示。

hello 2
me 1
you 1

  分組File Output Format Counters包括一個計數器Bytes Written,表示job執行時讀取的文件內容包括19個字節(空格、換行都是字符),如下所示。

hello you
hello me

  關於以上這段計數器日志中詳細的說明請見下面的注釋:

 1    Counters: 19 // Counter表示計數器,19表示有19個計數器(下面一共4計數器組)
 2    File Output Format Counters // 文件輸出格式化計數器組
 3      Bytes Written=19 // reduce輸出到hdfs的字節數,一共19個字節
 4    FileSystemCounters// 文件系統計數器組
 5      FILE_BYTES_READ=481
 6      HDFS_BYTES_READ=38
 7      FILE_BYTES_WRITTEN=81316
 8      HDFS_BYTES_WRITTEN=19
 9    File Input Format Counters // 文件輸入格式化計數器組
10      Bytes Read=19 // map從hdfs讀取的字節數
11    Map-Reduce Framework // MapReduce框架
12      Map output materialized bytes=49
13      Map input records=2 // map讀入的記錄行數,讀取兩行記錄,”hello you”,”hello me”
14      Reduce shuffle bytes=0 // 規約分區的字節數
15      Spilled Records=8
16      Map output bytes=35
17      Total committed heap usage (bytes)=266469376
18      SPLIT_RAW_BYTES=105
19      Combine input records=0 // 合並輸入的記錄數
20      Reduce input records=4 // reduce從map端接收的記錄行數
21      Reduce input groups=3  // reduce函數接收的key數量,即歸並后的k2數量
22      Combine output records=0 // 合並輸出的記錄數
23      Reduce output records=3 // reduce輸出的記錄行數。<helllo,{1,1}>,<you,{1}>,<me,{1}>
24      Map output records=4 // map輸出的記錄行數,輸出4行記錄

二、用戶自定義計數器

  以上是在Hadoop中系統內置的標准計數器。除此之外,由於不同的場景有不同的計數器應用需求,因此我們也可以自己定義計數器使用。

2.1 敏感詞記錄-准備

  現在假設我們需要對文件中的敏感詞做一個統計,即對敏感詞在文件中出現的次數做一個記錄。這里,我們還是以下面這個文件為例:

Hello World!
Hello Hadoop!

  文本內容很簡單,這里我們指定Hello是一個敏感詞,顯而易見這里出現了兩次Hello,即兩次敏感詞需要記錄下來。

2.2 敏感詞記錄-程序

  在WordCount程序的基礎之上,改寫Mapper類中的map方法,統計Hello出現的次數,如下代碼所示:

        public static class MyMapper extends
            Mapper<LongWritable, Text, Text, LongWritable> {
        /*
         * @param KEYIN →k1 表示每一行的起始位置(偏移量offset)
         * 
         * @param VALUEIN →v1 表示每一行的文本內容
         * 
         * @param KEYOUT →k2 表示每一行中的每個單詞
         * 
         * @param VALUEOUT →v2表示每一行中的每個單詞的出現次數,固定值為1
         */
        protected void map(LongWritable key, Text value,
                Mapper<LongWritable, Text, Text, LongWritable>.Context context)
                throws java.io.IOException, InterruptedException {
            Counter sensitiveCounter = context.getCounter("Sensitive Words:", "Hello");
            
            String line = value.toString();
            // 這里假定Hello是一個敏感詞
            if(line.contains("Hello")){
                sensitiveCounter.increment(1L);
            }
            String[] spilted = line.split(" ");
            for (String word : spilted) {
                context.write(new Text(word), new LongWritable(1L));
            }
        };
    }

  我們首先通過Mapper.Context類直接獲得計數器對象。這里有兩個形參,第一個是計數器組的名稱,第二是計數器的名稱。

  然后通過String類的contains方法判斷是否存在Hello敏感詞。如果有,進入條件判斷語句塊,調用計數器對象的increment方法。

2.3 敏感詞記錄-結果

  通過查看控制台日志信息,可以看到如下圖所示的信息:

  我們可以清楚地看到計數器由原來的19個變為20個,多出來的這個計數器正是我們自定義的敏感詞計數器,由於文件中只有兩個Hello,因此這里顯示Hello=2。

參考資料

(1)Suddenly,《Hadoop日記17-計數器、Map規約與分區》:http://www.cnblogs.com/sunddenly/p/4009568.html

(2)吳超,《Hadoop中的計數器》:http://www.superwu.cn/2013/08/14/460

(3)dajuezhao,《Hadoop中自定義計數器》:http://blog.csdn.net/dajuezhao/article/details/5788705

(4)萬川梅、謝正蘭,《Hadoop應用開發實戰詳解(修訂版)》:http://item.jd.com/11508248.html

   


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM