0%

Ambari 服务配置校验和配置推荐介绍

本文主要介绍 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 类,如 ValidationServiceRecommendationService, 然后调用相应的 ResourceProvider, 如 ValidationResourceProviderRecommendationResourceProvider。在 ResourceProvider 中会通过 StackAdvisorHelper 调用不同的命令,如 ConfigurationValidationCommandConfigurationRecommendationCommand, 而这些命令的类都继承 StackAdvisorCommand

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

执行 ambari-server\src\main\resources\scripts\stack_advisor.py 脚本,在 main 方法中会先加载 hostsFileservicesFile,解析为 hostsservices,获取stackNamestackVersionparentVersions 等 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.jsonservices.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(),会依次执行 validateYARNSiteConfigurationsFromHDP206validateYARNSiteConfigurationsFromHDP25validateYARNSiteConfigurationsFromHDP26validateYARNEnvConfigurationsFromHDP206validateYARNEnvConfigurationsFromHDP22validateYARNRangerPluginConfigurationsFromHDP22方法,方法中的 self.method_name 是在 ambari-server\src\main\resources\stacks\stack_advisor.py 中。

推荐配置

触发推荐配置

  • 在安装服务时,加载自定义配置之前会先请求推荐配置,如果有推荐配置,会弹出提示,如下图所示:

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

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

脚本执行逻辑

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

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

recommendConfigurations 方法中,获取 stackNamestackVersionhostsListserviceListcomponentsListclusterSummary 等信息, 然后定义 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 中,有 recommendYARNConfigurationsFromHDP206recommendYARNConfigurationsFromHDP22recommendYARNConfigurationsFromHDP23recommendYARNConfigurationsFromHDP25recommendYARNConfigurationsFromHDP26recommendYARNConfigurationsFromHDP30recommendConfigurationsForSSO 多个方法,会依次执行。

执行完推荐配置脚本后,会有两种处理方法,一种是直接修改原有的配置,通过 putxxxProperty 的方法将值修改为推荐配置;另一种是通过 self.getWarnItemself.getErrorItem 将推荐配置弹出警告或错误提示框。

示例

配置校验

ZooKeeper 为例做配置校验,原有的 ZookeeperServiceAdvisor类中的 getServiceConfigurationsValidationItems 方法没有校验逻辑,现增加 zookeeper-env 中的 Zookeeper Server Maximum Memory 不能超过可用内存的 10%,如果超过,则弹出警告窗。

创建 Validator

首先创建 ZOOKEEPERValidator 类,在这个类中实现具体的校验逻辑,需在 getServiceConfigurationsValidationItems 方法中引用,示例代码如下:

1
2
3
4
5
6
7
8
9
10
def getServiceConfigurationsValidationItems(self, configurations, recommendedDefaults, services, hosts):

self.logger.info("Class: %s, Method: %s. Validating Configurations." %
(self.__class__.__name__, inspect.stack()[0][3]))

self.logger.info("ZooKeeper: getServiceConfigurationsValidationItems ...")

validator = ZOOKEEPERValidator()

return validator.validateListOfConfigUsingMethod(configurations, recommendedDefaults, services, hosts, validator.validators)

ZOOKEEPERValidator 类代码示例如下:

1
2
3
4
5
6
7
8
class ZOOKEEPERValidator(service_advisor.ServiceAdvisor):

def __init__(self, *args, **kwargs):
self.as_super = super(ZOOKEEPERValidator, self)
self.as_super.__init__(*args, **kwargs)

self.logger.info("ZooKeeper: ZookeeperValidator ...")
self.validators = [("zookeeper-env", self.validateZookeeperEnvConfigurations)]

具体校验逻辑

因为校验的参数在 zookeeper-env中,这里单独写一个 validateZookeeperEnvConfigurations 方法,在 validateZookeeperEnvConfigurations 方法中实现校验 zookeeper-env 中参数的具体逻辑。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
def validateZookeeperEnvConfigurations(self, properties, recommendedDefaults, configurations, services, hosts):
self.logger.info("ZooKeeper: validateZookeeperEnvConfigurations ...")

validationItems = []

# get clusterSummary
servicesList, componentsList = self.get_service_and_component_lists(services["services"])
clusterSummary = self.getConfigurationClusterSummary(servicesList, hosts, componentsList, services)
self.logger.info("ZooKeeper: clusterSummary: {0}".format(clusterSummary))

# get totalAvailableRam
totalAvailableRam = int(clusterSummary['totalAvailableRam'])
self.logger.info("ZooKeeper: totalAvailableRam:{0} ".format(totalAvailableRam))

# get zk_server_heapsize
zk_server_heapsize = int(services["configurations"]["zookeeper-env"]["properties"]["zk_server_heapsize"])
self.logger.info("ZooKeeper: zk_server_heapsize:{0}".format(zk_server_heapsize))

# set ram limit
ramLimit = 0.1

self.logger.info("ZooKeeper: start if ...")
if zk_server_heapsize is not None and zk_server_heapsize > totalAvailableRam * ramLimit:
validationItems.append({"config-name": 'zk_server_heapsize',
"item": self.getWarnItem(
"zk_server_heapsize cat't exceed 10% of the total memory")})

return self.toConfigurationValidationProblems(validationItems, "zookeeper-env")

这里以校验 zookeeper-env 中的 Zookeeper Server Maximum Memory 的值不能超过可用内存的 10% 为例。首先获取 clusterSummary,接着获取 totalAvailableRam,然后获取 zk_server_heapsize(注意,这里获取的值要使用 int 强转下),

因为 Zookeeper Server Maximum Memory对应的 namezk_server_heapsize,需要从 services中获取,可以查看 service.json 中的结构关系。设置内存限制比例 ramLimit 为 0.1,然后就可以判断,如果超过可用内存的 10% 后,通过 getWarnItem 设置告警信息,并加入 validationItems,然后返回相应信息。

替换 service_advisor

进入 ZooKeeperservice_advisor.py 所在目录,然后连同编译的文件(service_advisor.pyoservice_advisor.pyc)一并删除。

1
2
cd /var/lib/ambari-server/resources/stacks/HDP/3.0/services/ZOOKEEPER
rm -rf service_advisor.py*

然后上传新的 service_advisor.py 文件(注意文件编码格式必须为:Unix)。

无需重启 Ambari server 或 agent,可以在界面直接修改配置测试。

修改配置测试

Zookeeper Server Maximum Memory 修改为 3072

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

通过 ambari-server.log 中的日志可以查看到:

1
2
2021-04-14 15:06:22,141 INFO DefaultStackAdvisor validateZookeeperEnvConfigurations: - ZooKeeper: totalAvailableRam:11264
2021-04-14 15:06:22,141 INFO DefaultStackAdvisor validateZookeeperEnvConfigurations: - ZooKeeper: zk_server_heapsize:3072

显然 3072 > 11264 *0.1,校验不通过。