向 波,俞黎阳
华东师范大学 计算机科学与软件工程学院,上海 200062
传统网络中,网络策略和配置在运行前都固化一体。网络运行期间,如果策略需求发生变动,重新配置修改相应的网络设备是一件非常繁琐的事情。在互联网/移动互联网瞬息万变的业务环境下,网络的高稳定与高性能还不足以满足实时的业务需求,灵活性和敏捷性变得日趋重要。
在这样的背景下,软件定义网络(Software Defined Network,SDN)应运而生,它提出将网络设备中的转发平面与控制平面解耦,提供了传统网络难以企及的灵活性和敏捷性。SDN将多个网络节点的控制平面集中化为一个中心控制器,网络管理人员可以通过在控制器上编写软件应用操作下层转发设备。通过这样的方式,可以大大简化网络的配置过程,并可以根据网络状况实时下发策略,有效提高网络的灵活性。
SDN目前仍处于萌芽发展期,业内已经有一部分实验性的网络架构应用于生产环境,比如Google的数据中心网络B4[1]。但是SDN在带来极大便利的同时,也面临许多新的问题,如控制器的可扩展性,SDN的故障恢复等。控制器的可扩展性指的是单个控制器的资源有限,导致单控制器无法处理大量请求负载。在大型网络中,这个问题尤为明显。而SDN的故障恢复在小型中型乃至大型网络中都是不容忽视的问题。SDN中,根据故障发生的位置,可以分为数据平面故障和控制平面故障,这两者故障恢复方式有所差别。数据平面故障时,控制器仍然可以参与故障恢复,控制器接受下层提交的故障信息,重新计算、下发命令给下层。在恢复时间要求严格的场合,也可以采用预先安装保护性措施的方式加快恢复速度[2]。而控制平面的容错则显得更为复杂一点,在控制平面(包括控制器自身以及控制器与交换机之间的通信链路)发生故障时,不再有控制器从上层指挥恢复行为。本文研究控制器单点故障时的容错机制。学术界对此已有多方讨论并提出了各种各样的解决方案,多控制器容错成为解决此问题的方案之一,也是当前使用最广泛的方案之一。当前主流的多控制器容错机制大多采用多控制器主从协作,这种机制需要多个控制器协同控制同一个控制域,某种程度上是对控制器资源的极大浪费。鉴于此,本文提出一种带内通信场景下平面式的多控制器容错架构,单控制器控制单个自治域,在可接受的时间内完成控制器故障的快速恢复。
图1展示了单控制器管理的SDN带内通信网络。中心化的控制器通过网络的南向接口(如OpenFlow)控制转发平面行为,这给网络带来了极大的灵活性。与此同时,集中化的控制器也成为网络运行时的一大隐患。若控制器发生单点故障,交换机仍可正常转发数据包,但是控制器无法对下属交换机进行正确的转发指导,大量的数据包(尤其是packet-in报文)会被丢弃,导致网络无法正常工作。
图1 SDN带内通信
目前SDN控制器容错主要针对的是多控制器场景。多控制器容错,主要考虑的有控制器部署、控制器级联失效以及具有容错能力的控制器架构设计这几个方面。
(1)关于多控制器部署。目前这方面的研究大多探讨带内通信场景下,如果某些节点失效,如何使得整个网络中受影响的节点数量最少,而不是考虑故障发生后如何进行故障恢复。这些研究的关键就在于使用何种算法进行多控制器部署。文献[3-5]分别使用了网络依赖分析,最小分割算法和贪心算法部署多个控制器。这些文章都是在控制器故障已经发生的情景下讨论多控制器部署问题。文献[6]则考虑了故障发生前后这两种场景,在多控制器部署和性能(控制器与交换机之间时延和容错性能)之间进行折中。文献[7]研究了多控制器主从协作时的控制器分配问题,在保证时延和交换机所需控制器数目的情况下,最小化网络中控制器的数量。
(2)如何处理控制器级联失效。控制器级联失效,是指在多控制器场景下,一台控制器失效后,其下属交换机需要交由其他控制器负责管理,此时就可能出现其他控制器过载的现象。文献[8]提出了一个参数-容忍模型,以及控制器容量与当前负载之间需满足的条件,来解决控制器的级联失效问题。
(3)具有容错能力的控制器架构设计。文献[9-10]提出使用额外的数据存储同步控制器之间的信息。文章提出采用主从式架构,即同一时间只有一台控制器对全网进行控制,从而减少了多个同时工作的控制器之间同步信息的开销。同时数据存储的使用也避免了控制器切换带来的耗时问题。文献[11]针对带内通信场景提出了一个基于事务的分布式控制平面来保证控制平面信息的一致性,同时使得故障域本地化。与带外通信相比,大大降低了复杂度,同时避免了带外的诸多限制。文献[12]提出一种高可用性的TCP技术,解决控制器故障恢复过程中交换机异步报文丢失的问题。文献[7,10,13]都采用了多控制器主从协作的思想。文献[7]提出一种控制器遭遇拜占庭式攻击而失效的解决方案。文中提出使用BFT(Bayzantine Fault Tolerant)算法来保证交换机不受被攻击控制器发出的虚假信息的影响,利用多控制器协作提高交换机流表下发更新的准确率和成功率。文献[10]重点研究了交换机与控制器之间多对多的对应关系,文中仅简单介绍算法的容错原理,没有结合SDN网络的具体场景对其工作机制和实现方法做进一步研究。此外,文章也没有给出FT(Fault Tolerant)算法对SDN网络性能造成的影响。文献[13-14]提出使用Paxos算法的思想进行多控制器容错。文献[13]着重于容错机制的实现,保证主控制器故障时网络能够平滑地切换到从控制器。而文献[14]重点研究并减小这种容错机制对于控制器性能的影响,在控制器容错与控制器性能之间进行平衡。
上述多控制器容错方案中,使用最为广泛的就是多控制器主从协作,主从控制器保持状态一致,主控制器失效时,从控制器可以快速接管主控制器的工作,使得网络能够正常运作。
然而,使用多个控制器控制单个网络域是对控制器资源的极大浪费。为了有效利用控制器资源,本文提出一种平面式的架构,具体为多个控制器组成的带内通信场景下,将网络划分成多个控制域,每个控制域由单独的控制器进行管理。这些控制器前后相连形成环状结构,利用心跳监测之类的方法检测控制器故障,控制器故障后,采用交换机重托管算法将故障控制器下的交换机托管到其余正常工作的控制器下。此外,考虑到单个控制器的负载能力有限,为了避免控制器过载引发控制器级联失效,本文选择将故障控制器下的交换机划分为多个交换机簇,再将交换机簇托管到不同的控制器下。极端情况下,正常工作控制器的总剩余负载无法满足故障控制器下所有交换机。为此,本文使用预定义的脚本动态添加控制器。为了获取故障控制器及其下属交换机的网络信息,本文将所有控制域的网络视图存储到一个分布式的Hazelcast数据库中。
这一节将对控制器故障检测,交换机簇划分和交换机重托管这三个主要模块进行介绍。
4.2.1 控制器故障检测
常见的网络故障检测方法有三种,分别是Hello报文(心跳检测)、BFD(Bidirectional Forwarding Detection)和LoS(Loss of Signal)。
以OSPF、ISIS等常见路由协议为例,这些协议本身就具有故障检测能力,通过互相发送Hello报文用于协商和建立邻居。关系建立完成后,邻居间仍然会每隔一定时间发送一次Hello报文并对收到的Hello报文进行回复。这种行为就像设备的心跳一样,只要心跳一直存在就表明设备功能正常,反之如果发送出去的Hello报文一直没有收到回复,那么协议就认为邻居出现故障。这种设备间互相发送Hello包的方式被称为慢Hello机制,其缺点是只能提供秒级检测,对于时延敏感的业务(如语音业务),超过1秒的延迟也是令人无法忍受的。BFD(Bidirectional Forwarding Detection)是一个用于检测网络故障的协议,可以实现毫秒级检测。BFD的原理和IGP协议自带的Hello报文类似,简单来说就是高速发送Hello报文,因此可以更快检测到故障。LoS意为信号丢失,可能的原因有很多,如网络设备链路故障,网络设备配置不正确或者设备本身故障。LoS往往用于检测数据平面转发端口的失效。由于本文是对控制器故障进行检测,并且需要保证实时性,所以本文选用了BFD。
4.2.2 交换机簇划分
控制器故障后,故障控制器无法对其下属交换机进行转发指导,这时就需要对网络进行快速恢复。本文采用的是平面式的容错架构,所以最好的方法就是将故障控制器下的交换机托管给其余正常工作的控制器。
然而,控制器负载交换机数量是有限的,在保证控制器能够正常工作的前提下,当前网络中可能不存在任何一台控制器剩余足够容量去负载故障控制器下的所有交换机,所以需要将故障控制器下的交换机划分为若干交换机簇,将交换机簇托管到不同的控制器下。交换机簇的划分在某种程度上也是一种控制器间的负载均衡,可以有效缓解文献[8]中提到的控制器级联失效问题。在交换机簇划分问题上,存在着许多的偏好,偏好不同,则结果往往大相径庭。例如,若按照交换机与控制器间延迟大小进行划分,网络恢复后节点间的延迟会较小,但是极易产生控制器负载失衡甚至级联失效;若按照控制器剩余容量大小进行划分,网络恢复后的延迟可能会较大,容易产生网络拥塞。本文平衡了延迟与控制器剩余容量双重偏好,延迟优先,在低延迟的情况下根据控制器剩余容量进行划分,保证网络恢复后的低延迟和高性能。即便这样,仍有可能出现其余正常工作控制器的总剩余容量小于故障控制器下交换机数量的极端情况。为此,本文使用预定义的脚本动态添加控制器。具体的交换机簇划分算法和实例将在5.4节进行详细介绍。
4.2.3 交换机重托管
交换机簇划分完成后,接下来的工作就是将这些交换机簇托管到对应的控制器下。本文采用的是带内通信模式,若某台交换机需要托管到其他的控制器下,则只需这台交换机与新的控制器直接或间接存在一条可以连通的链路即可。具体的重托管思想和过程将在5.5节进行详细介绍。
在上一章介绍整体架构的基础上,本章将详细介绍主要模块的实现细节。
本文选用的Floodlight控制器,虽自身提供了NoSQL的存储机制,但过于简单,综合考虑性能以及安全性和稳定性,本文使用Hazelcast实现分布式数据存储。
在众多的NoSQL数据库中,Hazelcast具有领先的多并发性能和灵活性,其数据存储机制和分布式架构保证了数据存储的低延迟和高并发。此外,Hazelcast提供了强大的一致性保证、事务支持和事件通知,并可通过配置定期将数据持久化到磁盘中。Hazelcast是基于Java实现的,很容易与Floodlight控制器进行整合。为了便于控制器故障的快速恢复,每台控制器定时获取其下属控制域的拓扑视图,并将抽象化的网络视图存储到Hazelcast中。
带内通信的建立参考了文献[15]中使用的DHCP客户端-服务器模式。带内通信网络下,交换机与控制器之间的会话通过TCP连接进行维持。选用DHCP客户端-服务器模式可以实现交换机动态获取网络地址,以便交换机与控制器之间能够建立TCP连接。具体步骤为:
(1)每台交换机运行一个DHCP(动态主机配置协议)客户端。
(2)每台交换机中开辟两块单独的栈区分别用来保存数据流和控制流。
(3)DHCP客户端(交换机)广播发送DHCP报文,DHCP服务器向客户端(交换机)回复DHCP报文时携带控制器的IP地址和端口号。DHCP服务器可以位于控制器内部进程中,也可以位于其他外部进程中。若DHCP服务器位于独立进程中,则此进程必须与控制器处于同一子网,以保证DHCP服务器能够与交换机进行通信。本文为了方便,将DHCP服务器放置于单独的进程中(一个控制域拥有一个DHCP服务器,所有DHCP服务器共享同一IP资源池)。
若交换机没有连接到控制器,即交换机没有分配IP地址,则交换机周期性地发送DHCP报文给其邻居节点,直到收到DHCP服务器的应答。如果邻居节点就是DHCP服务器,则DHCP服务器直接回复DHCP响应。否则,邻居节点根据自身是否已经与控制器建立Open-Flow会话决定转发或者丢弃DHCP报文。如果邻居节点已经与控制器建立DHCP会话,则邻居节点将DHCP请求报文转发给DHCP服务器,否则直接丢弃。当交换机获取到IP地址并且知晓了控制器的IP地址和端口号,交换机便与控制器建立OpenFlow会话。当每台交换机都与控制器建立或保持OpenFlow会话后,控制器通过LLDP(链路层发现协议)获取网络拓扑。
控制器故障检测主要利用相邻控制器间BFD通信进行控制器状态监测,这个模块被整合到控制器中。BFD原本用于两个转发点间快速发送Hello包进行故障检测,其中某个转发点接收不到Hello报文,则认为转发点间的链路发生故障。本文利用BFD故障检测的思想,在环形控制器间建立双BFD链路,假定链路持续稳定的情况下,若控制器间通信间断,则假定控制器发生故障。环形控制器类似于一条双向链表,链表节点可以与前后相邻节点进行通信。使用双BFD链路的目的是为了降低链路故障的概率,进一步保证控制器故障检测的准确率。
图2展示了4个控制器形成的环状链路。现举例说明控制器故障检测的思想和过程。
图2 中的控制器D、A、B依次相连。A定时向D和B发送Hello消息,同时在发送后将当前时间存储到数据库中。D和B若收到A发送的Hello消息,则将收到消息的时间存储到数据库中。若D在指定时刻未收到A发送的Hello消息,则D查询B在相应时刻是否收到A发送的Hello消息。若B未收到Hello消息,其也会采取相同的措施。只有D和B均未收到A发送的Hello消息,则假定A发生故障。为了进一步确认A是否故障,D和B到数据库中查询A最近一次发送Hello消息时记录到数据库中的时间,若该时间与当前时间相差超出Hello消息发送时间允许的误差,则判定A发生故障。
每台控制器与前后相邻两台控制器维持BFD会话可以大大提高控制器故障检测的准确率。此外,辅之以时间对比,可以进一步提高控制器故障检测的实时性和准确率。为了保证控制器间BFD消息发送的同步,实验环境均使用同一时钟服务器进行时钟同步。
据证监会公开数据显示,浦银安盛、招商、永赢、银华、平安基金等公司也申报了多只政策性金融债指数基金,目前正在排队等待审批。其中,平安基金于10月25日一口气申报了0-3年期、3-5年期、5-10年期等三只政策性金融债指数基金,覆盖到了短中长期的不同期限。整体来看,目前已经有15家公募基金公司开始布局政策性金融债指数基金(包括已申报但暂未获批的在内)。
交换机簇划分的前提是获取控制器故障前的全局网络拓扑,所以每台控制器需要定时获取各自控制域的网络拓扑并存储到数据库中。这里就存在这样一种情况,控制器刚刚获取网络拓扑信息并存储到数据库中,之后网络拓扑发生了变化,而在下一次控制器主动获取网络拓扑之前控制器发生了故障,此时数据库中关于此网络的拓扑信息便与实际的网络拓扑不一致。为了保证拓扑信息的实时性和一致性,本文使用LoS对交换机端口状态进行监测,当检测到端口状态发生变化(Up/Down),交换机发送packet-in消息通知控制器拓扑信息变化,控制器便可以及时更新网络拓扑。
在已有网络拓扑的情况下,接下来需要将数据库中存储的拓扑信息抽象成一张无向图,在无向图上进行图论切割。本文切割的标准是优先延迟(使用控制信息在网络中传输的跳数来表示),在保证低延迟的情况下再优先考虑新控制器的剩余负载。
为了描述交换机簇划分算法,本文定义了一些变量如表1。
表1 交换机簇划分算法中的符号表示
算法流程:
(1)若其余正常工作控制器的总剩余负载小于故障控制器下交换机数量,则新增控制器,否则转到(2)。
(2)使用DIJKSTRA(迪杰斯特拉)算法计算故障控制器下交换机到其余各台控制器的最小跳数,并将这些跳数存储到每台交换机对应的一个集合中(这一步是离线操作,离线操作可以节约大量时间,当网络拓扑发生变化后,控制器会重新计算)。
(3)对每台交换机集合中的数据按照跳数从小到大排序。
(4)对所有交换机集合按照集合中的最小跳数从小到大排序。
(6)若S中的交换机个数为1,则找出最小跳数对应的控制器Ci并判断Ri是否大于0,若大于0,则将S0托管到Ci下并更新Ri,同时将S0标记为已托管。否则,将S0的最小跳数从S0的跳数集合中移除,并转到(4)。若S中交换机个数大于1,则转到(7)。
(7)将S中的交换机按照跳数集合中最小跳数对应的控制器进行分组,分组结果为SS。对SS中的元素进行如下操作:若SSi中交换机对应控制器Ci的剩余容量Ri大于等于SSi中交换机的数量,则将SSi中的交换机托管到Ci下并更新Ri,同时将SSi中的交换机标记为已托管,否则转到(8)。
(8)比较SSi中交换机对应跳数集合中的下一个最小跳数,找出拥有下一个最小跳数的交换机SSij及对应的控制器Cj,记下一个最小跳数为h。顺序遍历其余未被托管的交换机中是否存在某个交换机Sk到控制器Cj的最小跳数小于h,若存在则将Sk托管到Cj下,更新Rj,将Sk标记为已托管,重复此过程直到遍历结束或Rj为0。若此时Rj仍大于0,则将SSij托管到Cj下,更新Rj,将SSij标记为已托管。否则,按照刚开始的思路重复执行。上述过程每次结束后,若SSi中的交换机数量小于等于Ri,则将SSi中的交换机托管到Ci下。若S Si中未被托管交换机数量仍大于Ri,则转到(8)直到SSi中的交换机全部被托管或SSi中未被托管的交换机数量不大于Ri。
(9)若交换机集合SS中仍有未处理的交换机,则转到(7),否则转到(5)直到所有的交换机都被托管。
下面举个例子来说明。
图3展示了4台控制器管理的SDN带内通信网络。C1控制 S10~S18,C2控制 S20~S28,C3控制 S30~S38,C4控制 S40~S48。
图3 四个控制器管理的SDN带内通信网络
假设控制器C1发生故障,从图3可以看出,整体上控制器C2、C3、C4下属交换机与控制器C1之间的延迟约为 C2≈C4<C3。现假设控制器 C2、C3、C4剩余容量分别为3、6、9。根据延迟优先原则,首先计算出控制器C1下各台交换机距离其余正常工作控制器的跳数,图中所示可以计算如下:
S10{5C2,10C3,7C4},S11{4C2,9C3,6C4},S12{3C2,8C3,7C4},S13{6C2,9C3,6C4},S14{5C2,8C3,5C4},S15{4C2,7C3,6C4},S16{7C2,8C3,5C4},S17{6C2,7C3,4C4},S18{5C2,6C3,5C4}。其中,S10{5C2,10C3,7C4}表示交换机S10距离C2控制器5跳,距离C3控制器10跳,距离C4控制器7跳。
下面对各个交换机集合中的数据按照跳数从小到大进行排序,结果为S10{5C2,7C4,10C3},S11{4C2,6C4,9C3},S12{3C2,7C4,8C3},S13{6C2,6C4,9C3},S14{5C2,5C4,8C3},S15{4C2,6C4,7C3},S16{5C4,7C2,8C3},S17{4C4,6C2,7C3},S18{5C2,5C4,6C3}。
接下来对所有交换机集合按照集合中的最小跳数从小到大进行排序,结果为S12{3C2,7C4,8C3},S11{4C2,6C4,9C3},S15{4C2,6C4,7C3},S17{4C4,6C2,7C3},S10{5C2,7C4,10C3},S14{5C2,5C4,8C3},S16{5C4,7C2,8C3},S18{5C2,5C4,6C3},S13{6C2,6C4,9C3}。
根据上面的排序结果,可以将交换机S12、S11和S15托管到控制器C2下,其余交换机都托管到控制器C4下,则划分出来的交换机簇为{C2{S12,S11,S15},C4{S16,S13,S17,S10,S14,S18}}。
这里再讨论一种情况,假设控制器C2、C3、C4剩余容量分别为2、9、2。根据之前排序的结果,将交换机S12托管到控制器C2下,之后R2为1。交换机S11、S15、S17的最小跳数都为4,因为R4等于2,所以交换机S17可以直接连接到C4下,之后R4为1。因为R2为1,所以交换机S11和S15不能同时托管到控制器C2下。接下来考虑交换机S11和S15的下一个最小跳数。S11和S15的次小跳数都为6且对应的控制器都是C4,而R4为1,此时需要查询是否存在某台交换机与控制器C4之间的最小跳数小于6,发现S16与控制器C4之间的最小跳数为5,所以将交换机S16托管到控制器C4下,之后R4为0。同理,接下来S11的下一个最小跳数为9,S15的下一个最小跳数为7,所以将交换机S11托管到控制器C2下,交换机S15托管到控制器C3下。
按照上述思路,可得出{C2{S12,S11},C3{S18,S15,S14,S13,S10},C4{S17,S16}}这样一种最优化划分方案。
交换机簇划分完成后,下一步就需要将划分出的交换机簇托管到相应的控制器下。
SDN控制器与交换机的通信是由交换机主动发起的,而划分出的交换机簇中的交换机并不知道该向哪台控制器发起连接请求,所以这就需要交换机主动获取或者被告知即将连接的新控制器的相关信息。
本文构建带内通信使用了DHCP客户端-服务器模式,这一通信模式可以用来实现上述应用。交换机重托管的思想就是重置交换机的IP地址,之后交换机中的DHCP客户端会和初始建立带内通信网络时那样向DHCP服务器发送DHCP请求报文,最后实现交换机与指定控制器建立连接。文献[15]中提到使用DHCP建立带内通信网络的速度较慢,然而此时的交换机托管速度会快得多,这是因为网络中绝大部分的交换机都与控制器建立了OpenFlow会话,同时,本文的DHCP服务器处于单独的进程中,一个控制域拥有一个DHCP服务器,所以DHCP报文的下一跳选择更多,被转发的几率也就大大提高。因此,几乎所有的DHCP请求报文都能够被直接转发给DHCP服务器,很少会出现带内通信建立时的DHCP请求报文丢弃行为。
本文使用Mininet作为仿真工具,在Floodlight控制器上进行增量开发,实现本文所提架构。
实验选用网格状拓扑(如图3所示),网格状拓扑易于扩展,在进行网络仿真时,网格状拓扑可以快速扩展到大规模网络,可以方便地对本文所提架构进行测试。
本文选择两种实验方案,一种是所有的控制器和仿真系统都安装在同一台Ubuntu14.04机器上,这台机器搭载Intel Core i7-6700 CPU,拥有16 GB内存;另一种是在三台云主机上部署控制器进行实验,三台云主机的配置相同,均为1核2 GB内存。第二种配置方案主要是为了模拟实际环境下控制器间的通信延迟。
控制器故障检测模块。控制器故障检测使用BFD的思想,大量实验表明,控制器故障检测的实时性和准确率与BFD消息的时间间隔有着很强的关联性。实验假设控制器间BFD链路通道稳定的情况下,随机停掉其中一台控制器,并重复运行50次统计平均检测时间。
图4展示了两种实验配置方案下选择不同BFD时间间隔对应的控制器平均故障检测时间。从图中可以看出,BFD消息发送时间间隔不同,对应的故障检测时间也会不同。总的来说,故障检测时间随着BFD消息时间间隔的增大而变长。图中显示若发生故障,则实际用来检测故障的时间很短。配置方案一的故障检测时间基本维持在4 ms以内,而配置方案二的故障检测时间会略长,大致在17 ms左右,比配置方案一多耗时约13 ms,这是由于控制器部署在同一台机器上时,控制器间的时延较小,而控制器部署在不同机器上时,控制器间的时延较大。通过PING命令可以测量出配置方案二不同机器之间的延迟约为12 ms,这也验证了实验结果的合理性。同时,这也说明实际环境下故障检测的时间预计都是在可接受的范围内。由于系统实际用来检测故障的时间很短,所以可以根据具体的应用场景选择BFD时间间隔。
图4 故障检测时间
综合下来无论是控制器处于同一机器环境下还是处于多台机器环境下,BFD时间间隔在10 ms至20 ms之间将是一个比较好的选择,既能保证故障检测的实时性,同时也可以达到几乎100%的故障检测率。
交换机簇划分。交换机簇划分有很多的偏好选择,不同的偏好对于故障恢复时间和恢复后的网络性能都有很大的影响。本文选择延迟优先,在延迟相同的情况下优先选择剩余容量大的控制器进行托管。假设网络中其余控制器总剩余容量为100,这些剩余容量随机分配到其余正常工作的控制器上并重复进行50次统计平均划分时间。
图5展示了故障控制器下不同交换机数量时选择不同偏好对应交换机簇划分所需时间。从图中可以看出,延迟优先以及控制器剩余容量优先这两种偏好与本文选择的延迟优先剩余容量次之的方式所需划分时间基本相当。由于本文选用的延迟优先剩余容量次之采用了双重偏好,所以耗时比其他两种略长,不过都是可以忽略不计的。此外,当控制器剩余总容量小于故障控制器下交换机数量时,系统会新增一个新的控制器,实验表明这一过程比较耗时,基本上维持在百毫秒的级别,但是新增控制器后便不再需要进行交换机簇划分,而是将故障控制器下的交换机全部挂载到新的控制器下。
图5 交换机簇划分所需时间
为了测试不同划分偏好对于故障恢复后网络性能的影响,本文从故障恢复后整体网络延迟(全网环境下交换机到所属控制器平均跳数)和各个控制器下交换机个数标准差这两个方面进行衡量。本文实验选用的是网格状网络,网络初始阶段各个控制器下交换机数量是相等的。选择故障恢复后各个控制器下交换机个数标准差这一指标,可以有效衡量故障恢复后各个控制器间的负载均衡以及是否可能出现控制器级联失效。假设网络中的故障控制器为C1,其余控制器总剩余容量为102(其余3个正常工作控制器都各自拥有34的剩余容量)。
图6展示了故障控制器下不同交换机数量时选择不同偏好对应网络恢复后的全网平均跳数。图7展示了故障控制器下不同交换机数量时选择不同偏好对应网络恢复后控制器下交换机个数标准差。
图6 交换机簇划分前后全网平均跳数
图7 交换机簇划分后各个控制器下交换机个数标准差
从图6中可以看出,本文所选延迟优先剩余容量次之的划分偏好对应划分后的全网平均跳数介于延迟优先和剩余容量优先这两种偏好对应结果之间,略逊于延迟优先对应的结果。然而从图7中可以看出,这一点点延迟上的逊色却换来了更加均衡的控制器负载,可以有效避免控制器级联失效。
交换机重托管。图8展示了交换机与新控制器间跳数对重托管时延的影响。从图8中可以看出,跳数对于时延的影响很小。若网络中其余交换机都与相应控制器建立了OpenFlow会话,那么当某台交换机需要连接到指定控制器时,其DHCP请求报文会被快速转发到DHCP服务器,这就类似于数据包的转发过程,速度会特别快。
图8 交换机重托管时延
容错机制对比。为了验证本文提出的带内通信场景下多控制器容错架构的有效性,本文选取目前广泛使用的多控制器主从容错机制进行实验对比,主要考虑的是容错所需控制器数量、控制器故障后的恢复时间以及存储拓扑信息所需空间大小。
实验均在相同条件下进行部署模拟。主从容错机制需要选择合适数量的从控制器,本文对比实验中选用的从控制器数量与主控制器数量相同,即主从容错机制使用的控制器数量是本文所提架构的2倍。
表2展示了两种容错方式下的故障恢复时间。从表2中可以看出,故障控制域下交换机数量对故障恢复时间有着较大影响。若故障控制域下存在大量交换机,交换机发送的DHCP报文需要等待邻居节点与控制器建立OpenFlow会话后才能被转发,部分DHCP请求报文会被丢弃,重托管速度较慢。主从机制下交换机一直与从控制器保持OpenFlow会话,所以切换速度相对较快。然而,主从控制器架构所需控制器数量最少是本文所提架构的两倍。文献[7,9]中提到为了保持高容错性,主从FT(Fault Tolerant)算法所需从控制器数量往往是主控制器数量的两倍甚至更多。
表2 故障恢复时间 ms
主从机制下,每个控制域对应的主从控制器都需要维护一份独立的网络拓扑,而本文所提架构只需维护一份全网拓扑信息,所需存储空间自然会低得多。
实验证明本文提出的带内通信场景下多控制器容错架构可以大大减少SDN网络中的控制器数量,显著提高控制器资源利用率,很好地提高网络服务质量。
本文研究并设计了一种带内通信场景下平面式的多控制器容错架构,使用单控制器控制单个自治域,与目前广泛使用的控制器主从协作方式相比,在相同的实验条件下,以30%左右的故障恢复时间为代价,将控制器的资源利用率至少提高了200%,并且随着网络规模的扩大,本文所提架构的优势将变得愈加明显。
未来考虑在交换机簇划分时添加一个负载均衡模块,以根据控制器的实际负载提供动态规划。同时,根据控制器的实时负载,可以预判性地新增控制器,这样可以大大缩短控制器故障恢复时间。