LVS的负载均衡算法主要分为静态动态两大类,它们各自适用于不同的场景。我用一个表格来汇总它们的主要特点,以便你直观了解:

算法类型 算法名称 关键特点 适用场景
静态算法 轮询 (RR) 均等地轮流分配请求,简单但不考虑服务器实际负载和性能差异 后端服务器性能接近且负载均匀的场景
加权轮询 (WRR) 根据预设的权重分配请求,权重高的服务器获得更多请求 服务器处理能力有明显差异的场景
源地址哈希 (SH) 根据请求的源IP地址进行哈希计算,将同一源IP的请求总是发往同一台RS 需要会话保持的应用场景
目标地址哈希 (DH) 根据请求的目标IP地址进行哈希计算,相同目标IP的请求发往同一RS 缓存服务器场景,提高缓存命中率
动态算法 最少连接 (LC) 将新连接请求分配给当前活动连接数最少的服务器 服务器性能相近,且连接请求处理时间长短不一(如长连接较多)的场景
加权最少连接 (WLC) LVS默认算法。在LC基础上考虑服务器权重,选择(活动连接数/权重)值最小的服务器 服务器性能差异较大,需要综合考量连接数和处理能力的通用场景
最短期望延迟 (SED) WLC的改进版,计算方式为**(活动连接数+1)256/权重*,旨在避免新请求加重高负载服务器 试图优化WLC在极端并发场景下的分配,但可能引入新的不均衡
永不排队 (NQ) SED的增强版,首先分配**空闲(连接数为0)**的服务器,若无则采用SED计算 尝试避免任何请求在繁忙服务器队列等待的场景
基于局部性的最少连接LBLC 考虑请求的目标IP,尽可能将相同目标IP的请求发往同一服务器,并结合最少连接原则 缓存集群系统,兼顾负载均衡和缓存局部性
带复制的基于局部性最少连接LBLCR LBLC的增强版,为目标IP维护一组服务器而非固定一台,从组内选择连接数最少的服务器 高负载、高可用的缓存集群场景,避免单点过热

默认算法:加权最少连接 (WLC)

LVS 默认采用的算法是 加权最少连接 (WLC)。这通常是因其在通用性、均衡效果和性能之间取得了较好的平衡。

选择WLC作为默认算法的原因

  1. 综合性强:WLC 结合了服务器的处理能力(通过权重体现)当前的实时负载(通过连接数体现)。这比单纯考虑轮询(RR)或最少连接(LC)更为全面。
  2. 适应性能差异:在实际的集群中,服务器硬件配置、处理能力很可能不一致。WLC 允许通过设置权重(Weight)来反映这种差异,性能好的服务器权重高,自然能承担更多的连接,避免了RR算法在性能不等的服务器间简单轮询带来的资源利用不合理问题。
  3. 动态调整能力:WLC 是一种动态算法,能够根据服务器当前连接数的变化实时调整调度决策。这比静态算法(如WRR)只能依据固定权重分配更灵活,能更好地应对流量的波动。
  4. 相对均衡的效果:在设计初衷上,WLC 旨在将新连接请求导向当前负载(连接数)与其处理能力(权重)相比相对较轻的服务器,从而在整个集群上达到一个相对均衡的负载状态。这使得它在多数场景下能提供不错的均衡效果。
  5. 历史与共识:WLC 算法在 LVS 中经过长期实践,被广泛认为是一种在各种场景下表现相对稳定和可靠的默认选择

注意:WLC 的局限性及 SED/NQ 的补充

值得注意的是,WLC 算法在某些特定情况下可能并非最优,甚至可能存在负载不均衡的风险

  • 短时高并发连接问题:当大量新连接几乎同时到达时,WLC 的内核实现(Overhead = (Active*256 + Inactive) / Weight) 可能因为对 ActiveInactive 连接状态的权重分配(一个Active连接的权重是256,一个Inactive权重是1)不够精确,导致调度器误判。这可能出现短时间内连接都被引导到某一台或某几台RS,导致负载不均。
  • 为改善WLC在高并发下的表现,LVS提供了 SEDNQ 算法作为优化。SED 算法通过 (Active+1)*256/Weight 的计算方式,试图预估加入新请求后的负载,避免请求堆积在已繁忙的服务器上。NQ 则更直接,优先选择当前连接数为0的空闲服务器,若无空闲服务器再退回到类似SED的计算,从而尽量避免任何请求排队。

如何选择合适的算法

选择哪神算法主要取决于你的具体应用场景和需求:

  • 服务器性能均衡,且连接请求差异不大:可以尝试简单的 RRWRR
  • 服务器性能差异较大,需要兼顾实时负载WLC 是一个稳妥的默认选择。
  • 大量持久连接(如数据库、长轮询),且担心服务器重启/扩容后连接分配不均WLC 通常比 WRR 表现更好。
  • 需要会话保持:选择 SH(基于源IP)或 DH(基于目标IP,适用于缓存集群)。
  • 缓存服务器集群LBLCLBLCR 可能更合适。
  • 追求极致性能,避免任何请求排队,或出现WLC在瞬时高并发下负载不均:可以考虑尝试 SEDNQ