交换机链路聚合负载均衡算法原理

初衷:

2011年初我学习交换机链路聚合技术的时候,心中一直有一个疑问:

交换机收到一个报文,到达聚合口的时候,是怎么选择成员口出去的呢?

是随机选的吗?还是按成员编号从小到大或从大到小轮循?如果选择源IP算法,是怎么实现不同源IP就走不同的端口的呢?那时网上也找不到介绍,这个疑问,直到2011年底做测试工程师时,才得到研发兄弟的回答,一直记在心里,总想找个时间发布到网上,让更多人知道,原来负载均衡算法其实是这么的简单!

链路聚合的主要作用是增加带宽,增加可靠性,防止二层环路。在这儿,我不讨论这技术为何而来与作何而用了,只说说报文到达聚合口时,是怎么选择出端口的。


感叹:

2012年底测试一个交换机项目时,和另一家公司(是大企业)是竞争关系,我负责测试本公司交换机(中小企业),名称就都不说了。

在进行入网测试时,工信部测试人员引入真实流量,分光成两份,分别进入两家厂商的交换机,交换机上配置同样的负载分担算法(如:都是SIP hash),同样的聚合组成员数(如:32个)。测试结果是:真实流10G两分钟,两家厂商各成员接口输出报文一模一样(判断出两家厂商负载均衡算法一模一样)。由此我才深深感叹,原来牛逼的厂商用的算法也不过如此而已(以前一直觉得大企业肯定很牛逼,事实最后的测试结果报告还不如我们)。


HASH表介绍:

在交换机内部,每创建一个聚合组时,底层同时创建对应该聚合组的一个hash表,该表存在于交换芯片上,hash表内容如下(简化)

左列index为芯片的硬性支持,现在一般是256,512,1024,更高的未见过。index数量越高,负载分担越均衡。

这儿以3个成员为例:

index

interface

0

eth0_0

1

eth0_1

2

eth0_2

3

eth0_0

4

eth0_1

5

eth0_2

.

.

.

.

.

.

1022

eth0_0

1023

eth0_1


HASH表维护:

交换机里有专门的线程,实时检测聚合组有效成员,一旦成员状态发生变化,立即刷新hash表项。

顺便谈谈刷新HASH表这个技术。

工程师up/down成员口,底层就必须实时的刷新成员(这儿比较考验厂商技术),刷新速度越慢,成员状态变动时丢包越多。技术最强的如cisco,可以做到up/down成员口时,不丢包。而我公司最初会丢一秒钟的包(研发设计思路问题)。后来优化后才达到up/down成员端口,有0.0几秒的丢包,无法做到不丢包。

up/down分析:当工程师在命令行up/down聚合组成员时,底层表项会有那么一丁点儿的响应时间刷新表项,这丁点儿时间,已经down掉的接口还存在hash表里,而报文是一直都有的,正好被hash到这个无效的出端口的报文都会被丢弃!)


交换机负载均衡转发原理:

虽然底层有了一张HASH表,那么到底是怎么利用这张表的呢?

1)工程师设定端口成员与HASH算法,如SIPDIPSIP+DIPSIP+DIP+SP+DP等。

2)交换机根据成员生成HASH表,根据算法提取报文中相应内容。

3)使用特定HASH值的计算方法,把提取的内容计算出一个10bits的值。

4)找到底层HASH表项中该值对应的出端口。

5)把报文从这个出端口转发出去。



HASH值的计算方法:

xor是异或运算,即两个值不相同,则异或结果为真;反之,为假。不同为1,相同为0

1SIP(源IP

1SIP xor 0 得到一个32bit的值.

2)然后作高16bits和低16bitsxor.

3)再用16bits15-12bits11-8bitsxor,将得到的4bits替换到11-8bits,得到12bits右移2位得到10bitshash

注:10bits的值必然是0-1023里的一个数,该index对应的interface是多少,就从该接口转发出去。(相同的IP必然是相同的hash值)


