目录
一:MapReduce模型简介
- MapReduce将复杂的,运行于大规模集群上的并行过程高度抽象到两个函数:Map和Reduce.
- 采用分而治之的策略,一个存储在分布式文件系统中的大规模数据集,会被切分成独立的分片(split),这些分片可以被多个Map任务并行处理。
- MapReduce设计的一个理念:数据向计算靠拢。
二:Map函数和Reduce函数
三:MapReduce的体系结构
client
- 用户编写的MapReduce程序通过client提交到JobTracker端。
- 用户可以通过client提供的一些接口查看作业运行状态。
JobTracker
- 负责资源监控和作业调度
TaskTracker
- TaskTracker会周期型地通过心跳“将本节点上资源的使用情况和任务的运行进度汇报
- 给JobTracker,同时接收JobTracker发生过来的命令并执行相应的操作。
Task
- Task分为Map Task和Reduce Task,均由TaskTracker启动。
四:MapReduce执行流程
- MapReduce框架使用InputFormat模块做map前的数据预处理,比如验证输入的格式是否符合输入定义;然后,将输入文件切分为逻辑上的多个InPutSplit.InputSplit是MapReduce对文件进行处理和运算的基本单位,只是一个逻辑概念,它只包含一些元数据信息,比如数据起始位置,数据长度,数据所在节点等。
- 因为InputSplit是逻辑切分而非物理划分,所以还需要通过RecordReader(RR)根据InputSplit中的信息来处理InputSplit中的具体记录,加载数据并将其转换为适合Map任务读取的键值对,输入给Map任务。
- Map任务会根据用户自定义的映射规则,输出一系列的<key , value>作为中间结果。
- 为了让Reduce可以并行处理Map的结果,需要对Map的输出进行一定的分区(Partition),排序(Sort),合并(Combine),归并(Merge)等操作。得到<key, value-list>形式的中间结果,再交给对应的Reduce来处理。从无序的<key, value>到有序的<key , value-list>这个过程称为shuffle。
- Reduce以一系列<key, value-list>中间结果作为输入,执行用户定义的逻辑,输出结果交给OutputFormat模块。
- OutputFormat模块会验证输出目录是否已经 存在,以及输出结果类型是否符合配置文件中的类型,如果都满足,就输出Reduce中的结果到分布式文件系统,
五:Shuffle过程,为什么需要shuffle
5.1为什么需要shuffle
为了让reduce可以并行处理Map的结果。也就是说需要把map产生的无序的<key , value>转换成有序的<key, value-list>.
5.2 shuffle过程简洁版
Shuffle是指对Map任务输出结果进行分区,排序,合并,归并等处理并交给Reduce的过程。因此Shuffle过程分为map端的操作和reduce端的操作。
map端的shuffle过程:
Map端的输出结果首先被写入缓存,当缓存满时,就启动溢写操作,把缓存中的数据写入磁盘文件,并清空缓存。当启动溢写操作时候,首先需要对缓存中的数据进行分区,然后对每个分区的数据进行排序和合并,再写入磁盘文件。每次溢写操作会生成一个新的磁盘文件。伴随着map任务的执行,磁盘中就会有多个溢写文件。在map任务全部结束之前,这些溢写文件会被归并到一个大的磁盘文件,然后通知相应的reduce来领取。
reduce端的shuffle过程:
Reduce任务从map端的不同map机器领取属于自己处理的那部分数据,然后对数据进行归并后交给reduce处理。
【注意】:(个人理解)
map端的归并是指对一个map任务的溢写的磁盘文件进行归并。
map端归并的文件不是全局有序的。
map端归并实在map端机器上。
reduce端的归并是指对多个map任务进行归并。
reduce端归并的文件是全局有序的。
reduce端归并是在reduce机器上。
5.3 shuffle详细版
5.3.1 map端的shuffle过程
- 输入数据和执行map任务。
- 写入缓存。每个map任务都会被分配一定的缓存,map任务的输出结果不是立即写入磁盘,而是首先写入缓存。在缓存中积累一定数量的map任务输出结果以后,再一次性批量写入缓存,这样可以大大减少对磁盘I/O的影响。
- 溢写(分区,排序,合并)。分区:在溢写磁盘前,缓存中的数据首先会被分区。排序:对于每个分区内的所有键值对,后天线程会根据key对他们进行内存排序,排序是MapReduce的默认操作。排序之后可以有用户自定义的combiner操作,这是可选的。合并:指将哪些具有相同的key的<key,value>的value加起来。
- 归并:每次溢写操作都会生成一个溢写操作,随着mapReduce任务进行,磁盘中溢写文件越来越多,在map任务执行之前,系统会对所有溢写文件中的数据进行归并。
5.3.2 Reduce端的shuffle过程
- 领取数据。map端shuffle过程结束后,所有map任务输出结果都保存在map机器本地磁盘上,Reduce任务需要把这些数据领取回来,存放到自己所在机器的本地磁盘上。
- 归并数据。从map端领取的数据会被存放在reduce任务所在机器的缓存中,如果缓存占满,就会像map端一样溢写到磁盘中。当溢写过程启动的时候,具有相同key的键值对会被归并。最终,当所有map端数据都被领取时,和map端一样,多个溢写文件会被归并为一个大文件,归并的时候还会对键值对进行排序,从而使最终大文件中的键值对都是有序的。
- 把数据输入给reduce任务。
六:如何设定Map和Reduce个数
重点问题
6.1 如何设置map数量
6.2 如何设置reduce数量
七:Hadoop序列化和反序列化
序列化:把内存中的对象,转化为字节序列(或者其他数据传输协议)以便于存储到磁盘(持久化)和网络传输
反序列化:将收到的字节序列(或者是其他数据传输协议)或者是磁盘的持久化数据,转换成内存中的对象。
为什么要序列化:‘活的’对象只生存在内存中,关机断电就没有了,并且只能由本地的进程使用。
八:Combiner合并
- Combiner是MR程序中Mapper和Reducer之外的一种组件
- Combiner组件的父类就是Reducer
- 一般而言,累加,最大值等场景可以使用合并操作。
- Combiner和Reducer的区别在于运行的位置:Combiner是在每一个MapTask所在节点运行;Reducer是接收全局所有的Mapper的输出结果。
- Combiner的意义就是对每一个MapTask的输出进行局部汇总,以减少网络传输量。
- Combiner能够应用的前提是不能影响最终的业务逻辑,而且Combiner的输出kv应该跟Reducer的输入kv类型要对应起来。
总结:Combiner 合并可以提高程序执行效率,减少 IO 传输。但是使用时必须不能影响原有的 业务处理结果。
九:Hadoop数据压缩
9.1 数据压缩优缺点
优点:减少磁盘I/O,减少磁盘存储空间
缺点:增加CPU开销。
9.2 压缩原则
- 运算密集型的Job,少用压缩
- I/O密集型的Job,多用压缩
9.3 MapReduce支持的压缩编码
【注意1】:LZO可以进行切片,需要建立索引,还需要指定输入格式
Snappy不支持切片,和文本处理一样,不需要修改。
9.4 切片
【注意2】:此处的切片指的是:
由于是分布式计算,所以需要支持对压缩数据进行分片,也就是hadoop的InputSplit,这样才能分配给多台机器并行处理。总结起来就是:hadoop在读入一个大文件的时候,会为每个文件维护一个索引文件,之后将文件按照一分一分的读入缓存,每当缓存读满,就将这一份进行lzo压缩,并在索引文件中维护相关的信息。
十:WordCount执行过程实例
1图解执行过程
2)java代码实例