跳转到内容

Envoy 负载均衡策略

lyonmu

背景

Envoy 的 cluster 通过 lb_policy 或新的 load_balancing_policy 字段选择负载均衡 策略。不同策略的差异不仅是“怎么选一个 upstream”,还会影响请求长尾、缓存命中、 会话保持、扩缩容抖动和 CPU 开销。

Envoy v3 API 中常见的枚举大致如下:

// Refer to :ref:`load balancer type <arch_overview_load_balancing_types>` architecture
// overview section for information on each type.
type Cluster_LbPolicy int32

const (
	// Refer to the :ref:`round robin load balancing
	// policy<arch_overview_load_balancing_types_round_robin>`
	// for an explanation.
	Cluster_ROUND_ROBIN Cluster_LbPolicy = 0
	// Refer to the :ref:`least request load balancing
	// policy<arch_overview_load_balancing_types_least_request>`
	// for an explanation.
	Cluster_LEAST_REQUEST Cluster_LbPolicy = 1
	// Refer to the :ref:`ring hash load balancing
	// policy<arch_overview_load_balancing_types_ring_hash>`
	// for an explanation.
	Cluster_RING_HASH Cluster_LbPolicy = 2
	// Refer to the :ref:`random load balancing
	// policy<arch_overview_load_balancing_types_random>`
	// for an explanation.
	Cluster_RANDOM Cluster_LbPolicy = 3
	// Refer to the :ref:`Maglev load balancing policy<arch_overview_load_balancing_types_maglev>`
	// for an explanation.
	Cluster_MAGLEV Cluster_LbPolicy = 5
	// This load balancer type must be specified if the configured cluster provides a cluster
	// specific load balancer. Consult the configured cluster's documentation for whether to set
	// this option or not.
	Cluster_CLUSTER_PROVIDED Cluster_LbPolicy = 6
	// Use the new :ref:`load_balancing_policy
	// <envoy_v3_api_field_config.cluster.v3.Cluster.load_balancing_policy>` field to determine the LB policy.
	// This has been deprecated in favor of using the :ref:`load_balancing_policy
	// <envoy_v3_api_field_config.cluster.v3.Cluster.load_balancing_policy>` field without
	// setting any value in :ref:`lb_policy<envoy_v3_api_field_config.cluster.v3.Cluster.lb_policy>`.
	Cluster_LOAD_BALANCING_POLICY_CONFIG Cluster_LbPolicy = 7
)

策略概览

策略复杂度是否感知负载是否适合稳定映射典型场景
Round RobinO(1)实例规格一致、请求耗时均匀
Least RequestO(1)大多数无状态微服务调用
Ring HashO(log N)缓存、会话保持、有状态路由
RandomO(1)超大规模且要求简单的集群
MaglevO(1)节点稳定、追求一致性哈希查找性能
Cluster Provided取决于实现取决于实现取决于实现上游 cluster 自己决定负载均衡
Load Balancing Policy Config取决于配置取决于配置取决于配置复杂策略组合或扩展策略

Round Robin

Round Robin 是最基础的轮询策略,复杂度是 O(1)。Envoy 维护一个游标,按 endpoint 列表顺序依次分发请求。

它支持权重。如果实例 A 的权重是 100,实例 B 的权重是 50,请求分发比例会接近 2:1。

适用场景:

缺点也很明显:Round Robin 不知道后端是否变慢。只要节点仍然健康,它就会继续把 请求发过去。如果某台机器处理变慢但还没有被健康检查摘除,可能造成队头阻塞,并 进一步恶化该节点。

Least Request

Least Request 常被理解为“选择当前请求数最少的节点”,但 Envoy 并不会遍历所有节点 寻找最小值。那样是 O(N),在大规模集群下成本太高。

Envoy 使用的是 P2C(Power of Two Choices)思想:随机选择两个健康节点,比较它们 的 active requests,然后选择较少的那个。它的复杂度是 O(1),但效果明显优于纯随机, 并且非常接近全局最优。

适用场景:

在生产环境中,Least Request 往往比 Round Robin 更适合作为默认策略,尤其是后端 请求耗时不稳定时。

Ring Hash

Ring Hash 是一致性哈希策略,查找复杂度通常是 O(log N)。Envoy 基于 Ketama 思路, 把节点映射到哈希环上,再把请求 key 映射到环上,顺时针选择最近的节点。

它的核心优势是减少扩缩容时的 key 漂移。节点变化时,只有一部分 key 会重新映射, 大部分缓存仍然有效。

适用场景:

使用 Ring Hash 时必须配置 hash policy。否则 Envoy 不知道应该用什么字段作为 key。

Random

Random 是纯随机选择一个健康节点,复杂度是 O(1)。

它的实现简单,适合非常大的 endpoint 集合,或者维护轮询状态、请求计数在极端场景 下可能成为瓶颈的情况。不过在多数生产场景里,它通常不如 Least Request 稳定。

适用场景:

Maglev

Maglev 是另一种一致性哈希策略,来源于 Google 的 Maglev 论文。它不使用哈希环,而 是构建固定大小的查找表,默认表大小常见为 65537 个槽位。

相比 Ring Hash,Maglev 查找复杂度是 O(1),查找速度更快,并且节点变化时能提供更 均匀的分布。

它的代价是建表成本更高。当 endpoint 列表频繁变化时,重建查找表会带来额外计算 开销。

适用场景:

如果后端经常扩缩容或健康状态频繁变化,Ring Hash 往往更容易控制成本。

Cluster Provided

CLUSTER_PROVIDED 是一个特殊标记,表示 Envoy 不负责具体负载均衡决策,而是依赖 上游 cluster 自身的机制。

它通常用于接入某些特定类型的 cluster,或者需要由上游系统自己完成分片、路由和 选择的场景。普通服务调用一般很少手动配置这个策略。

Load Balancing Policy Config

LOAD_BALANCING_POLICY_CONFIG 是 Envoy v3 API 引入的扩展方式。它表示不再只依赖 枚举值,而是通过 load_balancing_policy 字段读取更详细的策略配置。

它适合更复杂的策略组合,例如:

从长期看,load_balancing_policy 是更灵活的配置方式。

策略选择建议

可以按场景快速判断:

负载均衡策略没有绝对最优。真正的选择取决于请求耗时分布、服务是否有状态、endpoint 变化频率,以及是否需要稳定的 key 到节点映射。

Siguiente
Envoy 的 xDS 协议工作流程