shuffle流程
- 输入分片(input split):在进行map计算之前,mapreduce会根据输入文件计算输入分片(input split),每个输入分片(input split)针对一个map任务,输入分片(input split)存储的并非数据本身
- map阶段:就是程序员编写好的map函数了,因此map函数效率相对好控制,而且一般map操作都是本地化操作也就是在数据存储节点上进行;
- combiner阶段:combiner阶段是程序员可以选择的,combiner其实也是一种reduce操作。例如:如果计算只是求总数,最大值,最小值可以使用combiner,但是做平均值计算使用combiner的话,最终的reduce计算结果就会出错。
- shuffle阶段:将map的输出作为reduce的输入的过程就是shuffle了,这个是mapreduce优化的重点地方。
- map在做输出时候会在内存里开启一个环形内存缓冲区,默认大小是100mb
- map启动一个守护线程,如果缓冲区的内存达到了阀值的80%(默认)时候,这个守护线程就会把内容写到磁盘上,这个过程叫spill,另外的20%内存可以继续写入要写进磁盘的数据,写入磁盘和写入内存操作是互不干扰的,如果缓存区被撑满了,那么map就会阻塞写入内存的操作,让写入磁盘操作完成后再继续执行写入内存操作
- 写入磁盘前会有个排序操作,这个是在写入磁盘操作时候进行,不是在写入内存时候进行的,++如果我们定义了combiner函数,那么排序前还会执行combiner操作
- 每次spill操作就会产生一个溢出文件,等map输出全部做完后,map会合并这些输出文件。
- patitioner:一个Partitioner对应一个reduce作业,Partitioner因此就是reduce的输入分片,这个程序员可以编程控制,主要是根据实际key和value的值,根据实际业务类型或者为了更好的reduce负载均衡要求进行。到了reduce阶段就是合并map输出文件了,Partitioner会找到对应的map输出文件,然后进行多线程复制操作,复制时还会进行排序和合并文件,复制和map输出文件类似。(用户可以选择多种哦partitioner,hash或者有序)
- reduce阶段:和map函数一样也是程序员编写的,最终结果是存储在hdfs上的。
容错
任务出错
任务出错是比较常见的,引起错误的原因通常有低质量的代码、数据损坏、节点暂时性故障、一个任务出现下列三种情况的任意一种时被认为出错。
- 抛出一个没有补货的异常
- 以一个非零值退出程序
- 在一定的事件内没有向Tasktracker报告进度。
- 任务重试
- 多次在同一个taskTracker失败,把taskTracker加入黑名单
- 当一个任务经过最大尝试数的尝试运行后仍然失败,那么整个作业将被标记为失败。如果我们不希望这样(因为可能作业的溢写结果还是可用的),那么可以设置允许在不处罚整个作业失败的任务失败的最大百分比。
TaskTracker出错
当TaskTracker进程崩溃或者TaskTracker进程所在节点故障时,JobTracker将接收不到TaskTracker发来的心跳,那么JobTracker将会认为该TaskTracker失效并且在该TaskTracker运行过的任务都会被认为失败,这些将会被重新调度到别的TaskTracker执行,而对于用户来说,在执行MapReduce任务时,只会感觉到该作业在执行的一段时间里变慢了。
TaskTracker出错发生在Map阶段,因为Reduce需要所有Map阶段的数据,所以需要重新执行分配在Tasktracker上的所有任务(包括已经执行的)。
TaskTracker出错发生在Reduce阶段,因为Reduce任务都把结果输出到HDFS中,只需要重新执行未执行的Reduce任务。
JobTracker出错
在Hadoop中,JobTracker出错是非常严重的额情况,因为在Hadoop中JobTracker存在单节点故障的可能性,所以如果如果JobTracker一旦出错,那么正在运行的所有作业的内部状态信息将会丢失,即使JobTracker马上恢复了,作业的所有任务都会被认为是失败的,即所有作业都需要重新执行。
任务调度
提供3种类型的调度器
- FIFO调度器
- 容量调度器
- 公平调度器
由于有Yarn的存在,这3中调度器只关注于任务调度,如何从不同的队列中选择一个应用,好像FIFO就可以了。