四川省网站建设_网站建设公司_页面权重_seo优化
2026/1/16 13:49:41 网站建设 项目流程

文章目录

  • 前言
  • 一、Linux Bonding驱动底层架构简述
  • 二、Hash Policy
  • 三、 策略解析(layer2 / layer2+3 / layer3+4)
    • 1.layer2
    • 2.layer2+3
    • 3.layer3+4
  • 四、 底层实现细节(以Kernel源码为例)
  • 总结

前言

今天同事在部署环境的时候遇到了一个奇怪的问题:

两台服务器 A, B。操作系统是银河麒麟,过交换机做LACP bond mode4链路聚合,使用的默认layer2哈希策略,LACP已协商成功,聚合状态为UP。但是通过iperf3多并发测试流量长期集中在一条物理链路。

于是针对这个场景展开了排查最终锁定在xmit_hash_policy

参考资料:
1.https://access.redhat.com/solutions/71883
2.https://www.kernel.org/doc/Documentation/networking/bonding.txt
3.https://docs.redhat.com/zh-cn/documentation/red_hat_enterprise_linux/9/html/configuring_and_managing_networking/ref_xmit-hash-policy-bonding-parameter_configuring-network-bonding
4.https://github.com/torvalds/linux/blob/master/drivers/net/bonding/bond_main.c#L3376


一、Linux Bonding驱动底层架构简述

Linux Bonding机制本质上是一种内核模块,它将多个slave interface封装到一个bond interface上,使其对外表现为单个逻辑网卡,从而实现:链路冗余,负载分担,带宽聚合

Bonding驱动的行为主要受两个核心配置影响:

  • mode(工作模式):定义负载/冗余策略,例如 active-backup、802.3ad、balance-xor 等;
  • xmit_hash_policy(散列策略):控制在某些负载均衡模式下(如 balance-xor 和 802.3ad)如何选择发送接口。

二、Hash Policy

在聚合多个物理链路时,最难处理的问题之一是:

如何公平、稳定地把“多个连接/流量”分配到多个链路上?

如果没有合适的散列策略:

  • 相同源/目的 的多个包可能全部走同一物理链路
  • 导致链路利用不均衡;
  • 对某些模式下的连接性能造成瓶颈。

Linux Bonding的设计者引入了一个散列算法(Hash Algorithm),用于对数据包的部分头部字段进行组合计算,再根据结果映射到具体的物理端口。这个过程就是xmit_hash_policy的核心任务。

三、 策略解析(layer2 / layer2+3 / layer3+4)

在802.3ad(LACP)或balance-xor这类模式下,Bonding 必须决定每一个到底从哪一块物理网卡发出去。它不会随机发,而是做一个 hash(散列):

hash(报文头的一些字段) → 得到一个数 → 对链路数量取模 → 选定某条物理口发送

这样做的目的有两个:

  • 稳定性:同一个流始终走同一条链路,避免乱序。
  • 负载分担:不同的流尽量分散到不同链路。

xmit_hash_policy决定的就是hash输入用哪些字段。字段用得越多,区分“流”的粒度越细,但也更依赖报文类型、可能更容易碰到边界情况。

举个例子,类似于快递分拣的场景:

layer2相当于只看发件地址和收件人地址,所有寄到A小区的包裹全部走A通道,寄到B小区的包裹全部走B通道,好处是包裹外箱子印着小区名好分辨,大的小的跨国的都能寄,坏处是万一双十一A小区快递爆满了A通道堵死了B通道还闲着

layer2+3相当于 收件人小区 + 收件人手机号 比如A小区+手机号123走A通道 A小区+手机号987走B通道,优点是同一小区不同人可以分到不同通道,比layer2更均衡。但是缺点是需要在包裹上贴手机号(相当于是IP),如果前台代收(所有的包裹写同一个手机号)还是会挤到一起,没手机号的匿名包裹会随机分配通道

layer3+4相当于 收件人手机号+订单编号 比如手机号123+订单#2026-1(买的手机)走A通道,123+#2026-2(买的耳机)走B通道,123+#2026-3(买的电脑)走C通道。这样的优点是同一个人的多个订单可以完全分开,3 条通道全跑满,负载最均衡。缺点是必须每个包裹都写清楚订单号(相当于 TCP/UDP 端口),如果大件家具拆成3箱:只有第一箱有订单号,后两箱只写续件那么分拣系统看不懂可能会乱分,如果没订单号、没手机号也会乱分,如果标签是外语格式或者扫描仪解析失败,那么会默认走某一条,可能造成倾斜

