MapReduce计数器实验
一、實驗目的
-
通過實驗掌握基本的MapReduce編程方法;
-
掌握用MapReduce解決一些常見的數據處理問題,編寫計數器程序。
二、實驗平臺
-
操作系統:Linux(建議CentOS6.5);
-
Hadoop版本:2.9.2;
-
JDK版本:1.8或以上版本;
-
Java IDE:Eclipse;
三、實驗要求
能夠理解MapReduce編程思想,然后會編寫MapReduce版本計數器程序,并能執行該程序和分析執行過程。
四、實驗背景
1、MapReduce計數器是什么?
計數器是用來記錄job的執行進度和狀態的。它的作用可以理解為日志。我們可以在程序的某個位置插入計數器,記錄數據或者進度的變化情況。
2、MapReduce計數器能做什么?
MapReduce 計數器(Counter)為我們提供一個窗口,用于觀察 MapReduce Job 運行期的各種細節數據。對MapReduce性能調優很有幫助,MapReduce性能優化的評估大部分都是基于這些 Counter 的數值表現出來的。
3、內置計數器
MapReduce 自帶了許多默認Counter,現在我們來分析這些默認 Counter 的含義,方便大家觀察 Job 結果,如輸入的字節數、輸出的字節數、Map端輸入/輸出的字節數和條數、Reduce端的輸入/輸出的字節數和條數等。下面我們只需了解這些內置計數器,知道計數器組名稱(groupName)和計數器名稱(counterName),以后使用計數器會查找groupName和counterName即可。
4、計數器使用
(1)定義計數器
枚舉聲明計數器:
// 自定義枚舉變量Enum
Counter counter = context.getCounter(Enum enum)自定義計數器:
// 自己命名groupName和counterName
Counter counter = context.getCounter(String groupName,String counterName)(2)為計數器賦值
初始化計數器:
counter.setValue(long value);//設置初始值計數器自增:
counter.increment(long incr);// 增加計數(3)獲取計數器的值
獲取枚舉計數器的值:
Configuration conf = new Configuration();Job job = new Job(conf, "MyCounter");job.waitForCompletion(true);Counters counters=job.getCounters();Counter counter=counters.findCounter(LOG_PROCESSOR_COUNTER.BAD_RECORDS_LONG);//獲取自定義計數器的值:long value=counter.getValue();Configuration conf = new Configuration();Job job = new Job(conf, "MyCounter");job.waitForCompletion(true);Counters counters = job.getCounters();Counter counter=counters.findCounter("ErrorCounter","toolong");// 假如groupName為ErrorCounter,counterName為toolong//獲取內置計數器的值:long value = counter.getValue();Configuration conf = new Configuration();Job job = new Job(conf, "MyCounter");job.waitForCompletion(true);Counters counters=job.getCounters();Counter counter=counters.findCounter("org.apache.hadoop.mapreduce.JobCounter","TOTAL_LAUNCHED_REDUCES") ;long value=counter.getValue();Configuration conf = new Configuration();Job job = new Job(conf, "MyCounter");Counters counters = job.getCounters();for (CounterGroup group : counters) {for (Counter counter : group) {System.out.println(counter.getDisplayName() + ": " + counter.getName() + ": "+ counter.getValue());}}(5)自定義計數器
MapReduce允許用戶編寫程序來定義計數器,計數器的值可在mapper或reducer 中增加。多個計數器由一個Java枚舉(enum)類型來定義,以便對計數器分組。一個作業可以定義的枚舉類型數量不限,各個枚舉類型所包含的字段數量也不限。枚 舉類型的名稱即為組的名稱,枚舉類型的字段就是計數器名稱。計數器是全局的。換言之,MapReduce框架將跨所有map和reduce聚集這些計數器,并在作業結束 時產生一個最終結果。
五、實驗步驟
1、實驗分析設計
該實驗要求學生自己實現一個計數器,統計輸入的無效數據。說明如下:假如一個文件,規范的格式是3個字段,“\t”作為分隔符,其中有2條異常數據,一條數據是只有2個字段,一條數據是有4個字段。其內容如下所示:
jim 1 28kate 0 26tom 1lily 0 29 22編寫代碼統計文檔中字段不為3個的異常數據個數。如果字段超過3個視為過長字段,字段少于3個視為過短字段。
2、編寫程序代碼:
package mr ; import java.io.IOException; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Counter; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.Mapper; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import org.apache.hadoop.util.GenericOptionsParser;public class Counters {public static class MyCounterMap extends Mapper<LongWritable, Text, Text, Text> {public static Counter ct = null;protected void map(LongWritable key, Text value,org.apache.hadoop.mapreduce.Mapper<LongWritable, Text, Text, Text>.Context context)throws java.io.IOException, InterruptedException {String arr_value[] = value.toString().split("\t"); if (arr_value.length < 3) {ct = context.getCounter("ErrorCounter", "toolong"); // ErrorCounter為組名,toolong為組員名 ct.increment(1); // 計數器加一 } else if (arr_value.length>=3) {ct = context.getCounter("ErrorCounter", "tooshort");ct.increment(1);}} } public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {Configuration conf = new Configuration();String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();if (otherArgs.length != 2) {System.err.println("Usage: Counters <in> <out>");System.exit(2); } Job job = new Job(conf, "Counter");job.setJarByClass(Counters.class); job.setMapperClass(MyCounterMap.class); FileInputFormat.addInputPath(job, new Path(otherArgs[0]));FileOutputFormat.setOutputPath(job, new Path(otherArgs[1]));System.exit(job.waitForCompletion(true) ? 0 : 1);} }3、打包并提交
使用Eclipse開發工具將該代碼打包,選擇主類為mr.Counters。假定打包后的文件名為Counters.jar,主類Counters位于包mr下,則可使用如下命令向Hadoop集群提交本應用。
[root@master hadoop]# bin/hadoop jar Counters.jar mr.Counters /usr/counters/in/counters.txt /usr/counters/out其中“hadoop”為命令,“jar”為命令參數,后面緊跟打包。 “/usr/counts/in/counts.txt”為輸入文件在HDFS中的位置(如果沒有,自行上傳),“/usr/counts/out”為輸出文件在HDFS中的位置。
4、實驗操作:
步驟1 首先在Hadoop下使用 sbin/start-all.sh 命令啟動集群。
步驟2 上傳數據文件至HDFS
因為沒有HDFS中沒有 /usr/counters/in/ 目錄,所以要先創建數據輸入的路徑。之后將放在/root/data/7/counters.txt的數據文件上傳到剛剛創建好的路徑
步驟3編寫計數器程序。
步驟4打包程序。
步驟5 運行程序。
總結
以上是生活随笔為你收集整理的MapReduce计数器实验的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于java的银行账目管理系统
- 下一篇: OKR学习笔记01:OKR定义