Mapreduce程序实现思路

Map的输出 是key,value的 list
Reduce的输入是key。value的list
MapReduce核心思想
分而治之,先分后和;
MapReduce是hadoop提供的一个分布式运算框架
1将任务分为两个阶段执行
第一阶段:map阶段:(3台机器)
读取数据自己节点的任务数据,处理数据,根据key的hashcode%n的值决定输出结果的位置

第二阶段:reduce阶段:(2台机器)
根据自己的任务编号处理对应的map产生的中间结果文件,最终统计出全局的数据结果
2移动运算优于移动数据(直接在本地处理数据,不经过网络)
MapReduce技能运行在本地,也能运行在yarn上,运行在yarn上,也就是说分布式运行,maptask和reducetask可以分别运行在不同的机器上,可以人为指定maptask和reducetask运行在指定的机器上或者由yarn去分配.

在这里插入图片描述
代码实现
map阶段:
/**

  • 单词统计
  • 根据自己的任务编号处理不同范围的数据 1 读取的是HDFS的数据 2 处理行数据 line line.split(" ") 单词 --> (单词 ,1)
  • (a,1) (a,1) (b,1) 3 根据单词的hashcode%reducetask的个数 = 根据结果数据写到不同的文件中

*/
public class MapTask {
public static void main(String[] args) throws Exception {
// 1 接收名执行输入的四个参数
String path = args[0];// 处理数据的路径
long start = Long.parseLong(args[1]); // 起始位置
long length = Long.parseLong(args[2]); // 长度
String taskId = args[3]; // 任务标号
// 2 根据自己的任务编号和任务的范围读取数据
// 2.1 获取操作HDFS的客户端对象
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(new URI(“hdfs://doit01:9000”), conf, “root”);
// 创建两个输出对象 0 1

	FSDataOutputStream out0 = fs.create(new Path("/data/wc/map_output/res_m_" + taskId + "_0"));// res_m_0_0
	FSDataOutputStream out1 = fs.create(new Path("/data/wc/map_output/res_m_" + taskId + "_1"));// res_m_0_1
	// 2.2 读数据 获取任务数据的输入流
	FSDataInputStream fin = fs.open(new Path(path));
	// 跳到自己的数据任务开始的位置
	fin.seek(start);
	// 2.3 转换成字符流方便处理
	BufferedReader br = new BufferedReader(new InputStreamReader(fin));
	// 丢弃第一行数据
	if (start !=  0) {
		br.readLine();
	}
	String line = null;
	long len = 0;
	while ((line = br.readLine()) != null) {
		len += line.length() + 2; // 在windows中的换行是\r\n
		// 处理这一行数据
		String[] words = line.split(" ");
		for (String word : words) {
			// 写出去 word.hashcode()%2 0 1
			if (word.hashCode() % 2 == 0) { // 写到0文件中 HDFS中
				//
				out0.writeUTF(word + "\t" + 1+"\n");// a 1 a 1
			} else { // 写到1 文中
				out1.writeUTF(word + "\t" + 1+"\n");
			}
		}
		// 跳出   读取属于自己的数据
		if (len > length) {// 128M 
			break;
		}

	}
     //释放资源
	out0.close();
	out1.close();
	br.close();
	fin.close();
	fs.close();

}

}

reduce阶段
/**

  • 读取属于自己的map端产生的数据
  • 统计最终的结果
  • @author ThinkPad

*/
public class ReduceTask {

public static void main(String[] args) throws Exception {
	Map<String , Integer> map =  new HashedMap() ;
	
	String  taskId  = args[0] ;// 0   1
	//  获取操作hdfs 的客户端对象
	Configuration conf = new Configuration();
	FileSystem fs = FileSystem.get(new URI("hdfs://doit01:9000"), conf, "root");
	// 遍历文件夹下的所有的文件   map端产生数据的文件夹
	RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/data/wc/map_output"), false);
	while(listFiles.hasNext()) {
		LocatedFileStatus file = listFiles.next();
		Path path = file.getPath();
		// 获取文件名
		String name = path.getName();
		// 根据文件名的后一个字母来判断要处理的文件
		if(name.endsWith(taskId)) { // 处理
			// 读取文件
			FSDataInputStream fin = fs.open(path);
			BufferedReader br = new BufferedReader(new InputStreamReader(fin));
			String line = null ;
			while((line = br.readLine())!=null) {
				String[] split = line.split("\t") ; //
				String word = split[0] ;// 
				map.put(word, map.getOrDefault(word, 0)+1) ;
			}
			br.close();
			fin.close();
		}
	}
	
	//  所有的结果数据在map中  
	FSDataOutputStream out = fs.create(new  Path("/data/wc/reduce_out/res_r_"+taskId));
	
  Set<Entry<String,Integer>> entrySet = map.entrySet();
  for (Entry<String, Integer> entry : entrySet) {
	  out.writeUTF(entry.getKey()+"\t"+entry.getValue()+"\n");//换行
   }
  out.flush();
  out.close();
  fs.close();
	
}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值