> For the complete documentation index, see [llms.txt](https://docs.console.zenlayer.com/welcome/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.console.zenlayer.com/welcome/cn/elastic-compute/placement-group.md).

# 置放群组

**置放群组**（Placement Group）用于控制 Zenlayer 弹性算力（ZEC）实例在某个区域内的**物理主机**上的分布方式。如需管理置放群组，请在控制台导航至[置放群组](https://console.zenlayer.com/zec/placement-group)页面。若不使用置放群组，调度器可将任意两个实例部署在同一台物理主机上——一旦该主机故障，同一服务的多个副本可能同时下线。置放群组的作用恰恰相反：它将一组实例声明为一个容错集合，平台会将其分散部署在**不同的物理主机**上，确保单台主机故障最多只会影响其中已知比例的实例。

***

## 什么是置放群组

置放群组是一个区域级对象，将一组实例绑定到**不同的物理主机**上。它由两个参数控制：

* **`partition_num`**——群组最多可容纳的成员实例数量。平台的目标是将每个成员部署在独立的主机上。取值范围 2–5，默认值为 3。
* **`affinity`**——当无法实现完全分散时，平台允许在同一主机上共置的群组成员数量上限。这是一个**容忍阈值**，而非目标值或倍增因子。取值范围为 1 到 `partition_num / 2`，默认值为 1。

群组的**容量为 `partition_num`** 个实例。平台的首选策略始终是完全分散——每台主机一个成员。`affinity` 仅用于回退场景：若该区域无法为每个成员提供独立主机，则最多允许 `affinity` 个成员共置于同一主机，超出此限制的请求将被拒绝。

平台会上报 `constraint_status`，方便您随时确认分散策略是否已生效。

> 置放群组仅限于**单个区域**（例如 `asia-east-1`），不跨区域延伸。如需在整个区域故障时保持可用，请在每个区域分别创建一个置放群组，并在应用层实现数据复制。

> **分区粒度目前为主机级别。**

***

## 为什么要使用置放群组

| 场景                                             | 是否适合使用置放群组 | 说明                             |
| ---------------------------------------------- | ---------- | ------------------------------ |
| 分布式仲裁（etcd、ZooKeeper、Consul）——奇数节点集群           | ✅ 适合       | 每个成员部署在独立主机上，单主机故障最多只损失一个仲裁成员。 |
| 有状态副本（数据库主节点 + 副本、Kafka Broker、Cassandra 环形集群） | ✅ 适合       | 将副本共置于同一主机失去了部署多副本的意义。         |
| 无状态 Web 层，N > 1 个副本部署在负载均衡器后                   | ✅ 适合       | 避免单台主机故障导致 VIP 后端整层下线。         |
| 跨区域高可用——抵御整个区域故障                               | ❌ 不够       | 需在每个区域分别建立置放群组，并结合应用层复制。       |
| 单个虚拟机，无副本                                      | ❌ 意义不大     | 单成员群组没有实际效果。                   |
| HPC / 时延敏感型任务，希望实例**更近**而非更分散                  | ❌ 功能不匹配    | 置放群组强制实现反亲和性，目前不支持共置模式。        |

***

## `partition_num` 与 `affinity` 的协同作用

![每个成员理想情况下部署在各自独立的物理主机上](/files/r5aGWvaLJWTaDNUe16LH)

`partition_num` 和 `affinity` 表达的是两件不同的事：

* **`partition_num`** 决定群组可容纳**多少个成员**（同时也表示群组期望跨越多少台不同主机——每个成员一台）。
* **`affinity`** 决定在主机资源紧张时**允许多大程度的共置**。`affinity=1` 时，任何主机最多承载一个成员；`affinity=2` 时，回退场景下最多两个成员可共享一台主机，但绝不允许三个。

容量始终是 `partition_num`，`affinity` 不会扩充容量，它只控制当调度器无法为成员分配独立主机时（或恢复事件导致两个成员回到同一主机后），允许分散程度下降到何种程度后才拒绝分配（或将群组标记为*不满足约束*）。

### 两个示例

**`partition_num=5, affinity=1`**——5 节点仲裁集群的严格分散策略。\
群组最多容纳 5 个成员，所有成员必须部署在不同主机上，平台绝不共置任意两个成员。若无符合条件的空闲主机，该分配请求将被拒绝。

**`partition_num=5, affinity=2`**——具备回退容忍的容错分散策略。\
群组最多容纳 5 个成员，平台仍优先将所有成员部署在不同主机上。若主机容量不足，最多允许 2 个成员共享一台主机，但绝不超过此限。这样可确保群组大多数成员部署在不同主机上，单台主机故障不会同时击垮仲裁多数。

两种情况下，`partition_num` 均将群组上限设为 5 个成员；`affinity` 只改变分配被拒绝前允许的分散程度下限。

### 如何选择 `partition_num`

将 `partition_num` 与您希望分散的集群规模对齐：

| 集群规模                   | `partition_num` |
| ---------------------- | --------------- |
| 主节点 + 1 个副本            | 2               |
| 主节点 + 2 个副本            | 3               |
| 3 节点仲裁（etcd、ZK、Consul） | 3               |
| 5 节点仲裁                 | 5               |

若集群规模超过 `partition_num=5`，请将工作负载拆分到多个置放群组。

### 如何选择 `affinity`

`affinity` 是您对共置的容忍度，适用于无法实现完全分散的情形。对于小型仲裁集群和有状态副本（任意两个副本同时下线均不可接受），建议保持默认值 `1`，以获得最严格的"每主机一成员"保证。若您宁可在主机资源紧张时接受部分共置，也不希望分配请求被拒绝，可适当提高该值（上限为 `partition_num / 2`）。上限设为 `partition_num / 2` 的原因是：确保单台主机故障永远不会导致群组多数成员同时下线。

***

## 生命周期

![生命周期：先创建群组，再逐一分配实例](/files/aVEqZXpQED45BKPoWus0)

置放群组创建时为空，之后逐一为其分配实例。成员关系与实例创建是独立的操作。

1. **创建**群组。`region_id` 和初始 `partition_num` 在创建时确定。区域一旦设定终身不可更改；`partition_num` 和 `affinity` 后续可修改。
2. **分配实例**至群组。实例必须与群组位于同一区域，平台将为其选择满足分散策略的主机。
3. 可随时**移除实例**，其在群组中的槽位随即释放。
4. 后续可**修改** `partition_num` 或 `affinity`。若将 `partition_num` 降低至当前成员数以下，该操作将被拒绝。
5. 成员清空后可**删除**群组。

成员关系具有**排他性**：一个实例最多属于一个置放群组。跨群组重新分配是单步操作——平台将实例从旧群组移出，再将其加入新群组。

> **硬性上限：** `instance_count ≤ partition_num`。向已满的群组添加成员将被拒绝。

***

## 约束状态

`constraint_status` 反映当前部署是否仍满足分散策略：

| 状态     | 含义                                                  |
| ------ | --------------------------------------------------- |
| 约束已满足  | 所有主机上最多部署一个成员——完全分散生效中。稳定状态。                        |
| 约束存在风险 | 某台主机承载了多于一个成员，但未超过 `affinity` 上限。处于容忍范围内，但安全余量有所降低。 |
| 约束已违反  | 某台主机承载的成员数超过 `affinity`。极少出现，通常仅在异常恢复路径下发生。         |

平台会主动避免违反约束的分配，因此大多数群组会长期保持*已满足*状态。

***

## 实例管理

### 添加已有实例

只要群组有空余槽位且实例与群组位于同一区域，即可将正在运行的实例加入置放群组。平台会在实例的下一次分配事件（通常是下一次停止/启动）时应用新的部署位置。在此之前，实例已与群组关联，但其所在主机不会改变。

> 若实例当前所在主机与群组约束冲突，加入操作**不会触发热迁移**。请手动执行一次停止/启动操作，平台将重新为其选择合适的主机。

### 移除实例

移除操作在成员关系层面立即生效。实例继续运行在当前主机上，仅反亲和性的计账信息会更新。

### 替换故障成员

只要替换实例创建完成，立即将其分配至群组，空出的槽位即可复用。

***

## 限制

| 属性              | 值                               |
| --------------- | ------------------------------- |
| 作用范围            | 单个区域（如 `asia-east-1`），不支持跨区域群组。 |
| `partition_num` | 2–5，默认值为 3。                     |
| 每个群组的成员实例数      | ≤ `partition_num`。              |
| 每个实例的群组成员关系数    | 最多 1 个。                         |
| `affinity`      | 1 到 `partition_num / 2`，默认值为 1。 |
| 分区粒度            | 主机级别。                           |

***

## 常见问题

**置放群组能否跨区域？**\
不能。置放群组终身绑定于单个区域。如需跨区域高可用，请每个区域单独创建一个群组，并在应用层实现复制。

**成员数可以超过 `partition_num` 吗？**\
不能。请提高 `partition_num`（最大为 5），或将工作负载拆分到多个群组。

**提高 `affinity` 会增加容量吗？**\
不会。容量始终由 `partition_num` 决定。`affinity` 是调度器在无法完全分散时允许共置于单台主机的最大成员数——它控制的是允许的退化程度，而非群组容量。

**成员实例发生热迁移时会怎样？**\
目标主机的选择会确保约束依然满足，迁移过程中成员关系和 `constraint_status` 均保持不变。

**能否将实例在两个置放群组之间移动？**\
可以。重新分配是单步操作——实例离开旧群组的槽位，占用新群组的空闲槽位。两个群组必须与实例位于同一区域。

**使用置放群组会产生额外费用吗？**\
不会，每个群组均免费。

**为什么我的分配请求被拒绝了？**\
原因可能是群组已满（`instance_count == partition_num`），或该区域内没有主机能在当前 `affinity` 限制下满足约束。请尝试提高 `partition_num`、提高 `affinity`（允许更多共置作为回退），或选择其他区域。

**能否按机架或交换机而非主机进行分散？**\
目前不支持，仅暴露主机级别的分区粒度。

**置放群组与资源组有何区别？**\
**资源组**是组织/计费边界；**置放群组**是*物理部署*约束，控制实例可在哪里运行。两者相互独立。

***

## 延伸阅读

* [**实例规格**](/welcome/cn/elastic-compute/instance-specification.md) — 为每个成员选择合适的实例规格。
* [**网卡**](/welcome/cn/elastic-compute/networking/network-interface.md) — 虚拟网卡如何随实例热迁移。
