.. _arch_overview_load_balancing_priority_levels: 优先级别 ------------------ 在负载均衡过程中,Envoy 一般只会考虑处于最高优先级的主机。对于每个 EDS :ref:`LocalityLbEndpoints ` 还可以指定一个可选的优先级。当最高优先级(P=0)的端点是健康的,所有的流量将流转在该优先级的端点上。当最高优先级的端点变得不健康时,流量将开始流向较低优先级的端点。 系统可以通过 :ref:`超额供给系数 ` 配置超额供给流量,目前默认值为 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) 注意:这一节讲的是健康的优先级,但这也可以应用到 :ref:`降级的优先级 `。