源码分析Ambari的DAG是如何做的

我认为Ambari最有趣的地方之一是如何计算DAG(Directed acyclic graph,有向无环图)

简述

先简要概括一下Ambari是如何确定执行流程的:

ambari server会根据集群的元数据信息,在执行某一个Operation时候建立一个Stage DAG,根据这个DAG,划分不同的Stage,Stage间有执行顺序关系,必须按着顺序来;再根据每一个Stage,生成Command的DAG,将Command下发给ambari agent执行,第一个Stage的所有Command全部执行成功,才会执行第二个Stage,依次类推。


相关的类

当然,有很多细节需要补充,我们先认识几个类,按理解的重要性排序:

RoleGraphNode

第一个类:RoleGraphNode,它可以看成DAG的一个点

public class RoleGraphNode {
  public RoleGraphNode(Role role, RoleCommand command) {
    this.role = role;
    this.command = command;
  }
  private Role role;
  private RoleCommand command;
  private int inDegree = 0;
  private List<String> hosts = new ArrayList<String>();
  private Map<String, RoleGraphNode> edges = new TreeMap<String, RoleGraphNode>();
  public synchronized void addHost(String host) {
    hosts.add(host);
  }
  public synchronized void addEdge(RoleGraphNode rgn) {
    if (edges.containsKey(rgn.getRole().toString())) {
      return;
    }
    edges.put(rgn.getRole().toString(), rgn);
    rgn.incrementInDegree();
  }
  private synchronized void incrementInDegree() {
    inDegree ++;
  }
  public Role getRole() {
    return role;
  }
  public RoleCommand getCommand() {
    return command;
  }
  public List<String> getHosts() {
    return hosts;
  }
  public int getInDegree() {
    return inDegree;
  }

  Collection<RoleGraphNode> getEdges() {
    return edges.values();
  }
  public synchronized void decrementInDegree() {
    inDegree --;
  }

  @Override
  public String toString() {
    StringBuilder builder = new StringBuilder();
    builder.append("("+role+", "+command +", "+inDegree+")");
    return builder.toString();
  }
}

一个DAG的节点有两部分构成,Role和RoleCommand,

(1) Role: Role defines the components that are available to Ambari. 说白了,就是component。
(2) RoleCommand:一个枚举类,包含:INSTALL,UNINSTALL,START,STOP,EXECUTE,ABORT,UPGRADE,SERVICE_CHECK,
  /**
   * Represents any custom command
   */
  CUSTOM_COMMAND,

  /**
   * Represents any action
   */
  ACTIONEXECUTE

前面提到,Stage需要按顺序执行,那DAG如何确定顺序呢?

数据结构课都有上过,既然是一个有向无环图,那么先找到所有入度为0的nodes,这些nodes可以被划分在第一个Stage中,然后去掉这些nodes,以这些nodes为起点的边的终点的nodes的入度要-1,再找到所有入度为0的nodes,那么这些nodes可以被划分为第二个Stage,依次类推,就可以确定有多少个Stage和各个Stage的执行顺序。

在代码中是如何体现的呢?

