本文主要介绍 Ambari 服务配置参数的校验和配置推荐方法,主要根据 value-attributes 和 service_advisor 实现,分析其原理逻辑,并举例说明自定义方法。
概述
Ambari 的配置校验有两种:一种是在 xml 配置文件中,通过值的属性(value-attributes)做约束,在前端做校验;另一种是通过每个服务的 service_advisor.py 中的 getServiceConfigurationsValidationItems 方法做自定义校验。
Ambari 的推荐配置是通过每个服务的 service_advisor.py 中的 getServiceConfigurationRecommendations 方法实现,有些推荐配置会直接将原有的值修改为推荐配置,有些推荐配置则会弹出警告或错误提示框。
value-attributes
stacks 中,每个服务的 conffiguration 文件夹内都会有 xml 格式的配置文件,在这些配置文件中,规定了 name (名称,Ambari 中做标识)、display-name(显示名,界面显示的配置 key 值)、value(默认值)、description(描述,鼠标悬停时显示的提示内容)等基本属性。
另外,还有值的属性 value-attributes 可以对输入值做约束校验,下表列举了常用的值属性及说明。
| 属性 | 说明 | 样例 |
|---|---|---|
| type | 值的类型。 | boolean / int / float / directory / directories / content/value-list / user / password |
| overridable | 可覆盖的,即可以修改的值 | true / false |
| empty-value-valid | 空值是否有效。 | true / false |
| ui_only_property | 只是UI属性。(未见使用该属性) | true / false |
| read-only | 只读 | true / false |
| editable_only_at_install | 只在安装时可以编辑,安装后就不能修改。 | true / false |
| show-property-name | 显示属性名,如果为false,则不显示属性名,只有value | true / false |
| increment_step | 增量步长,用于滑动设置。 | |
| selection_cardinality | 选择基数,用于是否启用某项配置,常用于1,不开启。 | 1 |
| property-file-name | 属性值是某个文件中的内容。 | |
| property-file-type | 文件类型属性,值property-file-name值的文件格式 | json / xml / text |
| entries | 多条数据,包含多个entry,一般为多选,比如Hive Database 参数 | |
| hidden | 隐藏,不在界面展示 | |
| entries_editable | 实体是否可以编辑,如果false,则选择后展示,不可修改,如Hive Database 参数 | true / false |
| user-groups | 用户组,type为user时使用 | |
| keystore | 是否启用秘钥库,tpye为password时使用,常为true | true / false |
| maximum | 允许的最大值 | |
| minimum | 允许的最小值 | |
| unit | 值的单位 | B / MB / ms / Bytes / milliseconds |
| visible | 页面是否可见,常为false | true / false |
参考资料:Configuration support in Ambari - Apache Ambari - Apache Software Foundation
https://cwiki.apache.org/confluence/display/AMBARI/Configuration+support+in+Ambari
service_advisor
每个服务的 service_advisor 主要有配置校验、配置推荐、组件个数校验等方法,一般在 ambari-server\src\main\resources\stacks\HDP\3.0\services\Service_name\service_advisor.py, service_advisor.py 中有相应服务的 XxxServiceAdvisor,它继承于 ambari-server\src\main\resources\stacks\service_advisor.py 中的 ServiceAdvisor 类,而 ServiceAdvisor 又继承于 ambari-server\src\main\resources\stacks\stack_advisor.py 中的 DefaultStackAdvisor 类。
整体逻辑
接下来将介绍从页面请求到后台处理,再到执行脚本等整体逻辑。

页面请求时,会调用 /api/v1/stacks/HDP/versions/3.0/validations 或 /api/v1/stacks/HDP/versions/3.0/recommendations POST 接口,通过 Body 的 recommend 值区分不同命令类型 。请求会发送到相应的 service 类,如 ValidationService 、RecommendationService, 然后调用相应的 ResourceProvider, 如 ValidationResourceProvider 、 RecommendationResourceProvider。在 ResourceProvider 中会通过 StackAdvisorHelper 调用不同的命令,如 ConfigurationValidationCommand 、ConfigurationRecommendationCommand, 而这些命令的类都继承 StackAdvisorCommand。

