经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 大数据/云/AI » Hadoop » 查看文章
学习笔记—MapReduce
来源:cnblogs  作者:码小白  时间:2018/12/10 9:34:04  对本文有异议

MapReduce是什么

MapReduce是一种分布式计算编程框架,是Hadoop主要组成部分之一,可以让用户专注于编写核心逻辑代码,最后以高可靠、高容错的方式在大型集群上并行处理大量数据。

MapReduce的存储

MapReduce的数据是存储在HDFS上的,HDFS也是Hadoop的主要组成部分之一。下边是MapReduce在HDFS上的存储的图解

HDFS Architecture

HDFS主要有Namenode和Datanode两部分组成,整个集群有一个Namenode和多个DataNode,通常每一个节点一个DataNode,Namenode的主要功能是用来管理客户端client对数据文件的操作请求和储存数据文件的地址。DataNode主要是用来储存和管理本节点的数据文件。节点内部数据文件被分为一个或多个block块(block默认大小原来是64MB,后来变为128MB),然后这些块储存在一组DataNode中。(这里不对HDFS做过多的介绍,后续会写一篇详细的HDFS笔记)

MapReduce的运行流程

屏幕快照 2018-12-05 下午10.43.38

屏幕快照 2018-12-05 下午10.56.38

1、首先把需要处理的数据文件上传到HDFS上,然后这些数据会被分为好多个小的分片,然后每个分片对应一个map任务,推荐情况下分片的大小等于block块的大小。然后map的计算结果会暂存到一个内存缓冲区内,该缓冲区默认为100M,等缓存的数据达到一个阈值的时候,默认情况下是80%,然后会在磁盘创建一个文件,开始向文件里边写入数据。

2、map任务的输入数据的格式是<key,value>对的形式,我们也可以自定义自己的<key,value>类型。然后map在往内存缓冲区里写入数据的时候会根据key进行排序,同样溢写到磁盘的文件里的数据也是排好序的,最后map任务结束的时候可能会产生多个数据文件,然后把这些数据文件再根据归并排序合并成一个大的文件。

3、然后每个分片都会经过map任务后产生一个排好序的文件,同样文件的格式也是<key,value>对的形式,然后通过对key进行hash的方式把数据分配到不同的reduce里边去,这样对每个分片的数据进行hash,再把每个分片分配过来的数据进行合并,合并过程中也是不断进行排序的。最后数据经过reduce任务的处理就产生了最后的输出。

4、在我们开发中只需要对中间map和reduce的逻辑进行开发就可以了,中间分片,排序,合并,分配都有MapReduce框架帮我完成了。

MapReduce的资源调度系统

最后我们来看一下MapReduce的资源调度系统Yarn。

MapReduce NextGen??????

Yarn的基本思想是将资源管理和作业调度/监视的功能分解为单独的守护进程。全局唯一的ResourceManager是负责所有应用程序之间的资源的调度和分配,每个程序有一个ApplicationMaster,ApplicationMaster实际上是一个特定于框架的库,其任务是协调来自ResourceManager的资源,并与NodeManager一起执行和监视任务。NodeManager是每台机器框架代理,监视其资源使用情况(CPU,内存,磁盘,网络)并将其报告给ResourceManager。

WordConut代码

  • python实现

map.py

  1. #!/usr/bin/env python
  2. # -*- coding:UTF-8 -*-
  3. import sys
  4. for line in sys.stdin:
  5. words = line.strip().split()
  6. for word in words:
  7. print('%s\t%s' % (word, 1))

reduce.py

  1. #!/usr/bin/env python
  2. # -*- coding:UTF-8 -*-
  3. import sys
  4. current_word = None
  5. sum = 0
  6. for line in sys.stdin:
  7. word, count = line.strip().split(' ')
  8. if current_word == None:
  9. current_word = word
  10. if word != current_word:
  11. print('%s\t%s' % (current_word, sum))
  12. current_word = word
  13. sum = 0
  14. sum += int(count)
  15. print('%s\t%s' % (current_word, sum))

我们先把输入文件上传到HDFS上去

  1. hadoop fs -put /input.txt /

? 然后在Linux下运行,为了方便我们把命令写成了shell文件

  1. HADOOP_CMD="/usr/local/src/hadoop-2.6.1/bin/hadoop"
  2. STREAM_JAR_PATH="/usr/local/src/hadoop-2.6.1/share/hadoop/tools/lib/hadoop-streaming-2.6.1.jar"
  3. INPUT_FILE_PATH="/input.txt"
  4. OUTPUT_FILE_PATH="/output"
  5. $HADOOP_CMD fs -rmr -skipTrush $OUTPUT_FILE_PATH
  6. $HADOOP_CMD jar $STREAM_JAR_PATH -input $INPUT_FILE_PATH -output $OUTPUT_FILE_PATH -mapper "python map.py" -reducer "python reduce.py" -file "./map.py" -file "./reduce.py"
  • java实现

MyMap.java

  1. import org.apache.hadoop.io.IntWritable;
  2. import org.apache.hadoop.io.LongWritable;
  3. import org.apache.hadoop.io.Text;
  4. import org.apache.hadoop.mapreduce.Mapper;
  5. import java.io.IOException;
  6. public class MyMap extends Mapper<LongWritable, Text, Text, IntWritable> {
  7. private IntWritable one = new IntWritable(1);
  8. private Text text = new Text();
  9. @Override
  10. protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
  11. String line = value.toString();
  12. String[] words = line.split(" ");
  13. for (String word: words){
  14. text.set(word);
  15. context.write(text,one);
  16. }
  17. }
  18. }

MyReduce.java

  1. import org.apache.hadoop.io.IntWritable;
  2. import org.apache.hadoop.io.Text;
  3. import org.apache.hadoop.mapreduce.Reducer;
  4. import java.io.IOException;
  5. public class MyReduce extends Reducer<Text, IntWritable, Text, IntWritable> {
  6. private IntWritable result = new IntWritable();
  7. @Override
  8. protected void reduce(Text key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {
  9. int sum = 0;
  10. for (IntWritable i:values){
  11. sum+=i.get();
  12. }
  13. result.set(sum);
  14. context.write(key,result);
  15. }
  16. }

WordCount.java

  1. import org.apache.hadoop.conf.Configuration;
  2. import org.apache.hadoop.fs.Path;
  3. import org.apache.hadoop.io.IntWritable;
  4. import org.apache.hadoop.io.Text;
  5. import org.apache.hadoop.mapreduce.Job;
  6. import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
  7. import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;
  8. public class WordCount {
  9. public static void main(String[] args) throws Exception {
  10. Configuration configuration = new Configuration();
  11. Job job = Job.getInstance(configuration, "WordCount");
  12. job.setJarByClass(WordCount.class);
  13. job.setMapperClass(MyMap.class);
  14. job.setReducerClass(MyReduce.class);
  15. job.setOutputKeyClass(Text.class);
  16. job.setOutputValueClass(IntWritable.class);
  17. FileInputFormat.addInputPath(job, new Path(args[0]));
  18. FileOutputFormat.setOutputPath(job, new Path(args[1]));
  19. System.exit(job.waitForCompletion(true) ? 0 : 1);
  20. }
  21. }

把工程打成jar包,然后把jar包和输入文件上传到HDfs

  1. $ hadoop fs -put /wordcount.jar /
  2. $ hadoop fs -put /input.txt /

执行wordcount任务

  1. $ bin/hadoop jar wordcount.jar WordCount /input.txt /user/joe/wordcount/output

欢迎关注公众号:「努力给自己看」

扫码

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号