跳到主要内容

容器组

对 ContainerWorker 进行分组

容器组表示一组共享相同特性(如 Yarn 资源、Java 选项、环境变量等)的 ContainerWorker。它指定了启动 ContainerWorker 并在其中运行 TaskAttempt 所需的所有详细信息。其基本思想是:每个 Vertex 与一个唯一的 ContainerGroup 关联,以便其 TaskAttempt 可以在属于该 ContainerGroup 的任何 ContainerWorker 中运行。MR3 进一步发展了这一思想,允许 ContainerGroup 在多个 Vertex 之间共享,甚至跨 DAG 共享。

在下面显示的示例中,来自两个 DAG 的三个 Vertex 属于同一个 ContainerGroup。该 ContainerGroup 有两个活动的 ContainerWorker,正在运行来自其成员 Vertex 的 TaskAttempt。需要注意的是,并非每个 Vertex 都属于同一个 ContainerGroup。

containergroup

ContainerGroup 为运行 ContainerWorker 指定了以下选项/参数:

  • ContainerWorker 模式(Local 或 Yarn)
  • CPU 核数和内存方面的资源
  • 一个布尔标志,指定是否重用 ContainerWorker。这通常设置为 true。
  • 一个布尔标志,指定是否允许多个 TaskAttempt 并发运行。如果此标志为 true,则来自不同 Vertex 甚至来自不同 DAG(当并发执行多个 DAG 时)的多个 TaskAttempt 可以在同一个 ContainerWorker 中并发运行。(相比之下,Tez 中的容器一次只能运行一个 TaskAttempt。)

通过维护 ContainerGroup,我们简化了 TaskAttempt 与 ContainerWorker 实时匹配的逻辑。DAGAppMaster 的整体架构也变得更简单。例如,每个 ContainerGroup 运行自己的 TaskAttempt 调度器和自己的 ContainerWorker 通信器。

执行单个 DAG

对于执行单个 DAG,我们保持以下不变量:

  • 每个 Vertex 与一个唯一的 ContainerGroup 关联。因此,一个 DAG 可以使用多个 ContainerGroup。
  • 同一 DAG 中的多个 Vertex 可以属于同一个 ContainerGroup。因此,一个 ContainerWorker 可以运行来自不同 Vertex 的 TaskAttempt。

每个 Vertex 都可以关联到一个公共 ContainerGroup,在这种情况下,任何 TaskAttempt 可以在任何 ContainerWorker 中运行。在另一种极端情况下,每个 Vertex 都可以拥有自己的 ContainerGroup,这样来自不同 Vertex 的 TaskAttempt 就不能在同一个 ContainerWorker 中混合。

执行多个 DAG

在在同一 DAGAppMaster 中执行多个 DAG 的上下文中,MR3 允许以下规则:

  • ContainerGroup 可以配置为跨 DAG 可见,因此不同的 DAG 可以共享一个公共 ContainerGroup。这样的 ContainerGroup 称为开放 ContainerGroup(意思是它对任何活动的 DAG 都可用)。因此,MR3 中的 ContainerWorker 可以运行来自不同 DAG 的 TaskAttempt。

ContainerGroup 的使用意味着 MR3 在长时间运行的 DAGAppMaster 中创建 ContainerWorker 的成本可以忽略不计。这是因为 ContainerWorker 可以为任何 DAG 的任何 TaskAttempt 服务,从而最大化其生存机会,直到 DAGAppMaster 本身终止。例如,如果所有 DAG 在繁忙的 DAGAppMaster 中只使用一个公共 ContainerGroup,ContainerWorker 在长时间空闲后不太可能过早终止。在并发用户环境中,这种优势尤为明显,因为 DAGAppMaster 支持执行并发 DAG。

在以下实验中,我们向一个 DAGAppMaster 连续提交了 58 个 DAG(来自 TPC-DS 基准测试)。在第一次运行中,没有 DAG 共享相同的 ContainerGroup,因此在 DAG 的生命周期内没有 ContainerWorker 被重用,导致分配了 9695 个 ContainerWorker。

containergroupexp1

在第二次运行中,所有 DAG 共享一个 ContainerGroup,因此在 DAGAppMaster 的生命周期内只分配了 202 个 ContainerWorker。总执行时间也从 6634 秒减少到 4597 秒。执行时间的减少归因于省去了创建 ContainerWorker 的成本。

containergroupexp2