cardinality详解[一]
# 2. cardinality
和 category
的作用 📂
在 Ambari 的 metainfo.xml
文件中,category
与 cardinality
是定义服务组件角色与部署要求的两大核心属性:
category
标识组件的角色类型,如MASTER
(主节点)、CLIENT
(客户端)、SLAVE
(从节点)等,对应 UI 上组件分组和运维操作入口。cardinality
则约束每个组件在集群中的部署数量范围和分布规则 ,决定能否实现高可用、弹性伸缩、节点冗余与资源隔离。
# 2.1 cardinality
的作用与场景 🎯
cardinality
是集群“安全阀”和“自动扩容基线”。只有合理设置才能避免运维过程中的误操作和资源浪费,也为高可用架构与运维标准化提供了基础。
# 2.1.1 配置类型与常见场景
常见 cardinality 类型及实际意义如下:
- 1:组件全局唯一,集群内仅允许 1 个实例。适用于 NameNode、主控服务等单点核心(需借助冷备实现主备切换)。
- 1+:至少有 1 个,实际可扩展到多台,如多副本负载均衡器或支持横向扩展的服务(Zookeeper/Flink JobManager)。
- 0+:完全可选,部署或不部署均可,常用于“纯客户端工具”或“插件”类组件。
- 3+:典型的高可用分布式主节点,例如 Redis Master,要求集群里必须有 3 个以上以确保写入安全与主从切换。
- 1-3/3-9:约束组件的最小最大实例数,适合有资源限制的多副本服务(如 ElasticSearch 节点数上限)。
例如,Redis Master 设置为 cardinality: 3+
,意味着必须有 3
个或更多主节点,这样即使损失部分节点,集群依然能保证主写、主备自动切换和数据一致性。实际运维中,这也是避免“脑裂”“数据丢失”等灾难的最佳实践。
取值模式 | 场景示例 | 代码配置 | 说明 |
---|---|---|---|
精确值 | 只能有 1 个(如 HMaster) | <cardinality>1</cardinality> | 集群唯一节点,失效即风险 |
最小值 | 至少 3 个(如 Zookeeper/Redis) | <cardinality>3+</cardinality> | 典型高可用,支持主备与冗余 |
范围 | 2~4 个节点(如 ES 数据节点) | <cardinality>2-4</cardinality> | 限制资源浪费,约束伸缩边界 |
ALL | 必须全节点部署(如 Agent 组件) | <cardinality>ALL</cardinality> | 适合运维Agent、监控、边车等全节点任务 |
运维建议
实际部署时,应根据组件特性、业务需求与资源预算,合理设置 cardinality。盲目设高会造成资源浪费,设低则埋下高可用风险。
# 2.1.2 Java 后端解析与约束 🧑💻
Ambari 的 Java 服务端会在部署编排前对 cardinality
进行解析和合规性校验。其核心逻辑体现在 Cardinality
类中:
package org.apache.ambari.server.topology;
/**
* Component cardinality representation.
*/
public class Cardinality {
String cardinality;
int min = 0;
int max = Integer.MAX_VALUE;
int exact = -1;
boolean isAll = false;
// 核心参数-------核心中的核心 请往这里看👀
// 核心参数-------核心中的核心 请往这里看👀
public Cardinality(String cardinality) {
this.cardinality = cardinality;
if (cardinality != null && ! cardinality.isEmpty()) {
if (cardinality.contains("+")) {
min = Integer.parseInt(cardinality.split("\\+")[0]);
} else if (cardinality.contains("-")) {
String[] toks = cardinality.split("-");
min = Integer.parseInt(toks[0]);
max = Integer.parseInt(toks[1]);
} else if (cardinality.equals("ALL")) {
isAll = true;
} else {
exact = Integer.parseInt(cardinality);
}
}
}
// 核心参数-------核心中的核心 请往这里看👀
// 核心参数-------核心中的核心 请往这里看👀
}
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
29
30
31
32
33
34
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
- 自动区分“最小值”“最大值”“ALL 全节点”与“精确值”,并将其封装为统一接口供后续校验调用。
- Ambari Web UI 及 API 批量部署都会依赖此校验,防止因配置疏漏导致部署异常。
注意
如果 cardinality 设置与实际部署不符(如应有 3 个节点却只配了 2 个),Java 端会直接报错阻断,杜绝“带病上线”。
# 2.1.3 Python 端实际部署校验 🧑💻
在运维编排环节,Ambari 的 Python 侧(如 StackAdvisor
子类)会通过 getComponentLayoutValidations
方法,**动态校验当前实际部署节点数量
**与 cardinality 配置的匹配关系。
def getComponentLayoutValidations(self, services, hosts):
# Validating cardinality
for component in componentsList:
if component["StackServiceComponents"]["cardinality"] is not None:
componentName = component["StackServiceComponents"]["component_name"]
componentDisplayName = component["StackServiceComponents"]["display_name"]
componentHosts = []
if component["StackServiceComponents"]["hostnames"] is not None:
componentHosts = [componentHost for componentHost in component["StackServiceComponents"]["hostnames"] if componentHost in hostsSet]
componentHostsCount = len(componentHosts)
cardinality = str(component["StackServiceComponents"]["cardinality"])
# cardinality types: null, 1+, 1-2, 1, ALL
message = None
# 核心参数-------核心中的核心 请往这里看👀
# 核心参数-------核心中的核心 请往这里看👀
if "+" in cardinality:
hostsMin = int(cardinality[:-1])
if componentHostsCount < hostsMin:
message = "At least {0} {1} components should be installed in cluster.".format(hostsMin, componentDisplayName)
elif "-" in cardinality:
nums = cardinality.split("-")
hostsMin = int(nums[0])
hostsMax = int(nums[1])
if componentHostsCount > hostsMax or componentHostsCount < hostsMin:
message = "Between {0} and {1} {2} components should be installed in cluster.".format(hostsMin, hostsMax, componentDisplayName)
elif "ALL" == cardinality:
if componentHostsCount != hostsCount:
message = "{0} component should be installed on all hosts in cluster.".format(componentDisplayName)
else:
if componentHostsCount != int(cardinality):
message = "Exactly {0} {1} components should be installed in cluster.".format(int(cardinality), componentDisplayName)
if message is not None:
items.append({"type": 'host-component', "level": 'ERROR', "message": message, "component-name": componentName})
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
29
30
31
32
33
34
35
36
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
- 最小数量未达标,返回
At least ...
错误 - 数量超限,提示
Between ... and ...
警告 - ALL模式,不全节点部署直接报错
- 唯一性/精确值,数量不符立即终止编排
易错提醒
实际运维中,最常见的问题就是 cardinality 配置与实际主机数量不符,此时 Python 校验会主动终止部署,务必检查集群主机清单与组件分布!
# 2.2 运维实践与最佳建议 🚦
- 所有 HA(高可用)组件,务必用
3+
等约束防止单点风险。 - Agent、监控、边车类服务可用
ALL
,全节点自动部署,减少遗漏。 - 弹性集群推荐用范围/最小值,避免资源浪费同时保障冗余。
- 所有 cardinality 配置建议与企业运维基线规范同步,便于统一管控和自动化升级。