job客户端代码编写+使用

package com.sl;

import java.io.IOException;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;
/*
 * KEYIN		mt读取到的数据的key类型,是一行的起点偏移量-Long	
 * VALUEIN		mt读取的value的内容,是一行的内容-String
 * KEYOUT		用户自定义map方法,用户返回的kv值的key类型-在此demo中是String
 * VALUEOUT		用户自定义map方法,用户返回的kv值的value类型-在此demo中是Integet
 * 但是在map传输给reduce中,需要将数据序列化和反序列化(因为以上数据类型都是对象),但是jdk原生的序列化机制太冗余,所以
 * 必须自己实现hadoop自己的序列化接口,使用Hadoop自带的序列化机制
 * Hadoop为常用的数据类型Long,String,Integer,Float封装了自己的实现接口,分别是:LongWritable,Text,IntWritable,FloatWritable
 */
public class WordCountMapper extends Mapper<LongWritable, Text, Text, IntWritable>
{
	/**
	 * 重写父类的map方法,因为mp只认这个方法
	 * hadoop会直接把参数给你把一行数据传进来,运行此方法
	 */
	@Override
	protected void map(LongWritable key, Text value, Context context)
			throws IOException, InterruptedException
	{
		//传进来是一行数据,并封装成text对象,所以要拿此对象做手脚
		String line = value.toString();//转成字符串
		//切单词
		String[] words = line.split(" ");
		for (String word : words)
		{
			context.write(new Text(word), new IntWritable(1));
			
			//每次都会往context中存数据,然后context会攒着
			
		}
	}

}

package com.sl;

import java.util.Iterator;

import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;

public class WordcountReducer extends Reducer<Text, IntWritable, Text, IntWritable>
{
	//传到reduce时,得到的是一个key和一组values,values被封装成一个迭代器,靠迭代器再
	@Override
	protected void reduce(Text key, java.lang.Iterable<IntWritable> values,Context context) 
			throws java.io.IOException ,InterruptedException 
	{	int count = 0;
		Iterator<IntWritable> iterator = values.iterator();
		while(iterator.hasNext())
		{
			IntWritable value = iterator.next();
			count+= value.get();
		}
		context.write(key, new IntWritable(count));
	};

}

package com.sl;

import org.apache.hadoop.conf.Configuration;
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;




public class JobSubmitter
{
	public static void main(String[] args) throws Exception
	{
		//设置JVM系统参数,用于给job访问系统赋予权限
		System.setProperty("HADOOP_USER_NAME", "root");
		
		
		//创建conf对象,用来设置参数
		Configuration conf = new Configuration();
		//1,设置job运行时访问的默认文件系统
		conf.set("fs.defaultFS", "hdfs://node1:9000");
		//2,设置job提交去哪运行。yarn/local
		conf.set("mapreduce.framework", "yarn");
		conf.set("yarn.resourcemanager.hostname", "node1");
		//如果跨平台提交,则加的语句
		conf.set("mapreduce.app-submission.cross-platform", "true");
		
		Job job = Job.getInstance(conf);
		//1,封装参数:jar包所在位置---通过类加载器获取当前类的位置,然后依此拿所有的jar包
		job.setJar("d://wc.jar");
		job.setJarByClass(JobSubmitter.class);
		//2, 封装参数:本次job索要调用的两个实现类
		job.setMapperClass(WordCountMapper.class);
		job.setReducerClass(WordcountReducer.class);
		//3, 封装参数:本次job两个实现类所产生的数据的k/v的类型
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(IntWritable.class);
		
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(IntWritable.class);
		//4, 封装参数:本次job要处理的数据集的路径/结果是输出路径--输出路径必须不存在,存在则抛异常
		FileInputFormat.setInputPaths(job, new Path("/wordcount/input"));
		FileOutputFormat.setOutputPath(job, new Path("/wordcount/outputb"));
		//5,封装参数:想要启动的reduce task的数量
		job.setNumReduceTasks(2);
		//6,提交job--等待完成(boolean是决定是否将反馈信息打印到控制台)---返回值返回Hadoop是否成功
		//job.submit();
		boolean status = job.waitForCompletion(true);
		System.out.println(status);
		System.exit(status?0:-1);
		
	}
}

注:

  1. 不要导错Text包-----有很多
  2. 加载class类,要把三个java文件导成jar包,然后从本地加载类(job的34行)
  3. 如果遇见nativeIO错误,就是要改源码文件—见另一篇文章

猜你喜欢

转载自blog.csdn.net/xydxsl/article/details/87908966
今日推荐