StackAdvisorCommand 中的 invoke 方法会获取 host 信息和 service 信息,并将其写入到 hosts.json 和 services.json 两个文件中,如可在 /var/run/ambari-server/stack-recommendations/{requestId}目录中查看这两个文件, 然后调用 org.apache.ambari.server.api.services.stackadvisor.StackAdvisorRunner#runScript 方法执行脚本,最后读取脚本的执行结果,并构建 response 返回值。runScript方法中主要是设置 stackadvisor.out 和 stackadvisor.err 输出文件路径,然后根据 serviceAdvisorType 类型是 JAVA 或 Python 选择相应的执行方式,这里一般都是 Python,调用 prepareShellCommand 方法执行 Python 脚本。

执行 ambari-server\src\main\resources\scripts\stack_advisor.py 脚本,在 main 方法中会先加载 hostsFile 和 servicesFile,解析为 hosts 和 services,获取stackName、stackVersion、parentVersions 等 stack 信息,然后根据这些 stack 信息实例化 stackAdvisor。通过判断 action 的类型调用不同的方法,action 类型与请求 Body 体中的 recommend 相对应(不是完全一样,中间有转换)。
RECOMMEND_COMPONENT_LAYOUT_ACTION:推荐服务组件布局。VALIDATE_COMPONENT_LAYOUT_ACTION: 校验服务组件布局,在安装服务时校验组件安装节点个数,每选中或取消一个节点,就会发送一个校验请求。RECOMMEND_CONFIGURATIONS: 推荐配置,在安装服务的过程中,加载自定义之前调用。RECOMMEND_CONFIGURATIONS_FOR_SSO: 推荐配置单点登录(?)。RECOMMEND_CONFIGURATIONS_FOR_KERBEROS: 开kerberos时的推荐配置。RECOMMEND_CONFIGURATION_DEPENDENCIES: 推荐配置依赖,在安装服务之后,修改配置参数时调用。VALIDATE_CONFIGURATIONS: 校验配置,在安装过程中,设置好自定义配置点击“下一步”时调用。
根据不同的 action 类型,调用 stackAdvisor 中相应的方法,然后将结果写入到 json 文件中,如 configurations.json, 和 hosts.json、services.json在同一目录中。
调用 stackAdvisor 中相应的方法时,会实例化各服务的 serviceAdvisor,然后调用相应的方法,这些方法都是可以自定义的。
配置校验
在安装服务过程中,自定义配置后点击 “下一步” 时会调用校验接口, Ambari server 接收到请求后,执行 ambari-server\src\main\resources\scripts\stack_advisor.py, Python 脚本执行流程如下:

在 main 方法中,通过判断 action 类型为 VALIDATE_CONFIGURATIONS,执行 result = stackAdvisor.validateConfigurations(services, hosts), 调用 ambari-server\src\main\resources\stacks\stack_advisor.py 中的 validateConfigurations 方法,执行 validationItems = self.getConfigurationsValidationItems(services, hosts), 调用 getConfigurationsValidationItems 方法。

在 getConfigurationsValidationItems 方法中,通过 for 循环遍历 services 中的服务,调用 self.getConfigurationsValidationItemsForService 方法,在 getConfigurationsValidationItemsForService 方法中,获取 serviceAdvisor,然后调用 serviceAdvisor 中的 getServiceConfigurationsValidationItems 方法。

以 Yarn 服务为例,在 ambari-server\src\main\resources\stacks\HDP\3.0\services\YARN\service_advisor.py 脚本中,调用 getServiceConfigurationsValidationItems 方法,然后执行 validator = YARNValidator(),会依次执行 validateYARNSiteConfigurationsFromHDP206、validateYARNSiteConfigurationsFromHDP25、validateYARNSiteConfigurationsFromHDP26、validateYARNEnvConfigurationsFromHDP206、validateYARNEnvConfigurationsFromHDP22、validateYARNRangerPluginConfigurationsFromHDP22方法,方法中的 self.method_name 是在 ambari-server\src\main\resources\stacks\stack_advisor.py 中。
推荐配置
触发推荐配置
- 在安装服务时,加载自定义配置之前会先请求推荐配置,如果有推荐配置,会弹出提示,如下图所示:

- 安装服务后,修改配置参数时,也会调用推荐配置接口,如果有推荐配置,则会如下图所示:

点击“详细信息”后弹出如下对话框:

脚本执行逻辑
当触发推荐配置后,会调用 ambari-server\src\main\resources\scripts\stack_advisor.py 脚本,逻辑如下图所示:

通过 action 类型调用不同的方法,安装时的 action 是 recommend-configurations, 安装后的 action 是 recommend-configuration-dependencies, 但最终都会到 ambari-server\src\main\resources\stacks\stack_advisor.py 的 recommendConfigurations 方法。

