根据OpenVSwitch的转发流程,OpenVSwitch需要维护三个数据:Microflow cache,Megaflow cache和OpenFlow Table。前面介绍的是这三个数据之间的关系以及在转发过程中的作用。这部分来看看OpenVSwitch如何管理这三组数据。
OpenFlow Table
从OpenVSwitch的角度来说,OpenFlow的管理是简单的。因为OpenFlow是由SDN controller管理,OpenVSwitch只是提供了OpenFlow增删改查的接口。
Megaflow Cache
前面介绍了Megaflow cache的生成过程。但是生成了之后,还面临着更新和删除。对于更新来说,如果SDN controller更新了OpenFlow Table,那么同一个网络包经过OpenFlow pipeline的处理,得出来的datapath actions可能发生变化,对应的megaflow cache也需要更新。理想情况下,OpenVSwitch能够对于特定的事件,的确定哪些megaflow需要更新。这在有些场景容易达成,比如说通过匹配MAC地址转发到固定的端口(二层交换机特性),当发现MAC地址迁移到了其他的端口,那么只需要更新匹配了对应MAC地址的megaflow cache就可以。但是由于OpenFlow的通用性,大部分更新的场景不能容易的识别对应的megaflow cache。通常情况下,如果在一个OpenFlow Table中增加了一条OpenFlow规则,任何通过这个OpenFlow Table生成的,且用到了优先级更低的OpenFlow规则的megaflow cache都可能表现出不同的行为,都有可能需要更新。如果考虑到OpenFlow Tables组成的pipeline,这个问题将更加的复杂。
早期的OpenVSwitch将megaflow cache分为两组:组cache,当有OpenFlow规则变化时,所有的cache内容都送回到ovs-vswitchd进行重新计算,以确保它们是新的。第二组cache,通过tag标识变化,将变化与megaflow cache关联起来。例如将MAC地址与magaflow cache联系起来,当MAC发生变化时,通过tag查找到相应的magaflow cache,并更新它。随着SDN应用的越来越复杂,tag也越来越复杂,终,在OpenVSwitch 2.0,tag标识被废弃,只剩下组cache。现在,当有任何变化的时候,整个megaflow cache都会被重新计算。
这看起来是非常低效的,但是好在现在的服务器都是多核,且性能在不断提升。在OpenVSwitch 2.0中,ovs-vswitchd被设计成了多线程,可以充分利用多核CPU。并且多线程的设计可以避免重新计算megaflow cache时,阻塞新的megaflow cache下发。新的megaflow cache下发直接决定了网络连接的性能,所以不能阻塞这个过程。通过把更新megaflow cache和下发新的megaflow cache的程序被放到不同的线程,可以让两个流程谁也不阻塞谁。
默认情况下,重新计算(revalidator)的线程数是:CPU核数/4 + 1。下发新的megaflow cache(handler)的线程数是:CPU核数 - revalidators占用的核数,这样可以充分利用主机的CPU。在一个数千虚拟机规模的环境中,ovs-vswitchd的CPU消耗在10%左右,连一个核的CPU都消耗不了。下面是一个48U主机的OpenVSwitch线程数分配值。
# ovs-appctl memory/show
handlers:35 ofconns:2 ports:6 revalidators:13 rules:735
通过这样的设计,使得OpenVSwitch可以管理大量的megaflow cache,默认情况下,megaflow cache的数量是20万条。在实际使用中,这个数值是足够使用的。
同时OpenVSwitch还会定期的获取megaflow cache的统计值(大概1秒一次),以获得kernel datapath处理的packets数和bytes数。在OpenFlow规则中看到的packets数和bytes数的统计,就是这个定期同步任务的结果。获取megaflow cache统计值的核心目的是为了确定哪些megaflow cache一段时间没有使用,必须被删除。因为首先megaflow cache的规模是有限的,其次megaflow cache越小,转发性能也越好,所以需要有一个老化的过程。默认情况下,OpenVSwitch设置给megaflow cache的老化时间是10秒。如果megaflow cache已经超过了配置的大值,这个老化时间也会相应的减少。
Microflow cache
对于新版本的OpenVSwitch,Mircoflow cache只是到megaflow cache中各个Hash table的一个缓存,因此其时效性不是那么的重要,维护起来也更加的简单。
首先,microflow cache有一个固定的大小,如果microflow cache满了就用新的规则随机替换旧的规则,所以,也不需要老化功能;其次,如果因为更新,使得megaflow cache发生变化,microflow cache不会主动的更新,只有当下一个网络包到达microflow cache时,因为对应不到原来的megaflow cache中的Hash table,会重新的在megaflow cache Hash table中查找,进而重新定位到相应的Hash table。因此,microflow的管理也是被动的。
后,回顾一下OpenVSwitch的实现,它从来不是一个局部优的解决方案,它的设计哲学是以一个相对较优的方案满足所有的应用场景。