每个RoleGraphNode都可以表示为一个(role, command, inDegree)三元组,比如(datanode, install, 0);
每个RoleGraphNode都有该节点的边的信息(Map

RoleCommandOrder

第二个类:RoleCommandOrder,它可以理解成是如何生成DAG的graph的规则:

This class is used to establish the order between two roles.

判定规则函数实现如下:

  /**
   * Returns the dependency order. -1 => rgn1 before rgn2, 0 => they can be
   * parallel 1 => rgn2 before rgn1
   * 
   * @param rgn1 roleGraphNode1
   * @param rgn2 roleGraphNode2
   */
  public int order(RoleGraphNode rgn1, RoleGraphNode rgn2) {
    RoleCommandPair rcp1 = new RoleCommandPair(rgn1.getRole(),
        rgn1.getCommand());
    RoleCommandPair rcp2 = new RoleCommandPair(rgn2.getRole(),
        rgn2.getCommand());
    if ((this.dependencies.get(rcp1) != null)
        && (this.dependencies.get(rcp1).contains(rcp2))) {
      return 1;
    } else if ((this.dependencies.get(rcp2) != null)
        && (this.dependencies.get(rcp2).contains(rcp1))) {
      return -1;
    } else if (!rgn2.getCommand().equals(rgn1.getCommand())) {
      return compareCommands(rgn1, rgn2);
    }
    return 0;
  }

给定两个node:node1和node2
1. 如果node1 -> node2,则返回-1;
2. 如果node1和node2不存在先后关系,则返回0;
3. 反之,如果node2 -> node1,则返回1;

谁先谁后是根据command的类型决定:
INSTALL -> START -> EXECUTE -> SERVICE_CHECK -> STOP

  private int compareCommands(RoleGraphNode rgn1, RoleGraphNode rgn2) {
    // TODO: add proper order comparison support for RoleCommand.ACTIONEXECUTE

    RoleCommand rc1 = rgn1.getCommand();
    RoleCommand rc2 = rgn2.getCommand();
    if (rc1.equals(rc2)) {
      //If its coming here means roles have no dependencies.
      return 0;
    }

    if (independentCommands.contains(rc1) && independentCommands.contains(rc2)) {
      return 0;
    }

    if (rc1.equals(RoleCommand.INSTALL)) {
      return -1;
    } else if (rc2.equals(RoleCommand.INSTALL)) {
      return 1;
    } else if (rc1.equals(RoleCommand.START) || rc1.equals(RoleCommand.EXECUTE)
            || rc1.equals(RoleCommand.SERVICE_CHECK)) {
      return -1;
    } else if (rc2.equals(RoleCommand.START) || rc2.equals(RoleCommand.EXECUTE)
            || rc2.equals(RoleCommand.SERVICE_CHECK)) {
      return 1;
    } else if (rc1.equals(RoleCommand.STOP)) {
      return -1;
    } else if (rc2.equals(RoleCommand.STOP)) {
      return 1;
    }
    return 0;
  }

这里要明确的是:
除了上面的规则,还有一类规则信息是config,比如有role_command_order.json这个配置文件给定的规则,这类规则通常规定了不同component之间的顺序关系,可以是一个service间的不同component,比如:

"HIVE_SERVER-START": [
  "HIVE_METADATA_DATABASE-START"
],

也可以是不同service间的不同component,比如:

"KAFKA_MANAGER-START": [
  "ZOOKEEPER_SERVER-START"
],

再比如有service的metainfo.xml这个配置文件给定的规则,规定了service间的依赖关系:

<requiredServices>
    <service>YARN</service>
    <service>HIVE</service>
    <service>HDFS</service>
</requiredServices>


RoleGraph

第三个类:RoleGraph,通过给定的nodes来划分Stage,提供了如下方法:

(1) public void build(Stage stage)
给定一个Stage,建立一个DAG

(2) public List<Stage> getStages()
给定nodes,建立Stages

(3) private synchronized void removeZeroInDegreeNode(String role)
去除入度为0的node

(4) private Stage getStageFromGraphNodes(Stage origStage,
      List<RoleGraphNode> stageGraphNodes)
给定一个Stage,和一些nodes,重建一个新的Stage

(5) public String stringifyGraph()
字符串表示DAG

这里要明确的是:有两种DAG
1. Stage间的DAG:根据nodes建立Stage DAG,即不同Stage的DAG;
2. Stage内部的DAG:根据给定Stage内部的nodes建立Task DAG,即不同Command的DAG;


调用关系

下面需要介绍调用关系,这些类是如何串起来和它们是如何被其它类调用的。
等待更新…


下一节希望可以介绍Ambari的调度…

Ambari是一个开源的集群管理工具,它提供了一个用户友好的Web界面,用于安装、配置和管理Hadoop集群。源码安装Ambari可以提供更多的灵活性和定制化选项。 要进行Ambari源码安装,需要按照以下步骤进行: 1. 准备环境:首先,需要确保服务器满足硬件和软件要求。安装和配置Java JDK、Maven、Git等必要的软件,并设置相应的环境变量。 2. 下载源码:通过Git从Ambari的官方代码仓库下载源码。运行以下命令来克隆仓库: git clone https://github.com/apache/ambari.git 3. 编译源码:在下载完源码后,使用Maven工具来编译Ambari。进入Ambari源码目录,并运行以下命令: mvn clean install package 这将会编译源码并生成部署包。 4. 部署Ambari服务器:在编译完成后,将会生成Ambari服务器的二进制文件。将生成的二进制文件部署到目标服务器上,并运行以下命令启动Ambari服务器: ambari-server start 5. 访问Web界面:一旦Ambari服务器启动成功,可以通过Web浏览器访问Ambari的管理界面。默认情况下,界面地址是http://<服务器地址>:8080。按照界面上的指示,创建管理员账号和密码,并登录到管理界面。 6. 创建和配置集群:在Ambari管理界面中,可以创建和配置集群。根据实际需求,设置集群的名称、主机、服务和组件,以及配置相关参数。 7. 启动集群:配置完成后,点击“部署”按钮来启动集群。Ambari将会根据指定的配置,在主机上安装和配置相应的Hadoop组件和服务。可以在Ambari界面中监控和管理集群的运行状态和性能。 通过上述步骤,可以完成Ambari源码安装,并使用Ambari管理和监控Hadoop集群。注意,Ambari源码安装需要一定的技术知识和经验,适用于那些希望进行更深度定制和开发的用户。如果只是普通用户,建议使用官方提供的二进制安装包来安装和配置Ambari
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值