能否在紧密循环中请求不同资源能力的 YARN 容器?

Can request YARN containers of different resource capabilities in a tight loop?

我正在按照分布式 shell 应用程序的模型编写本机 YARN 应用程序。在我的 application master 中,我使用通常的循环请求两个容器,如下所示:

for (int i = 0; i < appContainerList.size(); ++i)
{
  ContainerRequest containerAsk = setupContainerAskForRM(i);
  amRMClient.addContainerRequest(containerAsk);
  appContainerList.setStatus(i, "requested");      
}

只要两个容器请求相同数量的内存,比如 512 或 1000,那么在这个循环运行后不久,我会收到一个回调到我的 AMRMClientAsync.CallbackHandler 的 onContainersAllocated 方法,其中包含两个已分配的容器。如果我要求两个以上具有相同资源分配的容器,也会发生这种情况,但我在这里将其保留为两个,以便简化问题的演示。

但是,如果我对不同的功能提出请求,比如一个用于 512,另一个用于 1000,那么我也会收到回调,但只分配了一个容器,而我再也没有收到第二个容器的回调请求。

我知道 AMRMClientAsync 和 RM 之间的通信依赖于每秒发送的心跳,所以我尝试在两个容器请求之间插入睡眠,现在我得到两个回调,每个回调都有一个分配的容器.

这是我睡觉时的代码。

for (int i = 0; i < appContainerList.size(); ++i)
{
  ContainerRequest containerAsk = setupContainerAskForRM(i);
  amRMClient.addContainerRequest(containerAsk);
  appContainerList.setStatus(i, "requested");
  try
  {
    Thread.sleep(5000);
  }
  catch (InterruptedException ex)
  {
    LOG.info("sleep interrupted " + ex);
  } 
}

对了,是不是不能在一个紧密的循环中请求不同资源能力的容器?对具有不同资源能力的容器的请求是否需要在两者之间进行休眠,这样它们就不会以相同的心跳与 RM 进行相同的通信?

如果是这样,这似乎意味着如果我有许多不同的容器类型,具有不同的资源能力,我必须将它们分组并确保对不同类型的请求之间至少有一个心跳。这比简单地在一个紧密的循环中请求容器而不考虑每个容器请求的资源能力要复杂得多。

我在这里找到了一个相关的 post:post by yihee and a JIRA here: YARN-314

我的问题的答案似乎是,正如 YARN-314 中所说: "Currently, resource requests for the same container and locality are expected to all be the same size." 因此,如果请求的资源不同,要在紧密循环中请求不同资源需求的容器,它们必须具有不同的优先级。

回答我自己的问题。基于我提到的其他参考资料,尤其是 YARN-314,我更改了我请求的容器的优先级,现在我可以在一个紧密的循环中请求容器,并且我在对我的 onContainersAllocated 回调处理程序的同一次调用中分配了两个容器。