背景
Ambari是一個(gè)強(qiáng)大的大數(shù)據(jù)集群管理平臺(tái)苗傅。在實(shí)際使用中新博,我們使用的大數(shù)據(jù)組件不會(huì)局限于官網(wǎng)提供的那些。如何在Ambari中集成進(jìn)去其他組件呢?
Stacks & Services
Stack為一系列service的集合壁却。可以在Ambari中定義多個(gè)不同版本的stacks裸准。比如HDP3.1為一個(gè)stack展东,可以包含Hadoop, Spark等等多個(gè)特定版本的service。
Ambari中stacks相關(guān)的配置信息位于:
- 源碼包:ambari-server/src/main/resources/stacks
- 安裝后:/var/lib/ambari-server/resources/stacks
如果多個(gè)stacks需要使用相同的service配置炒俱,需要將配置放置于common-services中盐肃。common-services目錄中存放的內(nèi)容可供任意版本的stack直接使用或繼承。
common-services目錄
common-services目錄位于源碼包的ambari-server/src/main/resources/common-services
目錄中向胡。如果某個(gè)服務(wù)需要在多個(gè)stacks之中共享恼蓬,需要將此service定義在common-services中。通常來(lái)說(shuō)common-services中給出了各個(gè)service的公用配置僵芹。比如下文提到的組件在ambari中的配置項(xiàng)(configuration)部分的配置处硬。
Service目錄結(jié)構(gòu)
Service的目錄結(jié)構(gòu)如下圖所示:
如圖所示,以HDFS為例拇派,每個(gè)service的組成部分解釋如下:
- Service ID:通常為大寫(xiě)荷辕,為Service名稱。
- configuration:存放了service對(duì)應(yīng)的配置文件件豌。該配置文件為XML格式疮方。這些XML文件描述了service的配置項(xiàng)如何Ambari的組件配置頁(yè)面展示(即service的圖形化配置頁(yè)面的配置文件,配置該頁(yè)面包含什么配置項(xiàng))茧彤。
- package:該目錄包含了多個(gè)子目錄骡显。其中用service控制腳本(啟動(dòng),停止和自定義操作等)和組件的配置文件模板曾掂。
- alert.json:service的告警信息定義惫谤。
- kerberos.json:service和Kerberos結(jié)合使用的配置信息。
- metainfo.xml:service最為重要的配置文件珠洗。其中定義的service的名稱溜歪,版本號(hào),簡(jiǎn)介和控制腳本名稱等等信息许蓖。
- metrics.json:service的監(jiān)控信息配置文件蝴猪。
- widgets.json:service的監(jiān)控圖形界面展示的配置调衰。
metainfo.xml 詳解
不僅service具有metainfo.xml配置文件,stack也會(huì)有這個(gè)配置文件自阱。對(duì)于stack來(lái)說(shuō)嚎莉,metainfo.xml基本用于指定各個(gè)stack之間的繼承關(guān)系。
service metainfo.xml的基礎(chǔ)配置項(xiàng):
<services>
<service>
<name>HDFS</name>
<displayName>HDFS</displayName>
<comment>Hadoop分布式文件系統(tǒng)动壤。</comment>
<version>2.1.0.2.0</version>
</service>
</services>
displayName萝喘,comment和version中的內(nèi)容會(huì)展示在安裝service的第一步,勾選所需組件的列表中琼懊。
component相關(guān)配置
component配置組規(guī)定了該服務(wù)下每個(gè)組件的部署方式和控制腳本等內(nèi)容。舉例來(lái)說(shuō)爬早,對(duì)于HDFS這個(gè)service哼丈,它的component包含namenode,datanode筛严,secondary namenode以及HDFS client等醉旦。在component配置項(xiàng)中可以對(duì)這些組件進(jìn)行配置。
HDFS的namenode組件配置:
<component>
<name>NAMENODE</name>
<displayName>NameNode</displayName>
<category>MASTER</category>
<cardinality>1-2</cardinality>
<versionAdvertised>true</versionAdvertised>
<reassignAllowed>true</reassignAllowed>
<commandScript>
<script>scripts/namenode.py</script>
<scriptType>PYTHON</scriptType>
<timeout>1800</timeout>
</commandScript>
<logs>
<log>
<logId>hdfs_namenode</logId>
<primary>true</primary>
</log>
<log>
<logId>hdfs_audit</logId>
</log>
</logs>
<customCommands>
<customCommand>
<name>DECOMMISSION</name>
<commandScript>
<script>scripts/namenode.py</script>
<scriptType>PYTHON</scriptType>
<timeout>600</timeout>
</commandScript>
</customCommand>
<customCommand>
<name>REBALANCEHDFS</name>
<background>true</background>
<commandScript>
<script>scripts/namenode.py</script>
<scriptType>PYTHON</scriptType>
</commandScript>
</customCommand>
</customCommands>
</component>
其中各個(gè)配置項(xiàng)的解釋:
- name:組件名稱桨啃。
- displayName:組件顯示的名稱车胡。
- category:組件的類型,包含MASTER照瘾,SLAVE和CLIENT三種匈棘。其中MASTER和SLAVE是有狀態(tài)的(啟動(dòng)和停止),CLIENT是無(wú)狀態(tài)的析命。
- cardinality:該組件可以安裝幾個(gè)實(shí)例主卫。可以支持如下格式鹃愤。1:一個(gè)實(shí)例簇搅。1-2:1個(gè)至2個(gè)實(shí)例。1+:1個(gè)或多個(gè)實(shí)例软吐。
- commandScript:組件的控制腳本配置瘩将。
- logs:為log search服務(wù)提供日志接入。
其中commandScript中的配置項(xiàng)含義如下:
- script:該組件的控制腳本相對(duì)路徑凹耙。
- scriptType:腳本類型姿现,通常我們使用Python腳本。
- timeout:腳本執(zhí)行的超時(shí)時(shí)間使兔。
customCommands配置
該配置項(xiàng)為組件的自定義命令建钥,即除了啟動(dòng),停止等等系統(tǒng)自帶命令之外的命令虐沥。
下面以HDFS的REBALANCEHDFS命令為例說(shuō)明下熊经。
<customCommand>
<name>REBALANCEHDFS</name>
<background>true</background>
<commandScript>
<script>scripts/namenode.py</script>
<scriptType>PYTHON</scriptType>
</commandScript>
</customCommand>
該配置項(xiàng)會(huì)在service管理頁(yè)面右上方菜單增加新的菜單項(xiàng)泽艘。配置項(xiàng)的含義和CommandScript相同。其中background
為true
說(shuō)明此command為后臺(tái)執(zhí)行镐依。
接下來(lái)大家可能有疑問(wèn)匹涮,當(dāng)點(diǎn)擊這個(gè)custom command的菜單項(xiàng)之后,ambari調(diào)用了namenode.py這個(gè)文件的哪個(gè)函數(shù)呢槐壳?
實(shí)際上ambari會(huì)調(diào)用和customCommand的name相同然低,名稱全為小寫(xiě)的python方法。如下所示务唐。
def rebalancehdfs(self, env):
...
osSpecifics配置
同一個(gè)service的安裝包在不同的平臺(tái)下雳攘,名字通常是不一樣的。安裝包的名稱和系統(tǒng)的對(duì)應(yīng)關(guān)系是該配置項(xiàng)所負(fù)責(zé)的內(nèi)容枫笛。
Zookeeper的osSpecifics配置示例
<osSpecifics>
<osSpecific>
<osFamily>amazon2015,redhat6,redhat7,suse11,suse12</osFamily>
<packages>
<package>
<name>zookeeper_${stack_version}</name>
</package>
<package>
<name>zookeeper_${stack_version}-server</name>
</package>
</packages>
</osSpecific>
<osSpecific>
<osFamily>debian7,ubuntu12,ubuntu14,ubuntu16</osFamily>
<packages>
<package>
<name>zookeeper-${stack_version}</name>
</package>
<package>
<name>zookeeper-${stack_version}-server</name>
</package>
</packages>
</osSpecific>
</osSpecifics>
注意:該配置中name為組件安裝包全名除了版本號(hào)以外的部分吨灭。需要在系統(tǒng)中使用apt search
或者 yum search
能夠搜索到。如果包搜索不到刑巧,或者說(shuō)沒(méi)有當(dāng)前系統(tǒng)對(duì)應(yīng)的osFamily喧兄,service在安裝過(guò)程不會(huì)報(bào)錯(cuò),但是軟件包并沒(méi)有被安裝啊楚,這點(diǎn)一定要注意吠冤。
service的繼承關(guān)系配置
以HDP這個(gè)stack為例,各個(gè)版本的HDP存在繼承關(guān)系恭理,高版本的HDP的各個(gè)組件的配置繼承自低版本的HDP拯辙。這條繼承線可以一直追溯至HDP2.0.6。
此時(shí)common-services中的配置為何可以共用就得到了解釋蚯斯。common-services中的service配置之所以會(huì)生效薄风,是因?yàn)樵谧罨A(chǔ)的HDP stack(2.0.6)中,每個(gè)service都繼承了common-services中的對(duì)應(yīng)配置拍嵌。
例如AMBARI_INFRA這個(gè)service遭赂。
<services>
<service>
<name>AMBARI_INFRA</name>
<extends>common-services/AMBARI_INFRA/0.1.0</extends>
</service>
</services>
HDP中的AMBARI_INFRA這個(gè)service的配置繼承自common-services中的AMBARI_INFRA/0.1.0的配置。其他組件也是類似的横辆,有興趣可以查看下相關(guān)源代碼撇他。
禁用service
加入deleted標(biāo)簽,該service在新增service向?qū)У牧斜碇袝?huì)被隱藏狈蚤。
<services>
<service>
<name>FALCON</name>
<version>0.10.0</version>
<deleted>true</deleted>
</service>
</services>
configuration-dependencies配置
列出了組件依賴的配置類別困肩。如果依賴的配置類更新了配置信息,該組件會(huì)被ambari標(biāo)記為需要重新啟動(dòng)脆侮。
其他配置項(xiàng)
更為詳細(xì)的介紹請(qǐng)參考官方文檔:https://cwiki.apache.org/confluence/display/AMBARI/Writing+metainfo.xml
configuration配置文件
configuration包含了一個(gè)或多個(gè)xml配置文件锌畸。其中每一個(gè)xml配置文件都代表了一個(gè)配置組。配置組名為xml文件名靖避。
每個(gè)xml文件中規(guī)定了service配置項(xiàng)的名稱潭枣,value類型和描述比默。
下面以HDFS的部分配置項(xiàng)為例說(shuō)明。
<property>
<!-- 配置項(xiàng)名稱 -->
<name>dfs.https.port</name>
<!-- 配置的默認(rèn)值 -->
<value>50470</value>
<!-- 配置的描述盆犁,即鼠標(biāo)移動(dòng)到文本框彈出的提示 -->
<description>
This property is used by HftpFileSystem.
</description>
<on-ambari-upgrade add="true"/>
</property>
<property>
<name>dfs.datanode.max.transfer.threads</name>
<value>1024</value>
<description>Specifies the maximum number of threads to use for transferring data in and out of the datanode.
</description>
<display-name>DataNode max data transfer threads</display-name>
<!-- 這里規(guī)定了屬性值的類型為int命咐,最小值為0,最大值為48000 -->
<value-attributes>
<type>int</type>
<minimum>0</minimum>
<maximum>48000</maximum>
</value-attributes>
<on-ambari-upgrade add="true"/>
</property>
其他更多的配置項(xiàng)谐岁,請(qǐng)參考官方文檔:https://cwiki.apache.org/confluence/display/AMBARI/Configuration+support+in+Ambari
在Python腳本中讀取配置項(xiàng)的值
舉例來(lái)說(shuō)醋奠,此處我們需要在控制腳本中讀取用戶在頁(yè)面填寫(xiě)的instance_name
配置項(xiàng)的值。
配置項(xiàng)的配置文件為: configuration/sample.xml
<?xml version="1.0"?>
<?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
<configuration>
<property>
<name>instance_name</name>
<value>instance1</value>
<description>Instance name for samplesrv</description>
</property>
</configuration>
在python腳本中的讀取方法為:
params.py
from resource_management.libraries.script import Script
config = Script.get_config()
# config被封裝為了字典格式伊佃,層級(jí)為configurations/文件名/屬性名
instance_name = config['configurations']['sample']['instance_name']
組件控制腳本的編寫(xiě)
組件的控制腳本位于package/scripts中窜司。腳本必須繼承resource_management.Script類。
- package/scripts: 控制腳本
- package/files: 控制腳本使用的文件
- package/templates: 生成配置文件的模板文件锭魔,比如core-site.xml, hdfs-site.xml的樣板配置文件等例证。
一個(gè)最簡(jiǎn)單的控制腳本文件:
import sys
from resource_management import Script
class Master(Script):
def install(self, env):
# 安裝組件時(shí)執(zhí)行的方法
print 'Install the Sample Srv Master';
def stop(self, env):
# 停止組件時(shí)執(zhí)行的方法
print 'Stop the Sample Srv Master';
def start(self, env):
# 啟動(dòng)組件時(shí)執(zhí)行的方法
print 'Start the Sample Srv Master';
def status(self, env):
# 組件運(yùn)行狀態(tài)檢測(cè)方法
print 'Status of the Sample Srv Master';
def configure(self, env):
# 組件配置更新時(shí)執(zhí)行的方法
print 'Configure the Sample Srv Master';
if __name__ == "__main__":
Master().execute()
ambari為編寫(xiě)控制腳本提供了如下庫(kù):
- resource_management
- ambari_commons
- ambari_simplejson
這些庫(kù)提供了常用的操作命令,無(wú)需再引入額外的Python包迷捧。
如果需要針對(duì)不同的操作系統(tǒng)編寫(xiě)不同的script,需要在繼承resource_management.Script之時(shí)添加不同的@OsFamilyImpl()
注解胀葱。
下面給出常用的部分控制腳本片段的寫(xiě)法漠秋。
檢查PID文件是否存在(進(jìn)程是否運(yùn)行)
from resource_management import *
# 如果pid文件不存在,會(huì)拋出ComponentIsNotRunning異常
check_process_status(pid_file_full_path)
Template 填充配置文件模板
使用用戶在service頁(yè)面配置中填寫(xiě)的值抵屿,來(lái)填充組件的配置模板庆锦,生成最終的配置文件。
# params文件提前將用戶在配置頁(yè)填寫(xiě)的配置項(xiàng)的值讀取進(jìn)來(lái)
# 對(duì)于config-template.xml.j2所有的模板變量轧葛,必須在params文件中定義搂抒,否則模板填充會(huì)報(bào)錯(cuò),也就是說(shuō)所有模板內(nèi)容必須能夠正確填充尿扯。
import params
env.set_params(params)
# config-template為configuration文件夾中的j2文件名
file_content = Template('config-template.xml.j2')
Python替換配置文件模板使用的是Jinja2模板
InlineTemplate
和Template相同求晶,只不過(guò)配置文件的模板來(lái)自于變量值,而不是Template中的xml模板
file_content = InlineTemplate(self.getConfig()['configurations']['gateway-log4j']['content'])
File
把內(nèi)容寫(xiě)入文件
File(path,
content=file_content,
owner=owner_user,
group=sample_group)
Directory
創(chuàng)建目錄
Directory(directories,
create_parents=True,
mode=0755,
owner=params.elastic_user,
group=params.elastic_group
)
User
用戶操作
# 創(chuàng)建用戶
User(user_name, action = "create", groups = group_name)
Execute
執(zhí)行特定的腳本
Execute('ls -al', user = 'user1')
Package 安裝指定的軟件包
Package(params.all_lzo_packages,
retry_on_repo_unavailability=params.agent_stack_retry_on_unavailability,
retry_count=params.agent_stack_retry_count)
后記
本博客為大家指明了Ambari集成大數(shù)據(jù)組件的基本配置衷笋。本人會(huì)在后續(xù)博客中為大家介紹如何為Ambari集成Elasticsearch服務(wù)芳杏。
Ambari官網(wǎng)參考資料
https://cwiki.apache.org/confluence/display/AMBARI/Defining+a+Custom+Stack+and+Services