优先级别

在负载均衡过程中,Envoy 一般只会考虑处于最高优先级的主机。对于每个 EDS LocalityLbEndpoints 还可以指定一个可选的优先级。当最高优先级(P=0)的端点是健康的,所有的流量将流转在该优先级的端点上。当最高优先级的端点变得不健康时,流量将开始流向较低优先级的端点。

系统可以通过 超额供给系数 配置超额供给流量,目前默认值为 1.4(本文档中的默认值)。如果一个优先级中 80% 的端点是健康的,那么这个级别仍然被认为是完全健康的,因为 80 * 1.4 > 100。因此,P=0 级别端点将继续接收所有流量,直到健康的节点占比低于 71.4%。

优先级逻辑适用于整数健康分数。一个优先级级别的健康分数是(该级别中健康主机的百分比)*(超额供给系数),上限为 100%。P=0 的端点收到(0 级的健康分数)% 的流量,其余的流量流向 P=1(假设 P=1 是 100% 健康的 — 后文再进一步说明)。例如,当 50% 的 P=0 端点是健康的,它们将收到 50 * 1.4 = 70% 的流量。每个优先级收到的流量的整数百分比,统称为系统的“优先级负载”。以下是一个例子(有 2 个优先级,P=1 100% 健康):

P=0 健康端点

到 P=0 的流量

到 P=1 的流量

100%

100%

0%

72%

100%

0%

71%

99%

1%

50%

70%

30%

25%

35%

65%

0%

0%

100%

Attention

为了使负载分配算法和归一化总健康计算能够正常工作,每个优先级必须能够处理(100% * 超额供给系数)的流量:Envoy 假设一个 100% 健康的 P=1 可以完全取代一个不健康的 P=0,等等。如果 P=0 有 10 台主机,但 P=1 只有 2 台主机,这个假设可能就不成立了。

健康分数代表了该级别当前处理流量的能力,它会受该级别最初的超额配置以及当前有不健康节点数量所影响。因此,如果所有级别的健康分数之和小于 100,那么 Envoy 认为没有足够的健康端点来完全处理流量。这个总和称为‘归一化总健康度“。当归一化总健康度降到 100 以下时,将各层的健康度分数归一化到该 100 以下的总分后再分配流量。如:健康度为 {20,30}(得出归一化的总健康度为 50)将被归一化,最终流量优先负载为 {40%,60%} 。

P=0 健康端点

P=1 健康端点

到 P=0 的流量

到 P=1 的流量

100%

100%

100%

0%

72%

72%

100%

0%

71%

71%

99%

1%

50%

50%

70%

30%

25%

100%

35%

65%

25%

25%

50%

50%

随着更多优先级的增加,每一级都会消耗相当于其归一化的有效健康值的负载,除非它上面各层的健康值之和达到 100%,在这种情况下,它不会收到负载。

P=0 健康端点

P=1 健康端点

P=2 健康端点

到 P=0 的流量

到 P=1 的流量

到 P=2 的流量

100%

100%

100%

100%

0%

0%

72%

72%

100%

100%

0%

0%

71%

71%

100%

99%

1%

0%

50%

50%

100%

70%

30%

0%

25%

100%

100%

35%

65%

0%

25%

25%

100%

35%

35%

30%

25%

25%

20%

36%

36%

28%

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

health(P_X) = min(100, 1.4 * 100 * healthy_P_X_backends / total_P_X_backends)
normalized_total_health = min(100, Σ(health(P_0)...health(P_X)))
priority_load(P_0) = min(100, health(P_0) * 100 / normalized_total_health)
priority_load(P_X) = min(100 - Σ(priority_load(P_0)..priority_load(P_X-1)),
                         health(P_X) * 100 / normalized_total_health)

注意:这一节讲的是健康的优先级,但这也可以应用到 降级的优先级