Ambari

什么是Ambari

Ambari为Apache基金会的一个顶级项目。作为一个为Hadoop系统提供一站式维护的工具,ambari支持通过web页面/RestfulApi的方式进行对集群的一键部署,最重要的是可以自己编写部署脚本部署自己的分布式系统。这个是富有价值的,现在有的公司使用的是自研的分布式框架,想要自动部署大多也是自研一套分布式框架。现在Ambari的出现,缓解了这个问题,用户只需要使用python按照规则编写一套部署在自己系统上的安装/启动脚本,就可以将自己的系统使用Ambari进行一键式部署。
Ambari不仅提供集群组件的部署功能,还提供了集群的监控功能,不过现在的监控只支持Hadoop生态中的服务,如果想使用Ambari进行监控,可能需要二次开发,这里我没有使用Ambari进行过对自研计算框架或其他服务的监控。
我在2014年至2015年间,在百度实习时有幸接触到Ambari,并且根据Ambari的部署规则编写了一套部署自研Hadoop整套计算框架的python脚本。如今百度公有云仍采用Ambari对用户采购的机器部署计算框架。相比阿里云自研的分布式运维部署框架,个人比较倾向于Ambari框架。优点相较自研来说,问题故障少、研发运维成本低等优点是自研分布式部署框架不具备的。
本文也基于当时我接触的Ambari 1.6版本及官方文档进行说明。

Ambari 目标

解决Hadoop生态系统部署

部署

Hadoop组件间有依赖,包括host、配置、版本、启动顺序、权限配置等。

部署过程跟踪

能够展示出部署过程中每个步骤的状态及相关信息,包括报错异常等情况。

多机部署问题

当集群规模增加后,机器出问题机率增加,在部署或更新中可能会出现机器故障、部署异常等情况。比较容易理解的是Hadoop中的部分组件是可以容忍机器出故障的,例如HDFS中的DataNode,所以在多机部署的情况下,需要容忍出现个别部署失败的情况。

管控集群配置

可以将默认配置写入Ambari-stack中,Ambari-Server在启动时将Ambari-stack中各个版本的config文件读入,当使用blueprint创建集群部署hadoop时,直接根据Ambari-stack默认配置生成command-json文件。

服务状态展示、监控、报警

基于各个计算框架的Metrics做的,我对这方面没有深入研究过。

Ambari 主要概念

资源

ambari将集群及集群中的服务、组件、机器都视为资源,资源的状态都会记录在DB中。

stack

发行版本的含义,如HDP,可以有若干版本。

service

服务,属于stack,一个stack下可以有多个service,service也可以分多个版本,版本间可以有继承关系。例如zookeeper就是一项服务。

component

组件,属于service,一个service下可以有多个component组成。例如HDFS服务下的组件有datanode,namenode等。

角色

component可以指定部署时的角色,如master、slave等,也可以指定每种角色需要的host个数。例如NameNode为单一host组件,可以部署在master机器上,DataNode可以部署在多台host上那么可以指定部署DataNode的角色为slave。

host

host为运Ambari-agent的一台机器,同时也是搭建集群内部的一台机器,可以为host设置对应的角色,例如master,slave等。

Ambari stack

Ambari-stack 表示hadoop某个发行版本,例如HDP-1.0.0,在用ambari创建一个集群时,首先要通过调用restfulAPI设置stack版本。stack下包含一个或多个service,例如HDP-2.0.6下包括多个service,分别是 ZOOKEEPER,HDFS,YARN,等。
单个service下通过配置service下存储的metainfo.xml来设置构成服务的component(组件)以及部署组件的部署脚本、运行组件的角色名称、部署脚本的文件名称、部署脚本的语言种类等信息。stack下package/script/ 存放agent操作相关component(组件)的脚本,ambari-agent会根据脚本的函数名称调用脚本的对应函数。
stack版本可以通过metainfo.xml设置继承关系。例如HDP-2.1继承了HDP-2.0.6的各个服务。

stack 目录结构

创建好stack后,需要重启ambari-server。可以在浏览器中通过Rest API来查看stack创建是否成功。http://<ambari-server>:8080/api/v1/stacks 对于服务下的metainfo.xml一定要保证格式、内容的正确性,如果ambari不能正常读取,那将识别不出stack的信息。

Ambari 自动化部署执行流程

外部通过Rest API调用Ambari-Server服务

部署集群分为两种形式,一种为单步调用各个Rest API进行分部创建,还有一种使用Ambari自带的Blueprint进行创建,使用Blueprint创建的好处是调用Rest API的次数较少。

单步调用

Blueprint

调用一次restAPI即可进行集群创建、服务安装、组件部署、服务开始等集群操作,简化了单步创建的调用次数。

ambari-server向ambari-agent反馈部署指令

ambari-server端负责接收rest请求,再向agent端发送命令,发送命令的格式是json,内部包涵部署脚本执行命令(安装/开始/停止服务)所需要的配置信息,这里所指的配置信息一般是手动部署集群需要配置的xml文件,例如hadoop-site.xml文件,在blueprint或单步创建里会有详细说明。
ambari-agent执行脚本。ambari-agent所执行的脚本存储在ambari-server 机器上的/var/lib/ambari-server/resources/stacks/HDP/2.0.6/下各个service路径下的package路径下的scripts内,脚本的编写语言为python,脚本继承了名为Script的父类,该父类提供了一些函数,例如Script.get_config(),该函数将agent接收来自server端的command-json文件的内容转化为字典格式方便脚本实现部署时对配置的使用。具体anent接收到的command-json保存在了运行agent机器下的/var/lib/ambari-agent/data路径下。

