1.x版本 与 2.x版本的区别
JoJobTracker: 全局唯一,管理:资源管理,作业调度,作业监控,重新调度作业等。
TaskTracker: 对本节点的资源( cpu、内存、磁盘等 )进行划分,负责具体的作业执行工作
Task: 就是 MapTask 与 ReduceTask
弊端一目了然,JoJobTracker 工作量太大且 存在单节点故障.
有空附上说明…
.
2.x版本 YARN 将 MapReduce 1.X 中的 JobTracker 拆分成了两个独立的组件:
ResourceManager :负责整个集群的资源管理和分配。
ApplicationMaster : 负责与ResourceManager中的调度器通信获得资源,
将得到的任务进行分配,监控作业的执行情况。
上图的 ApplicationManager 本人觉得应该是在NodeManager节点上启动.
2.有了基础的知识点后,我们就可以深入的了解 MapReduce的框架原理
分为以下几个方面.
InputFormat 数据输入.
其实只做了两件事 getSplits()制作切片,与 RecordReader<K,V> 生成<K,V>数据
FileInputFormat常见接口 | 是否自定义 | 应用场景 | 机制 | 读取文件方式 |
---|---|---|---|---|
TextInputFormat | 否,框架默认 | 默认 | split切片 == block块大小. | 行读取数据 |
CombineTextInputFormat | 否,设置调用 | block中保存的为小文件,且过多的场景 | 文件1>A值 就平分为多个B值文件,B=多个虚拟存储文件,B1+B2>=A值 就生成一个Split,否则再+B3直至>=A值. | A=setMaxInputSplitSize值大小,决定切片数量 |
KeyValueTextInputFormat | 否,设置调用 | 文件按行记录着单独的K,V值 | 类似Spark中的函数map(),使用. | 行读取 K,V数据. |
NLineInputFormat | 否,设置调用 | 不常用 | 不在按照Block块去划分Split,而是按照指定的行数去划分Split. | 指定的行数划分为一个Split. |
自定义InputFormat | 是, | 具体情况分析 | 没有现成的API可以使用 | 自定义 |
Drive端负责Split的划分以及FileInputFormat的接口,Map.calss()负责split 数据的;逻辑处理,Reduce.calss()负责mapTask数据的聚合逻辑处理.
3. shufflue机制
Map方法之后,Reduce方法之前的数据处理过程
详细清楚其过程,优化则为面试点.
.
以下几个小点 说一下:
partition分区: 默认的HashPartition, key的hashCode对ReduceTasks取模,将相同的key的数据放在一个partition中,容易数据倾斜!
WritableComparable排序: { 全排序、区内排序 },框架内排序是强制性执行的,所以只要再Map.class()中将数据放进对象即可. 区内排序则是在自定义的分区内,排序.
Combiner合并: 在Mapper端汇总!
==GroupingComparator:==使用场景 就是用户Id 分组,分析组内数据逻辑处理。使用起来比Hive和spark中复杂.
MapTask 工作机制:
- Read阶段:MapTask通过用户编写的RecordReader,从输入InputSplit中解析出一个个key/value。
- Map阶段:该节点主要是将解析出的key/value交给用户编写map()函数处理,并产生一系列新的key/value
- Collect收集阶段:在用户编写map()函数中,当数据处理完成后,一般会调用OutputCollector.collect()输出结果
- Spill阶段:即“溢写”,当环形缓冲区满后,MapReduce会将数据写到本地磁盘上,生成一个临时文件
- Combine阶段:当所有数据处理完成后,MapTask对所有临时文件进行一次合并,以确保最终只会生成一个数据文件
ReduceTask工作机制:
- Copy阶段:ReduceTask从各个MapTask上远程拷贝一片数据,超过阈值落磁盘.
- Merge阶段:在远程拷贝数据的同时,ReduceTask启动了两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多
- Sort阶段:按照MapReduce语义,用户编写reduce()函数输入数据是按key进行聚集的一组数据
- Reduce阶段:reduce()函数将计算结果写到HDFS上
- ReduceTask的任务数是可以手动设置的:
job.setNumReduceTasks(4); --这里设置4个ReduceTask任务数。
OutputFormat接口实现类: 这个比较简单.
- TextOutputForamt.class() 文本输入类
- SequenceFileOutputFormat.class() 将当前输出作为新的MapReduce任务的输入
- 自定义OutputFormat。class() 自己定义输出的格式.
Map端Join 与 Reduce端Jion 总的来说,Map端 API 写法简单。假设现在有A、B 两个文本 做Join关联。
- ReduceJoin:map.class() A、B之间 Join 字段为Key, 设置 classC包含A、B中的数据, classC为value; Map端处理好文本数据形成(K,V),Reduce端收到后根据value的不同,copy到自己的classNewbean中,然后再将数据合并,输出需要的格式数据.
- MapJoin: 可以节省Reduce端的任务,直接停止;在Mapper的setup阶段,将文件读取到缓存集合中 Map端直接读取+split+拼接, 其中的代码细节逻辑自己还是没有看懂,流程OK!
4. 数据清洗(ETL)
简单的ETL 就是在map端,处理掉不合理的数据行,复杂点就是 去除每行字段中的不合法数据.
以上 MapReduce的开发小结 结束》
5. 数据压缩
个人感觉没什么讲的,因为后面的 HBase 中就有极致压缩的数据压缩. 简单说一下几种:
压缩格式 | hadoop自带? | 算法 | 文件扩展名 | 是否可切分 | 换成压缩格式后,原来的程序是否需要修改 |
---|---|---|---|---|---|
DEFLATE | 是,直接使用 | DEFLATE | .deflate | 否 | 和文本处理一样,不需要修改 |
Gzip | 是,直接使用 | DEFLATE | .gz | 否 | 和文本处理一样,不需要修改 |
bzip2 | 是,直接使用 | bzip2 | .bz2 | 是 | 和文本处理一样,不需要修改 |
LZO | 否,需要安装 | LZO | .lzo | 是 | 需要建索引,还需要指定输入格式 |
Snappy | 否,需要安装 | Snappy | .snappy | 否 | 和文本处理一样,不需要修改 |
简单的使用:就是在Map端做Job结束后,数据发送前调用数据压缩,减少I/O次数;Reduce端接受 先做数据解压。再做数据处理。