1.layer2

layer2用MAC来分流(最粗粒度)
用的字段是源 MAC(src MAC)目的 MAC(dst MAC)
所以对于layer2来说同一对 MAC 地址 = 同一条流

这就会导致,如果你的服务器几乎所有流量都发往同一个网关/同一台对端设备,那么:

  • 目的 MAC 基本固定(比如都是网关 MAC)
  • 源 MAC 也固定(bond 的 MAC 或某块口的 MAC)
  • hash 输入几乎不变 → 结果不变 → 很可能长期只跑一条链路

场景:服务器 A(bond0)访问数据库网关 G(同一个网关):

A 的 src MAC:固定
G 的 dst MAC:固定
不管开 10 个TCP连接还是1000个连接,在layer2下它们看起来都属于同一个二层对话 → 可能一直走同一条物理口。

优点:最稳,最简单,兼容性最好
缺点:在对端 MAC 很集中的场景下,负载很难均匀

2.layer2+3

layer2+3用的是MAC + IP来分流
用的字段是layer2的MAC对再加上:源IP和目的IP
同一对IP地址(在同一对 MAC 的基础上)更容易被区分

可以理解为:
layer2只能区分我跟哪个设备说话
layer2+3能进一步区分我跟哪个IP说话

这样当服务器面对的是很多不同的客户端IP/不同的后端IP时,负载会明显更均匀。但如果你的业务本来就是所有连接都打到同一个VIP/同一个数据库 IP”,它仍然可能集中,因为dst IP也固定

场景 :很多客户端访问

1000个客户端IP访问服务(dst IP 是你的服务,src IP 各不相同)
这样hash输入变化很大,更容易把不同客户端的流分散到不同链路

优点:在多数数据中心场景里,是既稳又均衡的最佳折中
缺点:如果通信本来就是固定对固定(同一对 IP)则提升有限

3.layer3+4

layer3+4用的是IP+端口来分流
用的字段是源IP/目的IP源端口/目的端口

也就是同一对IP不够,还要看端口
可以理解为:
layer2+3区分是主机对主机
layer3+4是进一步区分会话对会话

如果有大量短连接(比如 HTTP/微服务调用),每个连接端口都不同hash输入差异大,能把连接更细粒度地分散到多条链路,但对于少量长连接,一个连接的4元组(srcIP, dstIP, srcPort, dstPort)是固定的,固定这个连接会一直走同一条链路

策略hash 看什么能把哪些流区分开最适合的场景
layer2MAC设备对设备简单、稳定、对端不集中的场景
layer2+3MAC + IP主机对主机数据中心最常用折中方案
layer3+4IP + 端口会话对会话高并发、多短连接、多端口

四、 底层实现细节(以Kernel源码为例)

在bonding驱动源码中,可以看到xmit_hash_policy的枚举和计算逻辑:

policy计算字段是否802.3ad说明
layer2MAC基于 MAC 驱动的最简单策略
layer2+3MAC+IP推荐散列策略
layer3+4IP+端口更精细但不严格 802.3ad

内部实现考虑了:

  • IPv4/IPv6
  • TCP/UDP vs 其他协议
  • 分片/重组行为

当 hash 值计算完成,它会通过:

slave_index=hash%slave_count;

将流映射到具体的物理端口。

实践中的权衡选择指南

场景推荐散列策略原因
标准 LACP + 交换机聚合layer2 或 layer2+3兼容 802.3ad 标准
大量短连接layer2+3更均衡分发
多端口多协议通信layer3+4分发更细粒度流
高要求链路顺序layer2 / layer2+3避免分片顺序不一致

总结

简单说,Bonding的负载均衡不是把一个连接拆成两路跑,而是给每一条流连接选一条出口,xmit_hash_policy做的事也很直白,他是决定用哪些信息来算这个出口,从而把不同的流尽量分散到不同链路上。所以选对策略才能更高效地利用聚合带宽。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询