文章来源:http://www.cnblogs.com/ggjucheng/archive/2012/07/25/2608817.html
其他参考文章:
Hadoop1.2.1容量调度器的配置:http://www.tuicool.com/articles/RjARNn
内容简介:如何进行资源的合理管理和分配,就成了一个急待解决的需求,由此就产生了后来的二个非常优秀的调度器分别是Yahoo!开源的CapacityScheduler(容量调度器)和Facebook开源的FairScheduler(公平调度器),在Hadoop2.x中,基于YARN平台的资源调度又对这三种调度器进行了整合,封装和重写,由此来统一YARN平台的资源调度和分配,大大简化了管理员对资源调度的操作和控制。
公司里有两个部门,一个叫hive,一个叫pig,这两个部门都需要使用公司里的hadoop集群。于是问题来了,因为hadoop默认是FIFO调度的,谁先提交任务,谁先被处理,于是hive部门很担心pig这个部门提交一个耗时的任务,影响了hive的业务,hive希望可以和pig在高峰期时,平均使用整个集群的计算容量,互不影响。
hadoop的默认调度器是FIFO,但是也有计算容量调度器,这个调度器可以解决上述问题。可以在hadoop里配置三个队列,一个是default,一个是hive,一个是pig。他们的计算容量分别是30%,40%,30%.这样hive和pig这两个部门,分为使用hive和pig两个队列,其中default作为其他部门或者临时使用。但是,如果hive部门和pig部门又希望,在平常时,没有人用集群的时候,hive或者部门可以使用100%的计算容量。
修改hadoop的配置文件mapred-site.xml:
<property> <name>mapred.jobtracker.taskScheduler</name> <value>org.apache.hadoop.mapred.CapacityTaskScheduler</value> </property> <property> <name>mapred.queue.names</name> <value>default,hive,pig</value> </property>
在capacity-scheduler.xml文件中填写如下内容:
<property> <name>mapred.capacity-scheduler.queue.hive.capacity</name> <value>40</value> <description>Percentage of the number of slots in the cluster that are to be available for jobs in this queue. </description> </property> <property> <name>mapred.capacity-scheduler.queue.hive.maximum-capacity</name> <value>-1</value> <description> </description> </property> <property> <name>mapred.capacity-scheduler.queue.hive.supports-priority</name> <value>true</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.hive.minimum-user-limit-percent</name> <value>100</value> <description> </description> </property> <property> <name>mapred.capacity-scheduler.queue.hive.user-limit-factor</name> <value>3</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.hive.maximum-initialized-active-tasks</name> <value>200000</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.hive.maximum-initialized-active-tasks-per-user</name> <value>100000</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.hive.init-accept-jobs-factor</name> <value>10</value> <description></description> </property> <!-- pig --> <property> <name>mapred.capacity-scheduler.queue.pig.capacity</name> <value>30</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.pig.maximum-capacity</name> <value>-1</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.pig.supports-priority</name> <value>true</value> <description>If true, priorities of jobs will be taken into account in scheduling decisions. </description> </property> <property> <name>mapred.capacity-scheduler.queue.pig.minimum-user-limit-percent</name> <value>100</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.pig.user-limit-factor</name> <value>4</value> <description>The multiple of the queue capacity which can be configured to allow a single user to acquire more slots. </description> </property> <property> <name>mapred.capacity-scheduler.queue.pig.maximum-initialized-active-tasks</name> <value>200000</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.pig.maximum-initialized-active-tasks-per-user</name> <value>100000</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.pig.init-accept-jobs-factor</name> <value>10</value> <description></description> </property> <!-- default --> <property> <name>mapred.capacity-scheduler.queue.default.capacity</name> <value>30</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.default.maximum-capacity</name> <value>-1</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.default.supports-priority</name> <value>true</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.default.minimum-user-limit-percent</name> <value>100</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.default.user-limit-factor</name> <value>4</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.default.maximum-initialized-active-tasks</name> <value>200000</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.default.maximum-initialized-active-tasks-per-user</name> <value>100000</value> <description></description> </property> <property> <name>mapred.capacity-scheduler.queue.default.init-accept-jobs-factor</name> <value>10</value> <description></description> </property>
这里配置了三个队列,分别是hive,pig,default,hive的容量是40%,由属性mapred.capacity-scheduler.queue.hive.capacity决定,其他队列的容量同理可得。
需要配置hive,pig,default可以抢占整个集群的资源,由属性mapred.capacity-scheduler.queue.hive.user-limit-factor绝对,hive队列这个值是3,所以用户可以使用的资源限量是40% * 3 =120%,所有有效计算容量是集群的100%.其他队列的最大集群计算容量同理可得。
mapreduce:在Job的代码中,设置Job属于的队列,例如hive:
conf.setQueueName("hive");
hive:在执行hive任务时,设置hive属于的队列,例如pig:
set mapred.job.queue.name=pig;
生产环境中,队列及其容量的修改在现实中是不可避免的,而每次修改,需要重启集群,这个代价很高,如果修改队列及其容量的配置不重启呢:
1.在主节点上根据具体需求,修改好mapred-site.xml和capacity-scheduler.xml
2.把配置同步到所有节点上
3.使用hadoop用户执行命令:hadoop mradmin -refreshQueues
这样就可以动态修改集群的队列及其容量配置,不需要重启了,刷新mapreduce的web管理控制台可以看到结果。
注意:如果配置没有同步到所有的节点,一些队列会无法启用。
==============================================================================================================================
资源调度器是Hadoop集群中一个比较重要的模块,最初的hadoop资源调度器是基于队列形式的FIFO调度的,这种模式在大规模集群的时候,资源分配并不是很合理,比如一个后提交的任务,但想要它先执行怎么办,而在FIFO模式下,只能等到前面所有的JOB执行完后,才能执行这个作业。所以如何进行资源的合理管理和分配,就成了一个急待解决的需求,由此就产生了后来的二个非常优秀的调度器分别是Yahoo!开源的CapacityScheduler(容量调度器)和Facebook开源的FairScheduler(公平调度器),在Hadoop2.x中,基于YARN平台的资源调度又对这三种调度器进行了整合,封装和重写,由此来统一YARN平台的资源调度和分配,大大简化了管理员对资源调度的操作和控制。
下面给出一个资料图看下这三个调度器之间的异同点
对比选项 | FifoScheduler | CapacityScheduler | FairScheduler |
设计目的 | 最简单的调度器,易于理解和上手 | 多用户的情况下,最大化集群的吞吐和利用率 | 多用户的情况下,强调用户公平地贡献资源 |
队列组织方式 | 单队列 | 树状组织队列。无论父队列还是子队列都会有资源参数限制,子队列的资源限制计算是基于父队列的。应用提交到叶子队列。 | 树状组织队列。但是父队列和子队列没有参数继承关系。父队列的资源限制对子队列没有影响。应用提交到叶子队列。 |
资源限制 | 无 | 父子队列之间有容量关系。每个队列限制了资源使用量,全局最大资源使用量,最大活跃应用数量等。 | 每个叶子队列有最小共享量,最大资源量和最大活跃应用数量。用户有最大活跃应用数量的全局配置。 |
队列ACL限制 | 可以限制应用提交权限 | 可以限制应用提交权限和队列开关权限,父子队列间的ACL会继承。 | 可以限制应用提交权限,父子队列间的ACL会继承。但是由于支持客户端动态创建队列,需要限制默认队列的应用数量。目前,还看不到关闭动态创建队列的选项。 |
队列排序算法 | 无 | 按照队列的资源使用量最小的优先 | 根据公平排序算法排序 |
应用选择算法 | 先进先出 | 先进先出 | 先进先出或者公平排序算法 |
本地优先分配 | 支持 | 支持 | 支持 |
延迟调度 | 不支持 | 不支持 | 支持 |
资源抢占 | 不支持 | 不支持 | 支持 |
。。。。。。省略详情看http://www.tuicool.com/articles/RjARNn
至此,容量调度器已经成功配置,在使用的时候,就可以根据作业的优先级对应提交到不用的队列上来合理的获取系统资源。
最后,散仙在总结一下,配置过程中遇到的一个问题。散仙原来的集群使用的是hadoop默认的tmp的路径,结果在集群启动时,有时会出现datanode无法启动的BUG,查看log日志,报了如下的异常信息:
2013-10-31 04:19:02,035 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /default-rack/Slave2 2013-10-31 04:19:02,038 INFO org.apache.hadoop.mapred.JobTracker: Adding tracker tracker_Slave2:localhost/127.0.0.1:56885 to host Slave2 2013-10-31 04:19:02,477 INFO org.apache.hadoop.net.NetworkTopology: Adding a new node: /default-rack/Slave 2013-10-31 04:19:02,478 INFO org.apache.hadoop.mapred.JobTracker: Adding tracker tracker_Slave:localhost/127.0.0.1:51876 to host Slave 2013-10-31 04:19:02,931 WARN org.apache.hadoop.mapred.JobTracker: Retrying... 2013-10-31 04:19:02,959 WARN org.apache.hadoop.hdfs.DFSClient: DataStreamer Exception: org.apache.hadoop.ipc.RemoteException: java.io.IOException: File /root/hadoop-1.2.0/tmp/mapred/system/jobtracker.info could only be replicated to 0 nodes, instead of 1 at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.getAdditionalBlock(FSNamesystem.java:1920) at org.apache.hadoop.hdfs.server.namenode.NameNode.addBlock(NameNode.java:783) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.hadoop.ipc.RPC$Server.call(RPC.java:587) at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1432) at org.apache.hadoop.ipc.Server$Handler$1.run(Server.java:1428) at java.security.AccessController.doPrivileged(Native Method) at javax.security.auth.Subject.doAs(Subject.java:396) at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1190) at org.apache.hadoop.ipc.Server$Handler.run(Server.java:1426) at org.apache.hadoop.ipc.Client.call(Client.java:1107) at org.apache.hadoop.ipc.RPC$Invoker.invoke(RPC.java:229) at com.sun.proxy.$Proxy7.addBlock(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.hadoop.io.retry.RetryInvocationHandler.invokeMethod(RetryInvocationHandler.java:85) at org.apache.hadoop.io.retry.RetryInvocationHandler.invoke(RetryInvocationHandler.java:62) at com.sun.proxy.$Proxy7.addBlock(Unknown Source) at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.locateFollowingBlock(DFSClient.java:3720) at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.nextBlockOutputStream(DFSClient.java:3580) at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream.access$2600(DFSClient.java:2783) at org.apache.hadoop.hdfs.DFSClient$DFSOutputStream$DataStreamer.run(DFSClient.java:3023) 2013-10-31 04:19:02,960 WARN org.apache.hadoop.hdfs.DFSClient: Error Recovery for null bad datanode[0] nodes == null 2013-10-31 04:19:02,960 WARN org.apache.hadoop.hdfs.DFSClient: Could not get block locations. Source file "/root/hadoop-1.2.0/tmp/mapred/system/jobtracker.info" - Aborting... 2013-10-31 04:19:02,960 WARN org.apache.hadoop.mapred.JobTracker: Writing to file hdfs://10.2.143.5:9090/root/hadoop-1.2.0/tmp/mapred/system/jobtracker.info failed! 2013-10-31 04:19:02,961 WARN org.apache.hadoop.mapred.JobTracker: FileSystem is not ready yet! 2013-10-31 04:19:02,965 WARN org.apache.hadoop.mapred.JobTracker: Failed to initialize recovery manager.
2013-10-31 04:19:02,959 WARN org.apache.hadoop.hdfs.DFSClient: DataStreamer Exception: org.apache.hadoop.ipc.RemoteException: java.io.IOException: File /root/hadoop-1.2.0/tmp/mapred/system/jobtracker.info could only be replicated to 0 nodes, instead of 1