聚合集群

聚合集群用于在具有不同配置的集群之间进行故障转移,例如,从 EDS 上游集群到 STRICT_DNS 上游集群,从使用 ROUND_ROBIN 负载均衡策略的集群到使用 MAGLEV 的集群,从连接超时时间为 0.1 秒的集群到连接超时时间为 1 秒的集群,等等。聚合集群通过在 配置 中引用其名称来松散地耦合多个集群。回退优先级由 集群列表 中的顺序隐式定义。聚合集群使用分层负载均衡。负载均衡器首先选择集群和优先级,然后将负载均衡委托给所选集群的负载均衡器。顶层负载均衡器通过将多个集群的优先级集线性化为一个,来重用现有的负载均衡算法。

线性化优先级集

上游主机被划分为多个 优先级级别,每个优先级级别包含一个健康主机、降级主机和不健康主机的列表。线性化用于通过合并来自多个集群的优先级级别来简化负载均衡期间的主机选择。例如,主集群有 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% 健康 - 稍后会详细介绍)。每个集群接收的流量的整数百分比被称为系统的“集群优先级负载”。例如,对于主集群,当 P=0 端点中 20% 处于健康状态、P=1 端点中 20% 处于健康状态、P=2 端点中 10% 处于健康状态时;对于次要集群,当 P=0 端点中 25% 处于健康状态、P=1 端点中 25% 处于健康状态时。主集群将接收 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

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