Hadoop调度器及其工作方法
问题分析
考官主要是考察面试者对于Hadoop个组件的了解程度;增分点:并考察能否结合组件的熟悉程度与具体需求做平衡,做出一个好的技术选型。
核心问题讲解
比较流行的三种调度器有:默认调度器FIFO,计算能力调度器Capacity Scheduler,公平调度器Fair Scheduler。
- 默认调度器FIFO:Hadoop中默认的调度器,采用先进先出的原则。
- 计算能力调度器Capacity Scheduler:选择占用资源小,优先级高的先执行。
- 公平调度器Fair Scheduler:同一队列中的作业公平共享队列中所有资源。
问题扩展
资源隔离问题
YARN对内存资源和CPU资源采用了不同的资源隔离方案。对于内存资源,它是一种限制性资源,它的量的大小直接决定应用程序的死活,因为应用程序到达内存限制,会发生OOM,就会被杀死。CPU资源一般用Cgroups进行资源控制,Cgroups控制资源测试可以参见这篇博文Cgroups控制cpu,内存,io示例,内存资源隔离除Cgroups之外提供了另外一个更灵活的方案,就是线程监控方案。
默认情况下YARN采用线程监控的方案控制内存使用,采用这种机制的原因有两点:
(1)Java创建子进程采用了“fork()+exec()”的方案,子进程启动的瞬间,它使用的内存量和父进程一致。一个进程使用的内存量可能瞬间翻倍,然后又降下来,采用线程监控的方法可防止这种情况下导致的swap操作。
(2)通常情况下,Hadoop任务运行在独立的Java虚拟机中,可以达到资源隔离的目的。Hadoop Streaming是Hadoop提供的一个编程工具,它允许用户使用任何可执行文件或者脚本文件作为Mapper和Reducer,通过Hadoop Streaming编写的MapReduce应用程序中每个任务可以由不同的编程语言环境组成,这难以通过创建单独的虚拟机达到资源隔离的效果。
综上,为了获取更加灵活的资源控制效果,Hadoop对内存的资源隔离采用线程监控方案。解决方案具体如下:
- linux系统的/proc/<pid>/stat文件,实时的反应进程树使用的内存总量,可以基于此判断任务粒度的内存使用量是否超过设定的最大值。getconf PAGESIZE可以获取page大小。
- 为了避免JVM的“fork()+exec()”模型引发的误杀操作,Hadoop赋予每个进程”年龄”属性,并规定刚启动进程的年龄是1,监控线程每更新一次,各个进程年龄加1,在此基础上,选择被杀死进程组的标准如下:如果一个进程组中所有的进程(年龄大于0)总内存超过用户设置的最大值的两倍,或者所有年龄大于1的进程总内存量超过用户设置最大值,则认为该进程组过量使用内存,就将其kill掉。这种细粒度,更加灵活的线程监控资源隔离方案,还是值得学习与称道的,记录于此,以后设计系统可以参考。
结合项目中使用
开发环境下调度器考虑的因素
(1)作业优先级。作业的优先级越高,它能够获取的资源(slot数目)也越多。Hadoop 提供了5种作业优先级,分别为 VERY_HIGH、HIGH、NORMAL、 LOW、VERY_LOW,通过mapreduce.job.priority属性来设置。
(2)作业提交时间。顾名思义,作业提交的时间越早,就越先执行。
(3)作业所在队列的资源限制。调度器可以分为多个队列,不同的产品线放到不同的队列里运行。不同的队列可以设置一个边缘限制,这样不同的队列有自己独立的资源,不会出现抢占和滥用资源的情况