MapReduce之WordCount
本博客采用创作共用版权协议, 要求署名、非商业用途和保持一致. 转载本博客文章必须也遵循署名-非商业用途-保持一致的创作共用协议.
#1. 再述MapReduce计算模型
- JobTracker用于管理和调度工作(
一个集群只有一个JobTracker) - TaskTracker用于执行工作
- 每个MapReduce任务被初始化为一个Job, 每个Job分为Map(接收键值对)和Reduce阶段
InputSplit(存储分片长度和记录数据位置的数组)把输入数据传送给单独的Map, 数据传给Map后, Map将输入分片传送到InputFormat()上, InputFormat()(用来生成可供Map处理的键值对)调用getRecordReader()方法生成RecordReader, RecordReader再通过createKey(), createValue()方法创建可供Map处理的键值对.TextInputFormat是Hadoop默认的输入方法, 每个文件都读作为Map的输入, 每行数组生成一条键值对(key在数据分片中的字节偏移量LongWritable, value是每行内容Text)
#2. 编译打包运行WordCount
总结一下通过Eclipse来编译打包运行自己写的MapReduce程序(基于Hadoop2.6.0)
##2.1. Hadoop库
在编写Hadoop程序会用到Hadoop库, 所以需要一些Hadoop库文件, 用于编译
- hadoop-common-2.6.0.jar
- hadoop-mapreduce-client-core-2.6.0.jar
- hadoop-test-1.2.1.jar
下载地址Group: org.apache.hadoop下载对应版本的库文件
##2.2. 创建工程
- 使用Eclipse创建名为WordCount的工程
- 在
Project Properties -> Java Build Path -> Libraries -> Add External Jars添加第一步所下载Jar包, 点击OK - 创建WordCount.java源文件
|
|
##2.3. 打包源文件
- 在
File -> Export -> Java -> JAR File, 然后点击next - 选中WordCount源文件, 设置输出路径和文件名WordCount.jar, 选择Finish则打包成功
- 在输出路径生成Wordcount.jar
##2.4. 启动HDFS服务
打开目录/usr/local/Cellar/hadoop/2.6.0/sbin
|
|
成功启动服务后, 可以直接在浏览器中输入http://localhost:50070/访问Hadoop页面
##2.5. 将输入文件上传到HDFS
打开目录/usr/local/Cellar/hadoop/2.6.0/bin
|
|
##2.6. 运行Jar文件
|
|
|
|
##2.7. 查看运行结果
|
|
##2.8. MapReduce运行流程
- JobTracker调度任务个TaskTracker, TaskTracker执行任务时, 返回进度报告, 如果执行失败, JobTracker将任务分配给另一个TaskTracker, 知道任务完成
- 数据按照TextInputFormat被处理成InputSplit, 输入到Map中, Map读取InputSplit指定位置的数据,
按照设定的方式处理数据, 最后写入本地磁盘 - Reduce读取Map输出数据, 合并value, 然后输出到HDFS上
#3. MapReduce任务优化
- 计算性能优化
- I/O操作优化
- 任务调度(就近原则, 选用空闲原则)
- 数据预处理应合理设置block快大小及Map和Reduce任务数量
- combine函数用于本地合并数据的函数, 运行用户combine用于本地合并, 可减少网络I/O的消耗
- 对Map输出和最终结果压缩
- 自定义comparator实现数据的二进制比较, 省去数据序列化和反序列化时间
#4. Hadoop流
当一个可执行未见作为Mapper时, 每个Map任务以一个独立的进程启动可执行未见, 任务执行时, 会把输入划分成行提供给可执行文件, 并作为Map的标准输入, Map从标准输出中收集数据, 并转换为<key, value>输出
Reduce任务启动可执行文件, 将键值对转化为标准输入, Reduce从标准输出中收集数据, 并转换为<key, value>输出