(接上:Hadoop-MR實現日誌清洗(一))java
4.groupbycount測試sql
編寫Hadoop-MR的groupbycount程序測試Hadoop運行環境,同時也是對mapreduce程序的一次複習。apache
爲了避免影響logparser項目結構,單首創建了groupbycount項目,配置與logparser一致。數據結構
初始結構:app
4.1源文件準備ide
源文件取自工做中部分數據集。函數
下載地址:2018-08-29-15-03-13_1959.rar oop
樣例數據:測試
leeyk99 fr fr pc Boutique Day Dresses 18 0 0 20180828 leeyk99 fr fr pc Women Accessories Phone Cases 4 0 0 20180828 leeyk99 fr fr pc Women Accessories Scarves 5 0 0 20180828 leeyk99 fr fr pc Women Beauty Beauty Tools Makeup Tools 1 0 0 20180828 leeyk99 fr fr pc Women Clothing Beachwear Swimwear 4 0 0 20180828 leeyk99 fr fr pc Women Clothing Bottoms Shorts 1 0 0 20180828
數據結構:spa
4.2map函數
package com.leeyk99.udp; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Mapper; import java.io.IOException; public class GroupByCountMapper extends Mapper<LongWritable, Text, Text, IntWritable> { private final int ONE=1; @Override protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { //super.map(key, value, context); String line=value.toString(); String[] lineSplit=line.split("\t"); String siteTp=lineSplit[0]; context.write(new Text(siteTp),new IntWritable(ONE)); } }
4.3reduce函數
package com.leeyk99.udp; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Reducer; import java.io.IOException; //import java.util.Iterator; public class GroupByCountReducer extends Reducer<Text, IntWritable, Text, IntWritable>{ @Override protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException { //super.reduce(key, values, context); Integer sum=0; /*Iterator<IntWritable> it=values.iterator(); if(it.hasNext()){ sum+=it.next().get(); }*/ for (IntWritable value : values ) { sum+=value.get(); } context.write(key,new IntWritable(sum)); } }
4.4程序入口
package com.leeyk99.udp; import org.apache.hadoop.fs.Path; import org.apache.hadoop.io.IntWritable; import org.apache.hadoop.io.Text; import org.apache.hadoop.mapreduce.Job; import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; import java.io.File; //import java.io.IOException; public class GroupByCount { public static void main(String[] args) throws Exception{//Exception範圍比較大,包含IOException、InterruptedException if(args.length != 2){ System.err.println("Usage: GroupByCount <input path> <output path>"); System.exit(-1); } Job job=new Job(); job.setJarByClass(GroupByCount.class); job.setJobName("job-GroupByCount"); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); job.setMapperClass(GroupByCountMapper.class); job.setReducerClass(GroupByCountReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); delDir(args[1]); System.exit(job.waitForCompletion(true)? 0 : 1); } private static void delDir(String path){ File f=new File(path); if(f.exists()){ if(f.isDirectory()){ String[] items=f.list(); for( String item : items ){ File f2=new File(path+"/"+item); if(f2.isDirectory()){ delDir(path+"/"+item); } else{ f2.delete(); } } } f.delete(); //刪除文件或者最後的空目錄 } else{ System.out.println("Output directory does not exist ."); } } }
4.5del函數
寫在入口函數中,也能夠單首創建個類。
private static void delDir(String path){ File f=new File(path); if(f.exists()){ if(f.isDirectory()){ String[] items=f.list(); for( String item : items ){ File f2=new File(path+"/"+item); if(f2.isDirectory()){ delDir(path+"/"+item); } else{ f2.delete(); } } } f.delete(); //刪除文件或者最後的空目錄 } else{ System.out.println("Output directory does not exist ."); } }
4.6測試
在IDEA中須要設置下運行配置(Run/Debug Configurations):點擊 + ,建立一個Application,選一下main class(通常輸入項目名或類名,去查找的時候已經自動列出來可選的main了),設置下程序參數(Program arguments): input/ output/
獲得:
點擊 ▶ 運行,獲得結果:
4.7小結
本次測試使用mapreduce實現相似sql: select key,count(user_id) from tableName group by key 用法的功能。
mapreduce程序的核心就是reduce函數中的計算實現,即對輸入值的遍歷處理,好比求和、計數、比較、取均、去重等多種運算。
目前已完成 單維度求和、單維度計數。像Max、Min、取均這三類無需再嘗試,由於這個三類和求和、計數相似。
後續繼續實現 單維度去重計數、單維度去重、無維度求和。
至於多維度,其實很簡單,由於在map函數中,獲得多列後合併成一個字符串做爲key(這幾個字段的分隔符至關於在Hive中指定的列分隔符)。(初步思路)
key和value的分隔符,如何指定呢(不是用默認的\t)?後續作一次多維度單指標求和測試。
那麼多維度多指標求和如何作呢?後續繼續測試。