MapReduce--7--求共同好友--改进版JobControl

MapReduce–7--求共同好友–改进版JobControl

在上一节

链接: MapReduce–6--共同好友.

中,我们发现,一个需求得出解,需要有两个MapReduce程序,那么如果碰到类似的需要运行多个有依赖关系的Job时,我们可以使用JobControl这个工具类,来管理多个具有依赖关系的job的运行, 所以上一MapReduce案例,我做了如下改写:

请看具体的代码实现:

package com.ghgj.mazh.mapreduce.jobControl;
 
import java.io.IOException;
import java.util.Arrays;
 
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.LongWritable;
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.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.jobcontrol.ControlledJob;
import org.apache.hadoop.mapreduce.lib.jobcontrol.JobControl;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
 
/**
 * 
 * 描述:求共同好友 -- 因为需要运行多个Job,所以使用JobControl对象来管理这多个具有依赖关系的任务的运行。
 */
public class CommonFirendsMR {
 
	public static void main(String[] args) throws Exception {
 
		Configuration conf = new Configuration();
		FileSystem fs = FileSystem.get(conf);
		
		/**
		 * 第一个job信息
		 */
		Job job = Job.getInstance(conf);
		job.setJarByClass(CommonFirendsMR.class);
		job.setMapperClass(CommonFriends1MRMapper.class);
		job.setReducerClass(CommonFriends1MRReducer.class);
		job.setMapOutputKeyClass(Text.class);
		job.setMapOutputValueClass(Text.class);
		job.setOutputKeyClass(Text.class);
		job.setOutputValueClass(Text.class);
		Path p1 = new Path("D:\\bigdata\\commonfriends\\input");
		Path p2 = new Path("D:\\bigdata\\commonfriends\\step1_output");
		if(fs.exists(p2)){
			fs.delete(p2, true);
		}
		FileInputFormat.setInputPaths(job, p1);
		FileOutputFormat.setOutputPath(job, p2);
		
		/**
		 * 第二个job信息
		 */
		Job job2 = Job.getInstance(conf);
		job2.setJarByClass(CommonFirendsMR.class);
		job2.setMapperClass(CommonFriends2MRMapper.class);
		job2.setReducerClass(CommonFriends2MRReducer.class);
		job2.setMapOutputKeyClass(Text.class);
		job2.setMapOutputValueClass(Text.class);
		job2.setOutputKeyClass(Text.class);
		job2.setOutputValueClass(Text.class);
		Path inpath2 = new Path("D:\\bigdata\\commonfriends\\step1_output");
		Path outPath2 = new Path("D:\\bigdata\\commonfriends\\step2_output");
		if (fs.exists(outPath2)) {
			fs.delete(outPath2, true);
		}
		FileInputFormat.setInputPaths(job2, inpath2);
		FileOutputFormat.setOutputPath(job2, outPath2);
		
		
		ControlledJob step1Job = new ControlledJob(job.getConfiguration());
		ControlledJob step2Job = new ControlledJob(job.getConfiguration());
		step1Job.setJob(job);
		step2Job.setJob(job2);
		
		/**
		 * 添加job和job之间的依赖关系,在此题中:step2Job是依赖于step1Job的计算结果的。所以必须要等到step1Job执行完成后,才能执行step2Job的任务的计算
		 */
		step2Job.addDependingJob(step1Job);
		
		/**
		 * 通过JobControl这个工具类,可以让多个MapReduce Job可以被有条理的组织起来,进行有先后顺序的运行
		 * 其实JobControl就是一个线程类。
		 */
		JobControl jc = new JobControl("CommonFriends");
		jc.addJob(step1Job);
		jc.addJob(step2Job);
		
		/**
		 * 启动目标线程,开启任务的执行
		 */
		Thread jobThread = new Thread(jc);
		jobThread.start();
		
		/**
		 * 每隔一段时间来判断一下该jc线程的任务是否执行完成
		 */
		while(!jc.allFinished()){
			Thread.sleep(500);
		}
		
		/**
		 * 当主线程程序退出了上面的while循环,证明任务已经全部执行成功。这主线程也可以正常退出了。
		 */
		System.exit(0);
	}
 
	/**
	 * 
	 * 描述:第一个MapReduce程序的Mapper
	 */
	public static class CommonFriends1MRMapper extends Mapper<LongWritable, Text, Text, Text> {
 
		/**
		 * key : 读取文件内容时的每行的起始偏移量
		 * value : 读取到的一行文本
		 * 		格式:A:B,C,D,F,E,O
		 */
		@Override
		protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
			String line = value.toString();
			String[] tokens = line.split(":");
			String person = tokens[0];
			String[] friends = tokens[1].split(",");
 
			for (String f : friends) {
				/**
				 * 输出数据格式:
				 * B	A
				 * C	A
				 * D	A
				 * F	A
				 * E	A
				 * O	A
				 */
				context.write(new Text(f), new Text(person));
			}
		}
	}
 
	/**
	 * 
	 * 描述:第一个MapReduce程序的Reducer
	 */
	public static class CommonFriends1MRReducer extends Reducer<Text, Text, Text, Text> {
		@Override
		protected void reduce(Text friend, Iterable<Text> persons, Context context) throws IOException, InterruptedException {
 
			StringBuffer sb = new StringBuffer();
			for (Text p : persons) {
				sb.append(p).append("-");
			}
			
			/**
			 * 输出数据格式:
			 * A I-K-C-B-G-F-H-O-D- 
			 */
			context.write(friend, new Text(sb.toString()));
		}
	}
 
	/**
	 * 作者: 马中华:http://blog.csdn.net/zhongqi2513
	 * 日期: 2017年10月25日下午7:37:07
	 * 
	 * 描述:第二个MapReduce程序的Mapper
	 */
	public static class CommonFriends2MRMapper extends Mapper<LongWritable, Text, Text, Text> {
 
		/**
		 * A I-K-C-B-G-F-H-O-D- 
		 * B A-F-J-E- 
		 * C A-E-B-H-F-G-K-
		 */
		@Override
		protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
			String line = value.toString();
			String[] tokens = line.split("\t");
			String friend = tokens[0];
			String[] persons = tokens[1].split("-");
 
			Arrays.sort(persons);
			for (int i = 0; i < persons.length - 1; i++) {
				for (int j = i + 1; j < persons.length; j++) {
					
					/**
					 * 输出数据格式:
					 * I-K	A
					 * I-C	A
					 * ....
					 */
					context.write(new Text(persons[i] + "-" + persons[j]), new Text(friend));
				}
			}
		}
	}
 
	/**
	 * 作者: 马中华:http://blog.csdn.net/zhongqi2513
	 * 日期: 2017年10月25日下午7:37:19
	 * 
	 * 描述:第二个MapReduce程序的Reducer
	 */
	public static class CommonFriends2MRReducer extends Reducer<Text, Text, Text, Text> {
		@Override
		protected void reduce(Text person_pair, Iterable<Text> friends, Context context) throws IOException, InterruptedException {
 
			StringBuffer sb = new StringBuffer();
			for (Text f : friends) {
				sb.append(f).append(" ");
			}
			
			/**
			 * 输出数据格式:
			 * A-B	C E
			 */
			context.write(person_pair, new Text(sb.toString()));
		}
 
	}
}

如有不当之处,请不吝指教。 ヾ(◍°∇°◍)ノ゙


作者:中琦2513
来源:CSDN
原文:https://blog.csdn.net/zhongqi2513/article/details/78344509
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值