Ambari Blueprint

官方文档

介绍

Ambari-Blueprint 主要作用是通过提供一个Rest API,调用几次API就可以创建一个集群,Ambari-server解析stack下的role_command_order.json文件来自动部署集群,role_command_order.json文件记录着各个服务与组件的部署顺序,ambari-server会自动根据顺序建立task,这样就简化了单步创建时调用Rest API的多次调用。

调用步骤

创建Blueprint

使用HTTP-POST请求建立Blueprint。
注意:在Ambari 1.4之后 在调用Rest API时需要加入 -H "X-Requested-By:ambari"
具体curl命令的demo如下:(集群组件只含有部分 不全 包括HDFS的nn dn ZK的server)

分配host

使用HTTP-POST请求分配host
具体curl demo命令如下:

这样就创建了集群名为的集群了,调用后自动按照role_command_order.json中设置的顺序进行组件的安装、开启,创建成功后会返回如下状态:

在浏览器中打开返回的链接,页面上显示的是每一个安装、开启组件的任务的进度,如果没有出现失败的task,那么会staus更改为COMPLETED。证明集群创建成功,如果失败,可以通过task连接转到task页面查看失败信息。

单步调用Rest API创建集群

单步创建集群即对于集群内每一个服务的安装、开启,组成服务的每一个组件host信息的设置等操作都进行一次ambari-server的restAPI的调用。这样做提高了对集群操作的灵活性,由于Blueprint的出现是在ambari 1.5版本之后,对非HDP版本的支持性可能存在不足,故调ambari-server的restAPI采用的是ambari单步创建集群的调用方式。
需要注意的是:在调用restAPI添加服务等操作请先确定该服务已经在stack中。

Add cluster 创建集群

API

Http-Method

POST

Request-Body

stack版本

DEMO

Add host for cluster 向集群添加host

API

Http-Method

POST

Request-Body

其中

<ambari-server> = nj01-hadoop-rd03.nj01.baidu.com
<cluster-name> = abaciCluster
<master/slave host> = nj01-hadoop-rd03.nj01.baidu.com

注意:如果一个集群有多台host 那么调用多次命令

DEMO

Add service for cluster 向已创建集群添加服务

API

Http-Method

POST

Request-Body

以添加HDFS服务为例

其中

<ambari-server> = nj01-hadoop-rd03.nj01.com
<cluster-name> = abaciCluster
<service-name> = HDFS

DEMO

Add component for service 向已有服务添加组件

API

Http-Method

POST

Request-Body

以添加HDFS服务为例,其中:

<ambari-server> = nj01-hadoop-rd03.nj01.com
<cluster-name> = abaciCluster
<service-name> = HDFS
<component-name> = NAMENODE/DATANODE

注意:调用restapi的次数有该服务的组件种类决定。

DEMO

Add configure for service 向服务添加配置

API

Http-Method

POST

Request-Body

以hadoop-user-info.properties.xml为例

上面的key-value值会存储在command-json中。
注意:配置项很多,可能需要调用多次该restapi。

DEMO

Update configure for service 向服务更新配置

API

Http-Method

PUT

Request-Body

DEMO

Add host for component 向组件添加host

API

Http-Method

POST

Request-Body

以HDFS为例,03为namenode 02 06为datanode:

DEMO

Install service 安装服务

API

Http-Method

PUT

Request-Body

以安装ZK服务为例:

DEMO

Start service 开启服务

API

Http-Method

PUT

Request-Body

以安装ZK服务为例:

DEMO

Close service 关闭服务

服务关闭的命令同服务安装完全一致,当该服务在集群中的状态为started时,这时调用ambari-api的安装命令,ambari系统会将正在运行的服务进程通过python脚本内的stop函数进行关闭。

Ambari-stack 部署脚本编写规则

Ambari-agent在执行脚本时,会根据脚本的函数名进行调用。以下是基本操作函数。

install()

在调用ambari-server安装对应服务的restapi时,ambari-server会给ambari-agent发送command-json格式的文件,agent会调用脚本中名为install()函数来进行部署。函数作用在于在集群内部署该服务的对应组件。

start()

函数作用是开启该服务下对应组件。注意:该方法需要在install成功后调用。

stop()

该函数作用是停止该服务下的对应组件。注意:该方法调用的api与install相同且组件状态为STARTED。

status()

在组件开启后,agent会不断检测组件的状态,并把状态通过心跳汇报给server端,server端收到心跳状态后更新当前集群的服务信息,当用户调用install api来停止组件时,server根据更新后的组件信息来向对应的host发出命令,如果某组件异常终止,那么server在发送停止命令时不会向异常终止的组件所在的agent发送停止命令。
status()状态检查可以使用父类提供的一种方式,check_process_status(file_path),该函数针对提供的文件路径检查对应文件内部的组件进程号是否存在,如果不存在,那么agent就通过心跳汇报给server。

main()

操作脚本的main函数直接调用父类的execute()函数即可。