前不久一个研究SDN的博士生和博主抱怨说:现在开源的SDN控制器性能都好差啊,每秒钟2K个新流就会提示packet-in太多,停止工作。博主问他是如何定义一个流的,他说用TCP 5 tuple。博主又问他是怎么产生那么密集的packet-in的,他说是用一台服务器直接向SDN控制器发packet-in。博主接着问那台服务器和SDN控制器的配置,他说服务器是8核,SDN控制器是4核。博主没有继续问更多的问题,而是在想:是什么原因让人们设计出这样的实验?如果这个实验的数据正确,那么又意味着什么呢?
直到今天,不少人对SDN和OpenFlow都抱有两个误解。第一,采用OpenFlow的SDN控制器是在per flow的更新流表。第二,每个flow有自己的生命周期,控制器只为active flow更新流表,其余的表项则会被删除。之所以是误解,是因为任何一个版本的OpenFlow标准都没有说per flow的更新,更没有说只为active flow更新流表。事实上,OpenFlow仅仅定义了控制器和交换机之间的一种接口,根本没提要如何使用这些接口。
一个非常有趣的问题是:人们为什么会对SDN和OpenFlow有以上的误解?首先,OpenFlow这个名字非常糟糕,它本身似乎在暗示人们这个协议是per flow的,但事实根本不是这样。如果有机会为这个协议重新起名,OpenTable会更合适,因为它本质上是开放了交换机里的各种流表,SDN控制器可以编辑这些流表。
另外OpenFlow协议本身需要交换机采取match+action的方式进行转发,而不是传统的2层+3层+TCAM的转发方式。这个转发方式的转变是造成人们产生以上误解的一个重要原因。在早期的OpenFlow实践中,人们发现在现有的硬件ASIC上很难采取wildcard match+action的转发方式。最立竿见影的在硬件上部署SDN的方案是仅仅利用ASIC上的TCAM表,因为这张表支持wildcard match,支持drop,forward,broadcast,copy to CPU等多种action。TCAM表与OpenFlow协议的转发方式有着最直接的对应的关系。于是市场上就出现了早期的支持OpenFlow的交换机:它们支持OpenFlow协议,将OpenFlow的每一个Flow Modification Message转变为相应的TCAM表项。这对SDN和OpenFlow的普及有非常积极的影响。但它有一个问题:TCAM实在是有些贵,导致即便到了今天,最成熟的ASIC也只支持3K-4K的TCAM表项,这么小的表最多只能做做demo,规模部署根本是天方夜谭。天才的SDN先驱们想到一个办法来克服TCAM表过小的问题,那就是采用reactive的方式来编写TCAM。通俗来说就是:只保存那些active流的表项,那些不再active的表项都会因为超时而被删除。具体的做法是:对于每个新流的第一个包,交换机不知道该如何处理,于是交换机会向控制器发送一个packet-in,控制器收到这个packet-in之后,计算路径并通过Flow_Mod告诉各个交换机如何转发这个新流。如果与这个流相关的各个表项在一段时间内没有见到新包,这个流被认为已经结束,相关的表项被从TCAM表中清除。这个reactive的办法确实从一定程度上解决了TCAM表过小的问题。不过SDN的后继者们却忘记了TCAM过小是因,reactive是果。如果一个初学者刚刚读完OpenFlow spec,他可能会想当然的以为SDN by design就是reactive的,而忽视了去探寻reactive的原因。事实上OpenFlow spec和是不是reactive没有任何关系。
历史讲到这里,我们再返回头看看文章开始的那个实验。不难发现,实验设计者在潜意识中就想当然的认为OpenFlow是per flow的并且是reactive的!带着这样的假设设计实验本身就不科学。很遗憾,这两个不正确的假设仍然在不少SDN研究者的脑子里根深蒂固,于是在实验中,他们会依靠产生不同的TCP 5 tuple来模拟大量新流。在工业界中,这样的误解会少很多,因为在设计任何一个SDN产品之前,人们会评估设计的瓶颈:如果每一个新的TCP 5 tuple都会引起packet-in的话,SDN控制器肯定会成为系统瓶颈,这种系统设计会被毫无疑问的在第一时间抛弃。我们从来没有听说过哪个厂商公布他们的控制器处理packet-in的能力,不是因为这是他们的机密,而是因为系统的稳定程度在设计上就与新流产生的速度无关,根本就没有人关心这个测试结果。
分析到这里,我们已经知道reactive的模式虽然在一定程度上解决了由于TCAM过小带来的问题,但也让SDN控制器成为了系统的瓶颈。如果文章最初的那个实验数据是正确的,那么reactive的SDN控制器根本无法控制大规模的网络和流量。在这种情况下,也许会有人建议去研究如何提高SDN控制器的性能,使其不再成为瓶颈。但这样便是典型的舍本逐末,解决一个本来可以不存在的问题。试想,如果TCAM足够大,人们还会采用reactive的方式来设计SDN系统吗?显然不会。与之相对应,proactive会成为一个更合理的方式,即:在新流还没有来到之前,就把相应的表项编辑好,这样,新流出现就不会引起packet-in了。
看到这里,也许有朋友会问:1) SDN控制器怎么知道会有什么流产生?2) TCAM只有那么大,如果在新流产生之前就主动的编辑好流表,怎么装得下?
其实这两个问题都是伪问题,之所以把它们列在这里是为了让文章的逻辑保持连贯。提出问题1的人仍然在局限在SDN是per flow的误解里面。除非人为的调度,SDN控制器永远不会聪明到能够猜出会有什么新流产生。但是没关系,问题的关键不在于知道会有什么新流产生,而在于知道各个设备在哪里。互联网发展到今天,从来都不是per flow转发,而是per device转发!传统的二层交换机需要学习(vlan, mac)到port的映射,其实就是在学习各个device在哪里。只要知道mac1在port1,不管什么flow,只要是去mac1的就转发到port1。同样的逻辑可以非常自然的推广到SDN里面,控制器可以学习各个device在哪里,并且告知网络中的交换机们如何达到各个设备。学习的渠道可以很多,比如ARP,LLDP,LACP等等。学习mac不过瘾,还可以学IP。总之,如果把per flow的mental model转变为per device的mental model,SDN系统设计的一切都会变得自然很多。
问题2是一个更大的伪问题。正如在之前的段落中介绍的那样,SDN的先驱们非常理想化的设计了OpenFlow协议,后来发现只有昂贵TCAM才能够和OpenFlow协议产生比较直接的对应,于是OpenFlow和TCAM才成为难兄难弟,总是成双成对的出现。问题是:我们的目的是用集中控制的方式简化网络管理,为什么一定要用TCAM?又为什么一定要用OpenFlow?这才触及到问题的本质。
博主的答案是:我们不一定要用TCAM,我们也不一定要用OpenFlow。一切都是design choice,只有不同的选择,没有最好的选择。比较有代表性的是学院派和工业界的选择。学院派以Nick McKeown教授为代表,主张彻底重新设计硬件交换芯片[link],使其完全适应OpenFlow协议。工业界的做法没有那么激进:cisco设计了ACI和OpFlex,让协议适应硬件ASIC;BigSwitch沿用了OpenFlow,但是只使用TCAM存放复杂的规则,而用L2和L3的表来存放一般的转发规则,在最大程度上规避了TCAM大小的局限。在多方的共同努力之下,SDN和OpenFlow设计之初的种种限制正在成为历史,reactive的系统设计也完成了它的历史使命。现在实用的proactive的SDN系统大概长这个样子:1) SDN控制器不断学习网络中的各种设备,包括交换机,链路,服务器,虚拟机等等,2) 管理员通过某种语言配置业务关系,比如multi-tier application和service chaining。3) SDN控制器翻译用户配置并且通过南向接口编辑交换机中的L2,L3表,这里的表项不是per flow的,而是per device的。SDN控制器同样通过南向接口将租户的业务逻辑转变为TCAM表项,这里的表项更复杂,可能需要匹配source+destination以及L4的某些字段。
采用proactive的方式设计SDN系统还有一个更大的好处是它极大的简化了High Availability(HA)的设计,让SDN控制器不再成为整个系统的单点故障(single point of failure)。以后的文章会对这一点进行深入讨论。
讲了这么多,博主只是在传达一个信息:采用reactive的方式设计SDN系统是有历史原因的。现在这些原因都已经不再存在,proactive的SDN系统设计已经成为主流。