whitelilis / whitelilis.github.io

5 stars 0 forks source link

resource manager 的一个 bug 的临时修复 #18

Open whitelilis opened 6 years ago

whitelilis commented 6 years ago

偶尔会发现,hadoop 集群中有内存资源,也有 pending 的作业,但是资源就是不分配。细看一下,有些节点的内存根本就没使用。 研究了一下正常节点的作业分配代码,nodemanager 心跳的处理是在 FairScheduler.java 的 nodeUpdate 函数中处理的。然后就看到了下面这段傻傻的代码 image 对于一个新加进来的节点,没有完成的 task,就不分配了。

https://issues.apache.org/jira/browse/YARN-6486 已经建议把这个功能废弃了,但是对于正在运行的 resource manager 怎么办呢?关掉参数,重启当然最简单,可是业务同学不会同意的,所以就有了下面的 byteman 代码:

RULE change empty
CLASS org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler
METHOD nodeUpdate
AT READ continuousSchedulingEnabled
BIND
   cur = $0.continuousSchedulingEnabled;
   host:org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeImpl = $1;
   nm:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSSchedulerNode = $node;
   aimH:String = "228.slave.adh";
IF host.hostName.equals(aimH)
DO
   traceln(aimH + " -> " + cur);
   $0.attemptScheduling(nm);
ENDRULE

把异常的机器搞一下,就好了

whitelilis commented 6 years ago

但是这样只能保证每个有问题的节点有部分资源可用。 所以还是这样来搞:如果没有调用 attemptScheduling,就调用一次,最终代码如下:

RULE judge init
CLASS org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler
METHOD nodeUpdate
AT ENTRY
BIND
   cur = $0.continuousSchedulingEnabled;
   host:org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeImpl = $1;
IF TRUE
DO
   createCounter(host);
ENDRULE

RULE judge invoke
CLASS org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler
METHOD nodeUpdate
AT INVOKE attemptScheduling
BIND
   cur = $0.continuousSchedulingEnabled;
   host:org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeImpl = $1;
IF TRUE
DO
   incrementCounter(host);
ENDRULE

RULE judge sum
CLASS org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FairScheduler
METHOD nodeUpdate
AT EXIT
BIND
   cur = $0.continuousSchedulingEnabled;
   host:org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNodeImpl = $1;
   nm:org.apache.hadoop.yarn.server.resourcemanager.scheduler.fair.FSSchedulerNode = $node;
   callCnt = readCounter(host);
IF callCnt == 0
DO
   traceln("calll" +  host.hostName + " -> " + readCounter(host));
   deleteCounter(host);
   $0.attemptScheduling(nm);
ENDRULE