MapReduce
概述
- Map函数
- 原始输出
<key,value>
包含重复项
- Reduce函数
- 输入
<key,value-list>
- 输出
<key,value>
体系结构
- Client
- 可以提交编写的应用程序
- 可以通过它提供的一些接口去查看当前提交作业的
- JobTracker
- 负责资源的监控和作业的调度
- 监控底层和其他的TaskTracker以及当前运行的Job健康状况
- 一旦探测失败的情况,就把这个任务转移到其他节点继续执行任务实现
- TaskTracker
- 执行具体的相关任务一般接受JobTracker发送过来的命令
- 把一些自己的资源使情况,以及任务的运行进度通过heartbeat发送给JobTracker
- slot
- reduce类型->reduce任务
- map类型->map任务
- Task
* map
* reduce - 设计理念:计算向数据考虑
- 归并:值的list化,合并:值的改变,但是要确保不能改变结果
- 采用"分而治之"的策略,大规模数据集会被切分成许多独立的分片
工作流程
- shuffle
- 执行的各个阶段
- 最优Reduce任务个数取决于集群中可用的reduce任务槽(slot)数目
- 但是个数要少于任务槽
Shuffle
- Map端和Reduce端的shuffle
- Map端的Shuffle是对输出结果进行分区、排序、合并等处理,并交给Reduce
Map端
- 过程
- 输入数据和执行Map任务
- 写入缓存
- 溢写(分区、排序、合并)
- 缓存满了就会进行
- 需要设置溢写比例
- 合并:减少写入磁盘的数据量,需要用户定义启动
- 文件归并
- 键值分区、且归并
Reduce端
- "领取"数据
- 归并数据:将数据进行合并为list等
- 把数据输入给Reduce任务
应用执行过程
- 程序部署
- 执行reduce任务或者执行map任务
- 读数据:<key,value>键值对
- 本地写数据
- 远程读数据
- 写数据
WordCount
- 输入大量单词文本文件
- 输出每个单词出现频率
- Map输出shuffle以后,键值对,值变成list集合,Reduce输出统计值list集合结果
具体应用
-
…
-
自然连接:Map映射生成key-value,Reduce对key值相同的进行汇总
-
编程实现
- Map处理逻辑
<key,value>
输出 - Reduce处理逻辑
<key,value-list>
输入Iterable容器
- Map处理逻辑
-
打包编译
MapReduce执行过程
输入分片,执行Map任务,通过shuffle操作之后进行Reduce操作
输入和输出过程
- 数据从文件中读取并形成键值对
- 依赖关系:TextInputFormat -> FileInputFormat -> InputFormat:getSplites&createRecordReader
- 主要功能:获取分片列表,创建记录读取器
输入
定义数据是如何从HDFS的文件中读取并转换为map函数能够处理的<key,value>形式
- getSplites思路(FileInputFormat类)
- getFormatMinSplitSize() & getMaxSpiltSize() & getgetMinSplitSize() 设置分片最大值和最小值的方法,三个方法分别对应以下解释
- 返回固定值1
- 读取配置的值(默认为Long 类型的最大值)
- 读取配置的值(默认为0)
- 存储分片结果
- 对文件进行分片 | 不可切片则退回整片数据 | 长度为零则设置空Hosts列表
- 获取文件block信息列表:位置/文件中偏移量/大小
- isSplitable() (from FileInputFormat) –
- splitSize 由 computeSplitSize(block大小,分片分片最大值,分片最小值)决定
if(blockSize<maxSize&&minSize<blockSize) splitSize=blockSize; else splitSize=maxSize;
- while循环切片操作:文件比切片大小大(一般1.1产量决定值)
- 改变block索引值
- 切片列表添加切片的内容(由block索引值决定切片文件范围):非物理划分
- 偏移量:length-bytesRemaining
- 改变剩余量
- 剩余量处理
- 将剩余的按照while循环中的切片操作处理
- 根据原始文件的大小设置输入文件数量
- 返回切片集合
- getFormatMinSplitSize() & getMaxSpiltSize() & getgetMinSplitSize() 设置分片最大值和最小值的方法,三个方法分别对应以下解释
读取分片转化数据
- LineRecordReader思路(TextInputFormat类)
- extends RecordReader
- initialize:初始化
- 主要:不是第一个分片则丢弃第一行同时会多读取一行(设置pos值)
- nextKeyValue:读取并返回下一个键值对
- 初始化key(此行数据在文件中的偏移量:pos值),value值
- 循环读取每一行数据,通过回车换行等读取一行数据到value
- maxLineLength作为临界值进行读取分割
- 下一分片第一行数据是否存在的判断结果
- getCurrentKey & getCurrentValue:只有在nextKeyValue返回true调用
- getProgress:读取记录的进度
- close:清理创建的RecordReader对象
- initialize:初始化
- extends RecordReader
自定义输入
- extends InputFormat
- 实现getSplits & createRecordReader
- createRecordReader
- 自定义RecordReader类,重载initialize & nextKeyValue
输出
将reduce函数的输出写到HDFS文件
- TextOutputFormat -> FileOutputFormat -> OutputFormat:
- getRecordWrite() : 返回write对象(写记录)
- checkOutputSpecs() : 检查输出设置是否合法
- 输出目录是否被设置
- y:检查输出目录是否存在
- y:抛出异常
- y:检查输出目录是否存在
- 输出目录是否被设置
- getOutputCommitter() : 传入输出流
- 对临时文件和文件的创建删除移动等操作,由TextOutputFormat实现
- TextOutputFormat实现
- 提供了getRecordWrite()操作的实现(主要实现的方法)
- 返回LineRecordWriter类(内部类,传入了写入流)实例
- 提供了getRecordWrite()操作的实现(主要实现的方法)
- LineRecordWriter实现 -> RecordWriter:获取输出文件的路径,创 建写入数据到文件的输出流,通过输出流创建
- write
- close
- LineRecordWriter的writer(继承RecordWrite)
- synchronized 与写互斥
- 判断key和value是否为空进行写入操作
- key
- 分隔符
- value
- 分行符
- Text类型的判断:获取字节数组
自定义输出格式
- 实现OutputFormat方法中的三个方法,主要重载getOutputCommitter()
- 重载getRecordWriter:RecordWriter(ouputstream)
- 自定义新的输出格式:自定义新的RecordWriter()类型
- 键值对写入所传入的输出流
- 继承RecordWrite,需要实现wirte&close
- 自定义新的输出格式:自定义新的RecordWriter()类型
注:&代表和,->代表继承
补充知识:yarn
-
facebook发布的取代npm的包管理工具
- 快、安全、可靠