置放群组

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


什么是置放群组

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

  • 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_numaffinity 的协同作用

每个成员理想情况下部署在各自独立的物理主机上

partition_numaffinity 表达的是两件不同的事:

  • partition_num 决定群组可容纳多少个成员(同时也表示群组期望跨越多少台不同主机——每个成员一台)。

  • affinity 决定在主机资源紧张时允许多大程度的共置affinity=1 时,任何主机最多承载一个成员;affinity=2 时,回退场景下最多两个成员可共享一台主机,但绝不允许三个。

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

两个示例

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 的原因是:确保单台主机故障永远不会导致群组多数成员同时下线。


生命周期

生命周期:先创建群组,再逐一分配实例

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

  1. 创建群组。region_id 和初始 partition_num 在创建时确定。区域一旦设定终身不可更改;partition_numaffinity 后续可修改。

  2. 分配实例至群组。实例必须与群组位于同一区域,平台将为其选择满足分散策略的主机。

  3. 可随时移除实例,其在群组中的槽位随即释放。

  4. 后续可修改 partition_numaffinity。若将 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(允许更多共置作为回退),或选择其他区域。

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

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


延伸阅读

  • 实例规格 — 为每个成员选择合适的实例规格。

  • 网卡 — 虚拟网卡如何随实例热迁移。

最后更新于