osSpecifics详解[三]
# 3.2.5 ComponentResourceProvider 方法定位
# 3.2.5.1 定位 Resources 操作方法
在 ComponentResourceProvider
类中,组件资源的管理和批量操作是平台高频调用的场景。通过代码反推,能看到 Ambari
对于资源更新的接口设计高度规范化,便于集成扩展和权限管理。
实际应用场景
无论是批量调整组件参数、滚动升级还是灰度发布,updateResourcesAuthorized
方法链都是集群自动化运维和大版本升级的底层核心之一。
其主要特性包括:
- 方法名以
update
开头:代表PUT
请求,用于组件的批量或单点更新。 - 操作对象是
Resource.Type.Component
:资源类型为组件粒度,适合微调或批量管理。
调用链解析:
- 入口方法:
updateResourcesAuthorized
- 核心链路:
updateResourcesAuthorized
→updateComponents
→createAndPersistStages
代码片段:
public RequestStatus updateResourcesAuthorized(final Request request, Predicate predicate)
throws SystemException, UnsupportedPropertyException, NoSuchResourceException, NoSuchParentResourceException {
// 此处省略部分代码
RequestStatusResponse response = modifyResources(new Command<RequestStatusResponse>() {
@Override
public RequestStatusResponse invoke() throws AmbariException, AuthorizationException {
return updateComponents(requests, request.getRequestInfoProperties(), runSmokeTest);
}
});
notifyUpdate(Resource.Type.Component, request, predicate);
return getRequestStatus(response);
}
protected RequestStatusResponse updateComponents(Set<ServiceComponentRequest> requests,
Map<String, String> requestProperties,
boolean runSmokeTest)
throws AmbariException, AuthorizationException {
// 此处省略大部分内容
// createAndPersistStages 方法继续反推
return getManagementController().createAndPersistStages(cluster, requestProperties, null, null, changedComps, changedScHosts, ignoredScHosts, runSmokeTest, false);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
笔记
这种设计不仅简化了批量任务下发的流程,还可以灵活集成定制化的安全策略(如命令白名单、资源锁等),平台的健壮性和可扩展性都得到了充分保障。
# 3.2.5.2 Resource.Type 定位
通过源码追踪,我们发现所有相关操作都围绕 Resource.Type.Component
展开,进一步保证了“接口职责单一,资源归属明确”,便于接口级权限管控和接口文档的自动生成。
- 入口 update 方法高度规范,对应实际业务中的 PUT 请求
- 资源类型精细化,兼容后续新组件的快速集成
# 3.2.5.3 定位资源操作类
在接口层,ComponentService
负责具体的请求路由。无论是对单组件还是多组件更新,都保持了参数结构和调用习惯的一致性,极大简化了平台与外部工具(如自动化部署脚本、CMDB)的对接成本。
方法名 | 请求类型 | 路径 | 描述 |
---|---|---|---|
updateComponent | PUT | /clusters/{clusterID}/services/{serviceID}/components/{componentID} | 更新指定组件信息 |
updateComponents | PUT | /clusters/{clusterID}/services/{serviceID}/components | 批量更新组件 |
代码片段:
/
* Handles: PUT /clusters/{clusterID}/services/{serviceID}/components/{componentID}
* Update a specific component.
*
* @param body http body
* @param headers http headers
* @param ui uri info
* @param componentName component id
*
* @return information regarding the updated component
*/
@PUT @ApiIgnore // until documented
@Path("{componentName}")
@Produces("text/plain")
public Response updateComponent(String body, @Context HttpHeaders headers, @Context UriInfo ui,
@PathParam("componentName") String componentName) {
return handleRequest(headers, body, ui, Request.Type.PUT, createComponentResource(
m_clusterName, m_serviceName, componentName));
}
/
* Handles: PUT /clusters/{clusterID}/services/{serviceID}/components
* Update multiple components.
*
* @param body http body
* @param headers http headers
* @param ui uri info
*
* @return information regarding the updated component
*/
@PUT @ApiIgnore // until documented
@Produces("text/plain")
public Response updateComponents(String body, @Context HttpHeaders headers, @Context UriInfo ui) {
return handleRequest(headers, body, ui, Request.Type.PUT, createComponentResource(
m_clusterName, m_serviceName, null));
}
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
29
30
31
32
33
34
35
36
37
38
业务实践补充
- 对于企业集群,常用此接口批量调整组件属性或进行“金丝雀发布”——只更新部分组件,观察健康状况后再全量推送。
- update 相关接口天然适合对接 CICD 平台,实现自动化回滚、回溯和变更审核。
# 3.3 getOsSpecifics 的主要用途
# 3.3.1 筛选软件包的逻辑
getOsSpecifics
作为多操作系统适配的关键利器,本质是让每一次包选择都精准命中主机环境。它的设计消除了人工区分的繁琐,提高了运维的安全性与一致性。
全局包匹配:适合所有操作系统通用包。常见于 JAR、Python 脚本等平台无关型依赖。
if (serviceInfo.getOsSpecifics().containsKey(AmbariMetaInfo.ANY_OS)) { anyOs = serviceInfo.getOsSpecifics().get(AmbariMetaInfo.ANY_OS); }
1
2
3特定 OS 包匹配:根据主机的
osFamily
,动态筛选最适合当前环境的软件包。ServiceOsSpecific hostOs = populateServicePackagesInfo(serviceInfo, hostParams, osFamily);
1组合最终包列表:将全局包与特定 OS 包合并,保证每台主机拿到的包都是最优解。
if (anyOs != null) { packages.addAll(anyOs.getPackages()); } if (hostOs != null) { packages.addAll(hostOs.getPackages()); }
1
2
3
4
5
6
运维误区提醒
有时软件包名中 OS 版本字段容易配置出错,比如 redhat7
/rhel7
混用,建议严格统一,否则极易出现“部分节点缺包”隐性故障!
# 3.3.2 功能特点
- 动态筛选:根据真实环境实时决策,大幅减少人为操作和脚本分支。
- 全局与特定结合:实现通用依赖与平台特定包的灵活叠加。
- 精准匹配:用
osFamily
精细区分平台,极大降低包不兼容风险。
典型场景
- 一键安装脚本中实现自适应部署,无需人工区分包类型
- 集群扩容时,新主机直接继承 osFamily 匹配策略,零差异配置
# 3.3.3 典型应用场景
服务部署
- 首次部署时,通过
getOsSpecifics
生成符合 OS 的软件包清单,极大提高自动化脚本鲁棒性。 - 例如:为 RedHat 主机选择
kafka_${stack_version}
,为 Ubuntu 主机选择kafka-${stack_version}
。
- 首次部署时,通过
服务升级
- 升级过程自动适配,不会因集群异构导致版本冲突。
- 例如:不同操作系统分批次升级,统一升级入口,自动区分包类型。
多操作系统支持
- 实现跨 RedHat、Ubuntu、SUSE 等混合集群的统一包管理。
- 保证部署脚本和升级流程对所有主机透明,无需特殊处理。
注意
实际生产建议将 osFamily 字段与运维 CMDB 强绑定,避免因主机系统误识别导致升级失败!
# 3.3.4 XML 配置与实际生成的结果
osSpecifics
在 XML 文件中的配置决定了平台软件包筛选的灵活性。
开发者只需按实际集群操作系统补全 <osFamily>
和 <package>
,无需维护多套脚本。
XML 示例:
<osSpecifics>
<osSpecific>
<osFamily>redhat8,redhat7</osFamily>
<packages>
<package>
<name>kafka_${stack_version}</name>
</package>
</packages>
</osSpecific>
<osSpecific>
<osFamily>ubuntu18,ubuntu20</osFamily>
<packages>
<package>
<name>kafka-${stack_version}</name>
</package>
</packages>
</osSpecific>
</osSpecifics>
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
实际运行效果:
生成命令参数如下:
"commandParams": {
"service_package_folder": "stacks/BIGTOP/3.2.0/services/KAFKA/package",
"hooks_folder": "stack-hooks",
"script": "scripts/kafka_broker.py",
"package_list": "[{\"name\":\"kafka_${stack_version}\", ... }]",
...
}
2
3
4
5
6
7
总结
合理利用 getOsSpecifics
配合 XML 配置,可显著提升大数据平台在多操作系统环境下的部署与运维效率,是 Ambari 智能化调度的精髓之一!
- 01
- bigtop-select 打包缺 compat 报错修复 deb07-16
- 02
- bigtop-select 打包缺 control 文件报错修复 deb07-16
- 03
- 首次编译-环境初始化 必装07-16