虽然大数据越来越流行,但其学习的门槛却一直阻碍着很多的初学者,而且各个产品之间的集成和维护也显得比较困难。不管是 Hadoop V1 或者 V2 的安装,又或者 Spark/YARN 等的集成,都不是几行简单的命令,而是要关联到许多的配置。有了 Ambari,这些都不再是难题。
前言本文适合已经初步了解 Ambari 的读者。对 Ambari 的基础知识,以及 Ambari 的安装步骤还不清楚的读者,可以先阅读基础篇文章《Ambari——大数据平台的搭建利器》。
Ambari 的现状目前 Apache Ambari 的最高版本是 2.0.1,最高的 Stack 版本是 HDP 2.2。未来不久将会发布 Ambari 2.1 以及 HDP 2.3(本文也将以 Ambari 2.0.1 和 HDP 2.2 为例进行讲解)。其实在 Ambari trunk 的 code 中,我们已经可以看到 HDP 2.3 相关的代码。
图 1. Ambari Trunk 的 codeHDP 2.2 所支持的 Service 已经有 18 个之多,分别是 Falcon,Flume,Hbase,HDFS,Hive,Kafka,Kerberos,Knox,Oozie,Pig,Ranger,Slider,Spark,Sqoop,Stom,Tez,Yarn,Zookeeper。HDP 2.3 将会支持更多的 Service,例如 Accumulo。
利用 Ambari 扩展集群利用 Ambari 搭建好的集群,可以通过 Ambari 来扩展。这里的步骤其实类似于 Add Service,只是少了选择 Master 的页面。下面是详细的描述。
第一步,需要打开 Hosts 页面,然后点击左上角的 Actions,在下拉列表中选择“Add New Hosts”。
图 2. Add Host 按钮第二步,在 Add Host Wizard 需要输入新增的机器名(包含完整域名)以及 Ambari Service 机器上生成的私钥。
图 3. 选择 Agent 机器页面第三步,需要部署已安装 Service 的 Slave 模块和 Client 模块。
图 4. 选择 Slave、Client 页面第四步,选择对应的 Service 的配置。这里 Ambari 为用户已经选择了默认的配置。选择完后,便会开始安装 Ambari Agent 到新的机器,并且安装选择的模块。
当 Add Host Wizard 完成时,我们就可以从 Hosts 的页面中看到新的机器,以及安装的模块(Component)。
图 5. 成功添加 Host 后页面 Ambari 的自定义命令(Custom Command)在 Ambari 的 Stack 中,每个 Service 都会有 start、stop、status、configure 这样的命令,我们称之为生命周期的控制命令(lifecycle command)。Service 的每个模块(Component)都必须实现这几个命令的逻辑。为了让用户可以更好地控制每个 Service 以及每个模块,Ambari 支持了自定义命令(Custom Command)。不过目前只能支持到模块级别(Component Level),Service Level 的还不支持。
具体的自定义命令配置在每个 Service 的 metainfo.xml 中。不过不同的模块类型,呈现在 GUI 的方式是有差异的。当给一个 Service 的 Master 模块增加一个自定义命令时,该命令会显示在该 Service 的 Service Action List。如果点击这个命令,Ambari Server 就会通知 Master 所在机器的 Agent,Agent 就会执行该自定义命令的逻辑。当增加一个自定义命令给 Slave 或 Client 类型的 Component(模块),该命令则会呈现在机器的 Component 页面。在哪个机器的 Component 页面点击该命令,Ambari Server 就会通知该机器 Agent 调用这个自定义的命令接口。
Master Component 的自定义命令这里我以 YARN 为例,给 Resource Manger 模块(Master)增加一个自定义命令。首先假设一个需求,例如,要在 YARN 的 Service Action 里面加一个命令来检查 Resource Manger 所在机器的内存空间还有多大。
第一步,需要找到 Yarn 的 metainfo.xml,并在 Resource Manager 的 Component 配置中增加一个自定义命令。Component 段的示例代码如下(metainfo.xml),其中 GetMem 这个命令就是我们新增的自定义命令。
<component> <name>RESOURCEMANAGER</name> <displayName>ResourceManager</displayName> <category>MASTER</category> <cardinality>1</cardinality> <versionAdvertised>true</versionAdvertised> <commandScript> <script>scripts/resourcemanager.py</script> <scriptType>PYTHON</scriptType> <timeout>1200</timeout> </commandScript> <customCommands> <customCommand> <name>DECOMMISSION</name> <commandScript> <script>scripts/resourcemanager.py</script> <scriptType>PYTHON</scriptType> <timeout>600</timeout> </commandScript> </customCommand> <customCommand> <name>REFRESHQUEUES</name> <commandScript> <script>scripts/resourcemanager.py</script> <scriptType>PYTHON</scriptType> <timeout>600</timeout> </commandScript> </customCommand> <!--新增部分 --> <customCommand> <name>GetMem</name> <commandScript> <script>scripts/resourcemanager.py</script> <scriptType>PYTHON</scriptType> <timeout>600</timeout> </commandScript> </customCommand> </customCommands> <configuration-dependencies> <config-type>capacity-scheduler</config-type> </configuration-dependencies> </component>
第二步,实现自定义命令的逻辑。这里 CustomComand 的 xml 段已经指定了具体的脚本(resourcemanager.py),所以需要在这个脚本中增加该命令的接口,而且函数名必须是小写且与配置的中的 name 保持一致。接下来,我们需要先找到 Ambari Server 上的 resourcemanager.py 文件。找到之后,在 resourcemanager.py 增加如下的示例代码(python 脚本中注意代码的对齐方式,否则会出现语法错误。可以参考 resourcemanager.py 中的 decommission 函数):
def getmem(self, env): import os print 'Execute this coustom command to get mem info on this host' os.system("free")
第三步,重启 Ambari Server 以及 Resource Manger 所在机器的 Ambari Agent。这一步为了加载新的配置,并且同步我们修改的脚本到 Agent 机器。因为在每个 Agent 的机器上,都有一个 cache 目录,用来存放从 Server 端下载的配置及脚本。当重启 Agent 时候,Agent 便会尝试从 Server 端下载最新的配置和脚本。重启命令如下:
ambari-server restart ambari-agent restart
第四步,登录 Ambari 的 WEB GUI,并检查 Yarn 的 Service Actions。这时候我们已经可以看到这个 GetMem 的命令了。由于 CustomComand 的 xml 段不支持 DisplayName 标签,所以我们没法通过配置更改这个名字。如果需求要更改这个名字,则不得不更改 GUI 的 JS 代码。
图 6. 自定义命令 GetMem 页面第五步,如果 GetMem 可以显示,就可以点击并执行该命令了。执行结果如下图显示。
图 7. 自定义命令 GetMem 执行进度页面 Slave/Client Component 的自定义命令本质上讲,为 Slave、Client 类型的 Component 增加自定义命令,与 Master 类型是没有什么区别的。唯一的区别就是在 GUI 上呈现的位置不一样。因此这里给一个简单的示例,不再赘述具体的步骤。
这里我为 Yarn 的 NodeManager 增加了一个自定义命令“iostat”,用来查看 NodeManager 所在机器的 IO 状况。在 Yarn 的 metainfo.xml 中,为 NodeManager 新增如下的配置。
<component> <name>NODEMANAGER</name> <displayName>NodeManager</displayName> <category>SLAVE</category> <cardinality>1+</cardinality> <versionAdvertised>true</versionAdvertised> <commandScript> <script>scripts/nodemanager.py</script> <scriptType>PYTHON</scriptType> <timeout>1200</timeout> </commandScript> <!--新增部分 --> <customCommands> <customCommand> <name>iostat</name> <commandScript> <script>scripts/nodemanager.py</script> <scriptType>PYTHON</scriptType> <timeout>600</timeout> </commandScript> </customCommand> </customCommands> </component>
在 nodemanager.py 中增加如下的示例代码
nodemanager.py 中新增代码段 def iostat(self, env): import os os.system("iostat")
配置完成后,重启 Ambari Server 以及 NodeManager 所在的 Agent 的机器。当重新登录 Ambari GUI 的时候,就可以在 NodeManger 所在机器的 Component 页面看到这个命令。如下图:
图 8. Component 页面到这里,我们就成功的为 YARN 的 Master 和 Slave 模块分别增加了一个自定义命令。现实的生产环境中,可以通过自定义命令扩展 Ambari 现在的控制功能,可以让 Ambari 更好的与 Hadoop 等软件切合。如果需要更深入应用自定义命令,以及增强 GUI 上面的显示功能,则可能需要向社区贡献 patch。这样可以更好的提升用户体验等。