Map-Reduce数据分析之一(实例2通话清单分析)

实例要求:

给出一个文档:包含一批电话通信清单,记录了用户A拨打用户B的记录;
需要做一个倒排索引,记录拨打给用户B的所有用户A。

文档内容:

Map-Reduce数据分析之一(实例2通话清单分析)_第1张图片

分析:

map:将每行记录按空格符划分出两个数据,一个10086作为key值,一个135.。。作为value

reduce:将相同key值的value放到迭代器里,然后迭代将其value串起来。

代码如下:

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.StringTokenizer;

import javax.lang.model.SourceVersion;
import org.apache.hadoop.util.Tool;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.NullWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.Mapper;
import org.apache.hadoop.mapreduce.Reducer;
import org.apache.hadoop.mapreduce.Mapper.Context;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
import org.apache.hadoop.util.GenericOptionsParser;
import org.apache.hadoop.util.ToolRunner;

/*
 *给出一个文档:包含一批电话通信清单,记录了用户A拨打用户B的记录
 *需要做一个倒排索引,记录拨打给用户B的所有用户A
 */
public class Test_2 extends Configured implements Tool
{
	enum Counter
	{
		LINESKIP;//出错到行  
	}
	public static class Map extends  Mapper<LongWritable,Text,Text,Text>
	{/*参数依次说明:输入key的格式,输入value到格式;输出key到格式,输出value到格式(<span style="font-family: Arial, Helvetica, sans-serif;">因为本例中使用的是TextInputFormat将不同类型的输入数据转化为Map能够处理的<key,value>,它的输出key值是LongWritable类型,value值是Text类型;</span><span style="font-family: Arial, Helvetica, sans-serif;">所以Map()的输入类型即为<LongWritable,Text>)*/</span>
		public void map(LongWritable key,Text value,Context context)throws IOException,InterruptedException
		{//context被称为上下文机制
			String line=value.toString();//读入原数据
			Text  word=new Text();
			try
			{
				//数据处理
				 String [] lineSplite=line.split(" ");//按135,10086分为anum,bnum
			    String anum=lineSplite[0];
			    String bnum=lineSplite[1];
			 
			    context.write(new Text(bnum),new Text(anum));//
			}
			catch(java.lang.ArrayIndexOutOfBoundsException e)
			{
				context.getCounter(Counter.LINESKIP).increment(1);//出错令计数器+1(数据缺失出错时)
				return;
			}
			
		}
	}
	public static class Reduce extends  Reducer<Text,Text,Text,Text>
	{//参数:输入输出到key和value(Reducer的输入格式必须要和Mapper的输出格式相一致)
		public void reduce(Text key,Iterable<Text>values,Context context) throws IOException,InterruptedException
		{//参数:key存10086,value作为一个迭代器存放所有打给10086的号码;context为上下文机制,负责将Map()输出的<key,value>进行收集
			String valueString;
			String out="";
			for(Text value:values)
			{
				valueString=value.toString();//将每个value字符串化,然后串起来且用|分割开
				out+=valueString+"|";
			}
			context.write(key, new Text(out));//输出key和value且中间用制表符分离
		}
	}
	public int run(String[] args) throws Exception
	{
		Configuration conf=getConf();
		Job job=new Job(conf,"Test_2");//任务名
		job.setJarByClass(Test_2.class);//指定class

		job.setOutputKeyClass(Text.class);//指定输出的key格式
		job.setOutputValueClass(Text.class);//指定输出的value格式
		job.setMapperClass( Map.class);//调用上面到Map类作为Map任务代码
		job.setReducerClass(Reduce.class);
		FileInputFormat.addInputPath(job, new Path(args[0]));//输入路径
		FileOutputFormat.setOutputPath(job, new Path(args[1]));//输出路径
		
		job.waitForCompletion(true);
		return  job.isSuccessful() ?0:1;
	}
	public static void main(String[] args) throws Exception
	{
		//运行任务
		int res=ToolRunner.run(new Configuration(),new Test_2(), args);
		System.exit(res);
	}
}

运行结果:

Map-Reduce数据分析之一(实例2通话清单分析)_第2张图片

你可能感兴趣的:(Map-Reduce数据分析之一(实例2通话清单分析))