2DIP(目的IP

SIP


3SIP+DIP(源IP+目的IP

1DIP xor SIP得到一个32bits的值。

2)然后作高16bits和低16bitsxor

3)再用16bits15-12bits11-8bitsxor,得到12bits右移2位得到10bitshash值。



4SIP+DIP+SP+DP(源地址 + 目的地址 + 源端口 + 目的端口)

1SIP xor DIP得到32bit的值value1

2hashtemp1的低16bits xor SP 得到32bithashtemp2

3hashtemp2 的低 16bit xor DP 得到 32bit hashtemp3

4)然后作高16bits和低16bitsxor

5)再用16bits1512bits118bits xor,将得到的4bits替换到118bits,得到12bits右移2位得到10bitshash


看完之后,是否发现,原来负载均衡算法是如此的容易!


很多看起来高端的技术,不是做不到,而是想不到。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


什么是设计模式一套被反复使用、多数人知晓的、经过分类编目的、代码 设计经验 的总结;使用设计模式是为了 可重用 代码、让代码 更容易 被他人理解、保证代码 可靠性;设计模式使代码编制  真正工程化;设计模式使软件工程的 基石脉络, 如同大厦的结构一样;并不直接用来完成代码的编写,而是 描述 在各种不同情况下,要怎么解决问题的一种方案;能使不稳定依赖于相对稳定、具体依赖于相对抽象,避免引
单一职责原则定义(Single Responsibility Principle,SRP)一个对象应该只包含 单一的职责,并且该职责被完整地封装在一个类中。Every  Object should have  a single responsibility, and that responsibility should be entirely encapsulated by t
动态代理和CGLib代理分不清吗,看看这篇文章,写的非常好,强烈推荐。原文截图*************************************************************************************************************************原文文本************
适配器模式将一个类的接口转换成客户期望的另一个接口,使得原本接口不兼容的类可以相互合作。
策略模式定义了一系列算法族,并封装在类中,它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
设计模式讲的是如何编写可扩展、可维护、可读的高质量代码,它是针对软件开发中经常遇到的一些设计问题,总结出来的一套通用的解决方案。
模板方法模式在一个方法中定义一个算法的骨架,而将一些步骤延迟到子类中,使得子类可以在不改变算法结构的情况下,重新定义算法中的某些步骤。
迭代器模式提供了一种方法,用于遍历集合对象中的元素,而又不暴露其内部的细节。
外观模式又叫门面模式,它提供了一个统一的(高层)接口,用来访问子系统中的一群接口,使得子系统更容易使用。
单例模式(Singleton Design Pattern)保证一个类只能有一个实例,并提供一个全局访问点。
组合模式可以将对象组合成树形结构来表示“整体-部分”的层次结构,使得客户可以用一致的方式处理个别对象和对象组合。
装饰者模式能够更灵活的,动态的给对象添加其它功能,而不需要修改任何现有的底层代码。
观察者模式(Observer Design Pattern)定义了对象之间的一对多依赖,当对象状态改变的时候,所有依赖者都会自动收到通知。
代理模式为对象提供一个代理,来控制对该对象的访问。代理模式在不改变原始类代码的情况下,通过引入代理类来给原始类附加功能。
工厂模式(Factory Design Pattern)可细分为三种,分别是简单工厂,工厂方法和抽象工厂,它们都是为了更好的创建对象。
状态模式允许对象在内部状态改变时,改变它的行为,对象看起来好像改变了它的类。
命令模式将请求封装为对象,能够支持请求的排队执行、记录日志、撤销等功能。
备忘录模式(Memento Pattern)保存一个对象的某个状态,以便在适当的时候恢复对象。备忘录模式属于行为型模式。 基本介绍 **意图:**在不破坏封装性的前提下,捕获一个对象的内部状态,并在该
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为
享元模式(Flyweight Pattern)(轻量级)(共享元素)主要用于减少创建对象的数量,以减少内存占用和提高性能。这种类型的设计模式属于结构型模式,它提供了减少对象数量从而改善应用所需的对象结