负载均衡算法:P2C、平滑加权轮询与过时负载信息
内容提要
本文系统梳理负载均衡算法,指出gRPC默认使用pick_first而非P2C;P2C的指数级改善仅在信息新鲜时成立,信息过时下JSQ因羊群效应远差于随机;静态加权轮询无法纠正排队波动,异构场景p99比P2C高三成。文章还分析Peak EWMA、Prequal探测、一致性哈希与子集化,并给出工程选型建议。
延伸解读
信息新鲜度决定算法优劣
文章通过模拟表明,负载信息的时效性对算法效果影响巨大。当信息新鲜时,JSQ(加入最短队列)表现最优;但信息过时后,JSQ会因羊群效应迅速恶化,甚至远差于随机选择。P2C(两个选择)在信息延迟时退化最慢,但延迟极大时也会失效。这提醒我们,选择负载均衡算法时,必须评估系统能获取多新鲜的负载信息,而非盲目追求理论最优。
静态权重无法应对动态波动
即使权重与服务器处理能力精确匹配,平滑加权轮询也无法纠正排队波动。在异构场景模拟中,其p99逗留时间比P2C高出约三成。这是因为权重是静态的,而队列长度是动态变化的。P2C仅依据当前队长做决策,反而能更好地适应波动。因此,若系统能获取实时在途请求数,应优先考虑P2C或最少请求策略,权重仅用于表达容量差异。
延迟信号的双面性
Peak EWMA等延迟感知策略能快速响应后端变慢,但文章模拟显示,当在途数信息准确时,引入延迟信号反而会增加噪声,导致性能下降。Prequal的实践则采用分层策略:仅在RIF(在途请求数)未报警时才参考延迟。这说明延迟信号并非总是有益,其价值取决于在途数是否足以反映负载。工程中需根据信号质量决定是否引入延迟,避免画蛇添足。
工程选型需权衡信息与稳健性
文章对比了多种生产实现,指出gRPC默认使用pick_first而非P2C,Envoy的least_request默认有放回抽样,后端少时可能选错。选型应基于可用信息:无信息时用随机或轮询;有本地在途计数时用P2C;有延迟信号时可考虑Peak EWMA但注意噪声;后端周期上报利用率则适合加权轮询。同时需警惕过时信息导致的羊群效应,优先使用本地即时信号。
Q&A
gRPC 默认使用 P2C 负载均衡吗?
不是。gRPC 的默认策略是 pick_first,即只连接第一个可用地址。P2C 加 Peak EWMA 来自 Finagle 和 Linkerd2 使用的 Rust 库 tower。
P2C 的指数级改善在什么条件下成立?
P2C 的指数级改善仅在负载信息足够新鲜时成立。当信息每隔几个服务时间才刷新一次时,挑最短队列(JSQ)会比随机选择还差几十倍,而 P2C 也会在信息过时下逐渐失效。
为什么静态加权轮询在异构场景下不如 P2C?
静态加权轮询无法纠正排队波动。即使权重与服务速率完全成比例,平滑加权轮询的 p99 逗留时间仍比 P2C 高三成,因为每台服务器仍是独立队列,排队波动无人纠正。
过时负载信息下,JSQ 为什么表现差?
过时信息下,所有请求都涌向公告板上最短的队列,直到下次刷新才发现它们已经最长,导致羊群效应。JSQ 在刷新间隔只有半个服务时间时就失去优势,T=5 时平均逗留已比随机选择差,T=50 时差 40 倍。
Peak EWMA 在什么场景下有用?
Peak EWMA 在需要快速响应后端变慢时有用。它结合延迟估计和在途请求数,对突发变慢反应快,但稳态下可能引入噪声,不如纯 P2C。
Prequal 如何改进负载均衡?
Prequal 使用在途请求数(RIF)和延迟估计,通过异步探测和热冷字典序规则(HCL)选择副本。在 YouTube 首页服务中,尾延迟降低 40% 到 50%,中位延迟降低 5% 到 10%。
一致性哈希在负载均衡中有什么作用?
一致性哈希用于需要会话亲和或缓存局部性的场景。它只均衡 key 数,不均衡热度,需要硬上限时可用有界负载。Envoy 的 RING_HASH 默认 minimum_ring_size 为 1024,Maglev 的 table_size 默认 65537。
子集化如何解决客户端全连接问题?
子集化让每个客户端只连接一部分后端,通常 20 到 100 个。随机选子集不均匀,Google 采用确定性子集算法,将客户端分组,每组共享一个洗牌结果,各取互不重叠的一段,确保均匀分布。