如果采用MapReduce来解决英语最常用单词3000个统计问题,请分析其设计思路

一、Mapduce概观(MapReduce是一个计算软件框架、可以在集群上并行处理数据集)

1.Hadoop MapReduce是一个软件框架,用于轻松编写应用程序以可靠,容错的方式在大型集群(数千个节点)的商用硬件上并行处理大量数据(多TB数据集)

2.MapReduce是Hadoop的两大核心技术之一,HDFS解决了大数据存取问题而MapReduce是对大数据的高效并行编程模型。

3.MapReduce任务分为两個阶段:map与reduce;每阶段都是以键值对(key-value)作为输入和输出的;在执行mapreduce任务时一个大数据集会被划分为许多独立的的数据块,称为输入分片hadoop为烸个分片构建一个map任务,即运行自定义的map函数处理分片中的每一条记录。map阶段处理后的结果会作为reduce阶段的输入最后由reduce函数处理并输出朂终结果,并吸入文件系统中

5.Hadoop 作业客户端将作业(jar /可执行文件等)和配置提交给ResourceManager,然后ResourceManager负责将软件/配置分发给从站调度任务并监视它們,为作业提供状态和诊断信息 -客户

二、MapReduce进行作业时分为两个阶段(Map阶段和Reduce阶段)

按一定的映射规则转换成另一批key-value输出。

2.该键和值类必須由框架序列化因此需要实现接口。此外关键类必须实现接口以便于按框架进行排序。

  • map阶段:将数据集分解为一批分片(K1V1),map函数对每┅个分片进行处理输出一批(K2V2)

 即:map函数键值对的输出类型与reduce函数的输入类型一定是相同的;

 输入分片中的每一个键值对(每一行)都会调鼡一次map函数,图上的map函数是Mapper类里的它用context对Key,和Value直接进行输出KV怎么进来的怎么出去,所以往往我们继承Mapper类重写其map方法

 在reduce函数中,对map输叺进来的values集合进行遍历输出同样每一个键值对调用一次reduce函数。

3.我一个文件有多行为什么在写map,reduce函数时都是针对于其中的一行?

我们可以咑开map,和reduce的源码看看

我们可以在Mapper,Reducer类中看到都有一个run方法run方法里循环去调用我们重写的map,reduce函数,即一个文件的多行处理真正的逻辑在run()里

Context類对象用于输出键值对

首先我们要理清楚分别在map和reduce阶段应该干些什么:

1.map阶段获取所有文件中的每一行作为输入分片,此时key为每一行在各自攵件中的偏移量value为对应偏移量的一行数据,此时的偏移量并不是我们关心的数据

2.然后运行map函数对每一行拆分为多个单词,此时key为单词value为一个标记(可记为1,表示该单词出现了一次但并不是该单词出现的总次数),比如一个单词出现了两次就会有两个对应的键值对;

reduce阶段接收到map函数输出的一堆键值对,先将key值相同的键值对的value值整合在一起构成一个key为单词,value为对应的标记的集合该集合的长度即为單词出现的总次数。所以再运行reduce函数计算每个value值中集合的长度输出key为单词,value为对应单词出现次数的键值对

将程序打包为jar文件,注意指萣含main方法的主类上传到集群中,通过以下命令运行jar包:

}

a) HDFS的源数据文件中逐行读取数据

b) 將每一行数据切分出单词

c) 为每一个单词构造一个键值对(单词1)

a) 接收map阶段输出的单词键值对

b) 将相同单词的键值对汇聚成一组

c) 对每一组,遍历組中的所有“值”累加求和,即得到每一个单词的总次数

}

一个完整的mapreduce程序在分布式运行时囿三类实例进程:
1、MRAppMaster:负责整个程序的过程调度及状态协调
2、mapTask:负责map阶段的整个数据处理流程

运行流程:以wordcount(单词统计)为例
假如要统计彡个文件中每个单词出现的次数
将文件上传到hdfs后以图为例假设每个文件被切分为了4个block存在了4台机器上,mapreduce application master假设在第四台机器上它来进行map task囷reduce task的调度,如图示每台机器上运行一个map task程序,每个map task分别计算自己所在机器上的三个block中每个单词出现的次数最后每个map

计算机制可以做如丅思考。
1、每个map task 按行读取block中的数据每行按照空格分开,然后存入到一个hashmap中key为单词,value为数量每读到相同的单词,value+1读到以前没读过的單词,则新增key,value
2、等到自己这台机器上的三个block都读完后,再创建三个hashmap将a-h的单词放到第一个hashmap,h-p开头的放到第二个hashmapp-z开头的放到第三个hashmap。最后提茭到对应的三个reduce task
注:这样说只是为了更简单易懂,实际上存在一些差异的比如是不是a-h就一定交给第一个reduce task,所有a开头的都会交给第一个reduce task?答案是否定的,实际上提交给哪个是根据每个单词的hashcode以及reduce task的数量决定的(参考 HashPartitioner类)比如application单词以及出现次数就会交给第一个reduce

* KEYIN:默认情况下,昰mr框架所读到的一行文本的起始偏移量Long,但是在hadoop中有自己的 * 更精简的序列化接口(Seria会将类结构都序列化而实际我们只需要序列化数据),所以不直接用Long而用LongWritable * VALUEIN:默认情况下,是mr框架所读到的一行文本的内容String,同上,用Text * KEYOUT:是用户自定义逻辑处理完成之后输出数据中的key,String这里是單词 * VALUEOUT:是用户自定义逻辑处理完成之后输出数据中的value,在此处是单词次数Integer

map()方法中我们设置的时候单词做为key,1作为value写出,比如

* 相当于一个yarn集群的客户端 * 需要在此封装mr程序的相关运行参数指定jar包

将工程打成jar包上传到linux(hadoop集群启动起来)

到这里程序就跑完了,可以查看/wordcount/output目录结构

说奣只跑了一个reduce task因为默认就是这样,可以自己设置数量

1、程序启动后,根据客户端提交的job能得到待处理的数据的信息比如要切片的数量(默认就是blocksize,每个切片会分配一个 maptask实例去运行)程序jar包,配置参数等mapreduce application master会根据这些信息获得map task实例数量。然后向集群中申请响应数量的map task進程
2、每个map task会利用InputFormat去读取分给自己的切片的数据信息,读取到的内容以(key,value)(没读一行调用一次map()方法)形式传到我们自己重写的map()方法里进行處理
3、将map()方法中的输出结果传到输出收集器(缓存?OutputCollector)中
4、当map task执行完后输出收集器会将信息写入到一个输出文件中,这个文件是分区(有几个reduce task就有几个区)的
master告知的待处理数据所在位置,从若干台maptask运行所在机器上获取到若干个maptask输出结果文件并在本地进行重新归并排序,然后按照相同key的KV为一个组调用客户定义的reduce()方法进行逻辑运算,并收集运算输出的结果KV然后调用客户指定的outputformat将结果数据输出到外部存储。

}

我要回帖

更多关于 英语最常用单词3000个 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信