链路聚合通过聚合多条并行的物理链路,对上层协议表现为一条逻辑链路,来提高吞吐量和冗余性。常见的链路聚合技术有Cisco的Etherchannel
,华为的Eth-trunk 以及 linux bonding 等。链路聚合分为动态和静态两种,静态的通过手工配置,动态的通过协议协商。IEEE 规定的链路聚合标准
LACP(Link Aggregation Control Protocol)使用的最为广泛1。
以太网的链路带宽是以10Mbps、100Mbps、1000Mpbs、10Gbps等,速率增长是离散的,链路聚合可以线性的增加链路带宽,例如两交换机之间的流量大于1Gbps小于2Gbps,利用链路聚合绑定两个千兆链路可以很好的解决问题;另一种情况,两交换机之间的流量大约11Gbps,可以利用链路绑定一条千兆一条万兆链路吗?下面的文章就来讨论这个问题。
静态与动态
静态链路聚合:
不需要使用控制协议(i.e 不使用基于网络的协议),通过手工配置生效,当聚合口组成员端口启动后,立即生效(成为活动的成员端口)。
动态链路聚合:
需要使用链路聚合控制协议(LACP),端口通过配置加链路聚合组,但是否生效(被选中成为活动的成员端口)取决于LACP的协商结果。
初见链路聚合——一个拓扑实践
在详细介绍链路聚合之前,先来讨论图1拓扑,初步挖掘一下链路聚合技术,这个神奇的拓扑在《MSTP 解决链路负载均衡与链路检测》一文中用于讨论MSTP 在该拓扑上的适用性,这里面用来讨论链路聚合依然很合适(它依然能引出很多问题)。
情景:如图1 所示,link1 是裸光纤链路,link2 中间加了百兆收发器。
问:这样的拓扑能否使用链路聚合技术?
答案:是不行的,链路聚合技术有很多限制,不同厂商的实现虽然不同,但是仍需要遵循这些限制,如图1 jieru 的E0/0/2 是一个百兆端口,G0/0/1 是一个千兆端口,二者的物理层实现不一样,无法聚合,图1 jieru 上配置e0/0/2与g0/0/1链路聚合会报错。
假设1:将jieru e0/0/2 换成千兆端口(G0/0/2)。
问:图1 拓扑可否使用链路聚合呢?
答案:可以配置成静态的端口聚合,但是静态端口聚合可能会导致转发黑洞。
先来看看link1与link2 有何不同。第一 对应两台交换机来说,g0/0/1 和g0/0/2 一个是光口,一个是电口,介质不同;第二 link1 实际速率(或者说 工作速率 speed)为1000Mbps,link2 实际速率为100Mbps。
第一,介质不同的两个端口可以做链路聚合吗?原则上是不行的,但是事实上很多厂商已经实现这一功能2,只要两条链路都是全双工点对点链路就行。
第二,工作速率不同的两个端口可以做链路聚合吗?动态链路聚合(基于LACP)不支持非等速率链路聚合,LACP 要求参与聚合的N条平行的链路 必须是全双工点对点端口,并且实际速率相同3;静态链路聚合并没有找到明确的规范,实际测试是可以聚合工作速率不同的两端口的。
根据华为的实现,huiju上将G0/0/1 - 2 配置到一个Eth-trunk 中,在huiju上显示
Eth-trunk 的带宽为1.1Gbps,实际上链路带宽不一定能到这么大(见下文 负载均衡章节分析)。
而就算静态链路聚合可以很好的解决负载问题,但是依然解决不了图1 拓扑中潜在的风险,在《MSTP 解决链路负载均衡与链路检测》中谈到,应用在图1 中的冗余协议必须要解决对Link2的链路检测问题,才能避免转发黑洞。静态配置的链路聚合无法感知link2 光纤链路故障(不依赖hello消息),故障发生后相当一部分数据帧会被送入无休止的黑洞。
假设2:目前的光纤传输技术发展的很快,利用DWDM技术,在单个波长上甚至都能传输40Gbps的流量,单条裸光纤使用百兆收发器实在浪费,将图1 中的百兆收发器改成高端些的光端机,为Link2 提供1Gbps的链路带宽。可以满足LACP的要求使用动态链路聚合技术了。
问1:图1 使用LACP聚合的link2 还会产生流量转发黑洞吗?
答:是不会的,使用LACP聚合的链路,会周期性的交换LACPDU,Link2 光纤链路故障发生后,LACP 可以感知到,从而将G0/0/2 端口置为非活动状态,分配给其的会话流量重新分配给G0/0/1 ,因而只会短暂的出现网络中断。
**问2:**link2 光纤链路故障后,LACP多久才能感知到?
**答:**LACP双方在协商阶段会较频繁的发送LACPDU,当协商完成确定要聚合的链路后,LACP双方默认Slow Periodic Time模式下,30s发送一次LACPDU,Long Timeout Time 90s;因此LACP 大约需要90s 才能感知到link2 光纤故障。对于有些业务来说90s的时间太长了,可以调整LACP 工作在Fast Periodic Time 模式下(仅当确认业务不繁忙,且端到端延时较小的情况下,不然造成LACP 震荡),1s 交互一次LACPDU ,Short Timeout Time 3s,从而实现故障快速感知切换。
链路聚合原理分析
上文已经谈到,链路聚合分为动态与静态两种,静态模式的链路聚合会造成不可预料的问题,在多数情况下建议使用动态模式下的链路聚合,使用链路聚合控制协议自动去协商、评估、聚合链路。这节从最常见的链路聚合控制协议(LACP)入手,分析链路聚合的原理。
分层模型
在OSI分层参考模型中,链路聚合工作数据链路层的链路聚合子层,MAC子层之上,MAC Client之下。链路聚合子层可以聚合多个独立的链路,向MAC Client 提供单一的MAC 接口,见下图2
Aggregator (聚合器)为链路聚合组提供数据传输和接收的方法,并向MAC Client 提供单一的MAC 接口,Aggregator包含Frame Collector 和 Frame Distributor,Frame Collector负责从聚合链路组中接收数据帧,传递给MAC Client,Frame Distributor将从MAC Client 收取的数据帧通过聚合链路组传输出去,无论是接收还是传输数据帧,都必须要避免数据帧乱序或者重复;Aggregator Control 中,LACP 负责与对端系统通过Control Frame 交换信息,协商决定聚合哪些链路,以及使能或关闭聚合组,Aggregator Control 通过共享变量实现对Aggregator 的控制。图示见上图3 5.
LACPDU
链路聚合控制协议(LACP)通过交互LACPDU,为配对双方协商聚合哪几条条链路、以及协商如何在聚合链路上正确的发送与接收数据。LACPDU的格式
LACPDU 通过二层组播发送。LACPDU结构中字段很多,这里先介绍一下什么是“Actor”与“Partner”。
链路两端的LACP参与者,通过组播向链路上发送LACPDU,参与者发送LACPDU时,本地系统就称为“Actor”,远端系统就称为“Partner”(换句话说,每个参与者都认为自己是“Actor”,对方是“Partner”)。
LACP状态机
Receive machine:接收并维护与Partner的状态;
Periodic Transmission machine:负责周期性的传送LACPDU,保持聚合状;
Selection Logic :负责为端口选择合适的Aggregator,称:“端口选择了Aggregator” 为”selected”;
Mux machine:负责将端口附着到对应的Aggregator(或分离) ,并且负责使能端口接收或转发数据(或关闭);
Transmit machine:负责周期性的或按其他状态机的要求传输LACPDU。
当LACP协商开始时,Receive machine 负责与Partner 交换配置信息,当Actor和Partner信息交换完毕后(双方完全知晓了对方的信息),Selection Logic 依据对应的算法为端口选择Aggregator,选择完毕后,Mux machine将处于”selected”状态的端口附着在其对应的Aggregator上,并使能数据转发;此后Aggregator便可收取MAC Client 的数据帧,向端口组分发,并且收集端口组转发来的数据帧,传递给 MAC Client;链路聚合完成后,Periodic Transmission machine 周期性的传送LACPDU,Receive machine 接收LACPDU,共同负责保持、维护LACP链路聚合组的状态;Transmit machine 在整个过程中,负责LACPDU的传输。
LACPDU的Actor/Partner State
LACP 使用LACPDU 向对端系统传达自身目前的状态(Actor State)、自己已知的对端系统的状态(Patner State),完成协商过程。
1、协商开始之前,参与者双方都未收到对方的LACPDU,因此端口状态为
Active, Aggeration, defaulted
1
Active:表示系统在该链路使能了LACP;
Aggeration:表示系统认为该链路是“有聚合能力的”;
defaulted:表示系统Receive machine 未获得”Partner”的LACPDU,因此将Partner的信息置于默认值。
2、协商开始后,参与者双方收到了对方的LACPDU,获知了对方的信息,LACP为端口选择了合适的Aggregator,端口会置于以下状态通知对方:
Active, Aggeration, Synchronization
1
Synchronization:表示系统认为该链路已经加入了聚合组,选择了合适的aggregator。
3、当参与者双方的端口都处于2状态时,说明协商成功,该链路可以加入链路聚合组,参与者端口会置于以下状态通知对方:
Activity, Aggregation, Synchronization, Collecting, Distributing
1
Collecting:表示Frame Collector 已经使能,准备接收数据帧;
Distributing:表示Frame Distributor 已经使能,准备分发数据帧。
4、最终参与者双方都处于3状态,链路聚合完成,开始准备转发数据帧。
Selection 算法
简介
Selection 算法或者叫Selection逻辑,是LACP协议中最核心的部分。Selection为端口选择Aggregator,实际上就是决定哪些端口可以聚合,并形成链路聚合组。开始介绍前先了解一下几个概念:
KEY:每个端口、aggregator 都对应一个key,拥有相同key的一组端口,具有聚合的潜力。端口的key 由端口的速率、双工状态、点对点状态以及管理配置信息等决定,具有相同key的端口才有可能聚合在一起。在推荐的实现中,每个端口对应一个aggregator,该aggregator的key与对应的端口的key相同。
System Identifier:由LACP参与者的MAC地址(one of the ports of the System)和优先级(priority)组成。System Identifier用来决定Master与Salve,优先级值小的系统成为Master,优先级相同,则mac地址值小的成为Master。
LAG ID:译为,链路聚合组标识符。同一链路聚合组内的端口的LAG ID 相同。LAG ID由 Actor System Identifier、Actor port key、Partner System Identifier、Partner port key组成。
SElELCTED:当一个端口处于SElELCTED状态,说明该端口已经选择了合适的Aggregator,准备下一步准备attach到Aggregator,完成链路聚合。
很多LACP的实现中,都需要管理员手动的在每个系统配置待聚合的端口组(如思科的EtherChannel),再由LACP协商决定哪些端口可以聚合。
算法6
每一个待聚合端口组只能产生一个链路聚合组,链路聚合组中端口的LAG ID 相同,其他端口处于”UNSELECTED(不选择任何Aggregator)”状态 ;
Master系统,从待聚合端口组中优先级最高的端口开始选择,端口选择KEY与其相同的Aggregator(SELECTED),次优先级的端口如果LAG ID与最高优先级端口相同,则选择同一个Aggregator,若不同,则置于“UNSELECTED”状态,执行下一个端口,直到选择完毕。
Slave系统根据Master的选择,决定聚合哪些端口。
Master P1-3 属于待聚合端口组5,且端口的速率等信息相同,因此Key都为401(系统计算),
Slave P1 P3属于待聚合端口组10,P2 属于带聚合端口组5,因此Key不相同。Master上P1-3的priority都为默认值,因此Port id 最小的P1 是最高优先级的端口,P1首先选择自己对应的aggregator;从图上可以看到P2的LAG ID (401,401,401,401)与P1 的LAG ID(401,401,12945,12945)不同,因此P2 置于”UNSELECTED”状态;P3的LAG ID与P1相同,因此P3 选择与P1 同一个aggregator ;Slave 根据Master 的聚合结果聚合自己的端口。
如图6,将P2 的Priority改为0,因此P2成为了待聚合端口组中最高优先级端口,P2选择了自己对应的aggregator,由于P1、P3的LAG ID与P2不同,因此P1、P3置于“UNSELECTED”状态。
负载均衡与权重
这节讨论aggregator如何分发(从链路聚合组中选择一条成员链路并转发)上层协议(MAC Client)的数据帧,如图3 aggregator 中的Frame Distributor负责分发数据帧,分发需有一定的负载均衡算法, 使数据帧相对均匀的分布在不同的成员链路上,达到扩展带宽的作用。不同的链路聚合实现有多种分发负载算法,但每种分发算法最好都不要产生:
给定的会话7 数据帧乱序
数据帧重复
数据帧乱序或者重复都会对接收者造成不良影响,为避免产生着两种情况,有一个约定俗成的规则,即:所有属于给定会话的数据帧 必须保证从同一链路转发。 这就要求给定会话无论何时到达Frame Distributor,Frame Distributor需要为其选择固定的一条链路,也就是说选择算法是”history Independent”,可以为每个会话维护一张转发端口的对应表,当第一个数据帧选择链路转发后,后续的数据帧依照转发表转发,如此减轻设备的计算负担。
几种负载均衡算法
满足上述规则的负载方式有很多,链路聚合可以使用 MAC 、IP、Layer4 port numbers 逐流负载,可以是基于源地址(端口)、目的地址(端口)或者两种都有8。可以根据不同的拓扑类型选择不同的负载方法。
Example A 是典型的“多对多”传输的场景,SW1 和 SW2 之间的聚合链路基于源MAC或目的MAC(src-mac or dst-mac)分发,即可将流量负载在各个成员链路;
Example B 多台PC同一台路由器通信,路由器的IP、MAC都只有一个,因此源自PC的流量需使用源MAC 负载,源自路由器的流量需使用目的MAC负载。(SW1 src-mac,SW2 dst-mac);
Example C 假设两台服务器所有的通信都使用相同的MAC地址,若实现负载,基于IP或MAC的负载方式都不行,可利用高层协议的信息负载,比如Layer4 port numbers。
非等价链路聚合?
回到图1 的问题,LACP为什么不能聚合速率不同的链路?端口的Key会依据速率(speed)等信息计算,如果速率不同,端口的Key就会不同,LACP无法聚合。上文说过可以通过静态的链路聚合将速率不同的链路聚合起来,但丧失了LACP的特性。目前LACP标准中还不能支持非等价链路聚合。
非等价链路聚合设想
假设需要带宽为12Gbps的链路,如何适配LACP才能实现呢,这里有个设想:
首先LACP key的计算将端口速率排除在外,这样不同速率的端口key 的计算值相同,可以聚合在一起。只有这样是不行的,12Gbps的链路需要聚合三条链路带宽分别是10Gbps、1Gbps、1Gbps,以现有的分发负载方式是无法应对不同速率的端口的。可为每个端口维护一个Weight(权重)值,比如10Gpbs端口的weight是10,1Gbps的weight 是 1,Frame Distributor 依据不同的权重将10/12的会话分发到10Gbps的端口,将1/12的会话分发到1Gbps的端口。
这里有个两个问题,第一 Frame Distributor 不可能预知链路的会话数量,该怎样依据比例分发会话呢?第二 每个会话的流量不同,以会话为粒度负载有可能会造成流量负载不均,甚至拥塞。
为解决这两个问题,使用基于端口负载的动态的权重也许行得通。下面设想一下方案:
为了获得更好的负载效果,将权重的基数设为100Mbps,因此10Gbps的原始权重是10000Mpbs/100Mbps=100,1Gbps的原始权重是10;
当一个数据帧到达,获取当前3个端口的负载量(以Mbps为单位),X=负载量整除100,原始权重减去X等于当前端口权重,数据帧从当前权重最大的端口转发。
维护一张转发表,转发表中是会话的信息与转发端口的对应表,当一个数据帧到达时,先搜索转发表,有对应的转发条目直接转发,没有对应的转发条目则执行上述2转发规则,计算出端口后,转发条目维护进转发表。
这里面端口负载量的计算很有讲究,由于会话的流量是动态的,时大时小,因此负载量须是一段时间的平均负载量,时间跨度取大了或取小了都会对实际负载效果造成影响。
实际实现中,转发表的最大可维持的条目数也有讲究。条目数太多,会过度占用设备的内存,并且寻址时间会增加;条目数太少,会影响选择算法的”history Independent”,同一会话的数据有可能从不同链路转发,造成乱序或帧重复。