在 recommendConfigurations 方法中,获取 stackName、stackVersion、hostsList、serviceList、componentsList、clusterSummary 等信息, 然后定义 recommendations 格式,接着会判断 config-groups 是否在 services 中,如果在,则调用 recommendConfigGroupsConfigurations 方法(目前没看到哪种情况会走这个逻辑),如果不在,则会走之后的逻辑,这也是推荐配置的主要逻辑。先 for 循环遍历 services,实例化 serviceAdvisor,并将 serviceAdvisor 加入到 serviceAdvisors,然后再 for 循环遍历 serviceAdvisors, 调用 serviceAdvisor.getServiceConfigurationRecommendations(configurations, clusterSummary, services, hosts), 这就调用了每个服务的 service_advisor 中的 getServiceConfigurationRecommendations 方法。
以 Yarn 为例,在 ambari-server\src\main\resources\stacks\HDP\3.0\services\YARN\service_advisor.py 中的 YARNServiceAdvisor(这个文件中还有 MAPREDUCE2Validator)的 getServiceConfigurationRecommendations 中,有 recommendYARNConfigurationsFromHDP206、recommendYARNConfigurationsFromHDP22、recommendYARNConfigurationsFromHDP23、recommendYARNConfigurationsFromHDP25、recommendYARNConfigurationsFromHDP26、recommendYARNConfigurationsFromHDP30、recommendConfigurationsForSSO 多个方法,会依次执行。

执行完推荐配置脚本后,会有两种处理方法,一种是直接修改原有的配置,通过 putxxxProperty 的方法将值修改为推荐配置;另一种是通过 self.getWarnItem 或 self.getErrorItem 将推荐配置弹出警告或错误提示框。
示例
配置校验
以 ZooKeeper 为例做配置校验,原有的 ZookeeperServiceAdvisor类中的 getServiceConfigurationsValidationItems 方法没有校验逻辑,现增加 zookeeper-env 中的 Zookeeper Server Maximum Memory 不能超过可用内存的 10%,如果超过,则弹出警告窗。
创建 Validator
首先创建 ZOOKEEPERValidator 类,在这个类中实现具体的校验逻辑,需在 getServiceConfigurationsValidationItems 方法中引用,示例代码如下:
1 | def getServiceConfigurationsValidationItems(self, configurations, recommendedDefaults, services, hosts): |
ZOOKEEPERValidator 类代码示例如下:
1 | class ZOOKEEPERValidator(service_advisor.ServiceAdvisor): |
具体校验逻辑
因为校验的参数在 zookeeper-env中,这里单独写一个 validateZookeeperEnvConfigurations 方法,在 validateZookeeperEnvConfigurations 方法中实现校验 zookeeper-env 中参数的具体逻辑。
1 | def validateZookeeperEnvConfigurations(self, properties, recommendedDefaults, configurations, services, hosts): |
这里以校验 zookeeper-env 中的 Zookeeper Server Maximum Memory 的值不能超过可用内存的 10% 为例。首先获取 clusterSummary,接着获取 totalAvailableRam,然后获取 zk_server_heapsize(注意,这里获取的值要使用 int 强转下),
因为 Zookeeper Server Maximum Memory对应的 name 为 zk_server_heapsize,需要从 services中获取,可以查看 service.json 中的结构关系。设置内存限制比例 ramLimit 为 0.1,然后就可以判断,如果超过可用内存的 10% 后,通过 getWarnItem 设置告警信息,并加入 validationItems,然后返回相应信息。
替换 service_advisor
进入 ZooKeeper 的 service_advisor.py 所在目录,然后连同编译的文件(service_advisor.pyo,service_advisor.pyc)一并删除。
1 | cd /var/lib/ambari-server/resources/stacks/HDP/3.0/services/ZOOKEEPER |
然后上传新的 service_advisor.py 文件(注意文件编码格式必须为:Unix)。
无需重启 Ambari server 或 agent,可以在界面直接修改配置测试。
修改配置测试
将 Zookeeper Server Maximum Memory 修改为 3072。

点击”保存”按钮,会弹出如下警告框。

通过 ambari-server.log 中的日志可以查看到:
1 | 2021-04-14 15:06:22,141 INFO DefaultStackAdvisor validateZookeeperEnvConfigurations: - ZooKeeper: totalAvailableRam:11264 |
显然 3072 > 11264 *0.1,校验不通过。