聚合集群

聚合集群用于不同配置的集群之间的故障切换,例如,从 EDS 上游集群到 STRICT_DNS 上游集群,从使用 ROUND_ROBIN 负载均衡策略的集群到使用 MAGLEV 的集群,从连接超时 0.1s 的集群到连接超时 1s 的集群等。聚合集群通过在 配置 中引用它们的名称松散地耦合多个集群。降级优先级由 集群列表 中的排序隐式定义。

聚合集群使用分层负载均衡。负载均衡器首先选择集群和优先级,然后将负载均衡委托给所选集群的负载均衡器。顶层负载均衡器通过将多个集群的优先级集线性化为一个集群,重用现有的负载均衡算法。

线性化优先级设置

上游主机被划分为多个 优先级,每个优先级包含健康、降级和不健康的主机列表。线性化是通过合并多个集群的优先级来简化负载均衡过程中的主机选择。例如,一级集群有 3 个优先级,二级有 2 个,三级有 2 个,故障切换顺序按一级、二级、三级集群先后展开。

集群

优先级

线性化后的优先级

一级集群

0

0

一级集群

1

1

一级集群

2

2

二级集群

0

3

二级集群

1

4

三级集群

0

5

三级集群

1

6

示例

一个聚合集群配置的示例如下所示:

name: aggregate_cluster
connect_timeout: 0.25s
lb_policy: CLUSTER_PROVIDED
cluster_type:
  name: envoy.clusters.aggregate
  typed_config:
    "@type": type.googleapis.com/envoy.extensions.clusters.aggregate.v3.ClusterConfig
    clusters:
    # cluster primary, secondary and tertiary should be defined outside.
    - primary
    - secondary
    - tertiary

注意:PriorityLoad 重试插件 对于聚合集群来说是不起作用的,因为聚合负载均衡器在负载均衡过程中会覆盖 PriorityLoad

负载均衡示例

聚合集群采用分层负载均衡算法,顶层根据每个集群中所有 优先级 的健康评分将流量分配到不同集群。本节中的聚合集群包括两个集群,与上面的配置描述不同。

集群

到一级集群的流量

到二级集群的流量

一级集群

二级集群

P=0 健康端点

P=1 健康端点

P=2 健康端点

P=0 健康端点

P=1 健康端点

100%

100%

100%

100%

100%

100%

0%

72%

100%

100%

100%

100%

100%

0%

71%

1%

0%

100%

100%

100%

0%

71%

0%

0%

100%

100%

99%

1%

50%

0%

0%

50%

0%

70%

30%

20%

20%

10%

25%

25%

70%

30%

20%

0%

0%

20%

0%

50%

50%

0%

0%

0%

100%

0%

0%

100%

0%

0%

0%

72%

0%

0%

100%

注意:上面的负载均衡使用默认的 超额供给系数,即 1.4,这意味着如果一个优先级中 80% 的端点是健康的,那么这个级别仍然被认为是完全健康的,因为 80 * 1.4 > 100。

该示例展示了聚合集群级负载均衡器如何选择集群。例如,健康度为 {{20,20,10},{25,25}} 将导致优先负载为 {{28%,28%,14%},{30%,0%}} 的流量分配。当归一化后的总健康度降到 100 以下时,将各等级的健康度分数归一化到 100 以下的总健康度后进行流量分配。如:健康指数为 {{20,0,0},{20,0}}。产生的归一化总健康度为 56)将归一化,每个集群将收到 20 * 1.4 / 56 = 50% 的流量,这导致优先负载为 {{50%,0%,0%},{50%,0%,0%}} 的流量。

负载均衡器复用优先级逻辑来帮助选择集群。优先级逻辑使用整数健康分数。一个级别的健康分数是(该级别中健康主机的百分比)*(超额供给系数),上限为 100%。P=0 的端点收到 0 级的健康分数百分比的流量,其余的流量流向 P=1(假设 P=1 是 100% 健康的 — 后面会详细介绍)。每个集群收到的流量的整数百分比,统称为系统的“集群优先级负载”。例如,对于一级集群,当 20% 的 P=0 健康端点,20% 的 P=1 健康端点,10% 的 P=2 健康端点;对于二级集群,当 25% 的 P=0 健康端点,25% 的 P=1 健康端点。一级群将收到 20% * 1.4 + 20% * 1.4 + 10% * 1.4 = 70% 的流量。二级集群将收到 min(100 - 70,25% * 1.4 + 25% * 1.4) = 30% 的流量。所有集群的流量之和为 100%。在选择集群和优先级之前,会预先计算出归一化健康评分和优先级负载。

用伪代码来总结一下以上算法:

health(P_X) = min(100, 1.4 * 100 * healthy_P_X_backends / total_P_X_backends), where
                total_P_X_backends is the number of backends for priority P_X after linearization
normalized_total_health = min(100, Σ(health(P_0)...health(P_X)))
cluster_priority_load(C_0) = min(100, Σ(health(P_0)...health(P_k)) * 100 / normalized_total_health),
                where P_0...P_k belong to C_0
cluster_priority_load(C_X) = min(100 - Σ(priority_load(C_0)..priority_load(C_X-1)),
                         Σ(health(P_x)...health(P_X)) * 100 / normalized_total_health),
                         where P_x...P_X belong to C_X
map from priorities to clusters:
  P_0 ... P_k ... ...P_x ... P_X
  ^       ^          ^       ^
  cluster C_0        cluster C_X

第二层是将负载均衡委托给第一步选择的集群,集群可以使用 负载均衡器类型 指定的任何负载均衡算法。