我在上一篇文章也提到过,对于全虚拟化和半虚拟化,需要分配给虚拟机一个虚拟网络接口,这些就需要一个虚拟交换机vswitch(可以和hypervisor一同使用),从而将虚拟网络接口的数据包从物理接口转发出去。但是在复杂的系统中,这个虚拟交换机的性能往往并不好。开源项目netmap[1]做了一个高性能网络框架,并且同样使用这个原理完成了高性能虚拟网络交换机vale的设计[2],在多种场景下Vale测量的性能[3]也非常好。
note:由于项目需要,我常常思考一个高性能的虚拟交换机应该怎么做。从netmap和Vale这些设计和论述中我受益匪浅,我把我浅薄的理解记录并分享,希望也能给大家帮助。
Netmap
由于官网上介绍的已经很详细了,我这里简单描述。
Netmap 框架是一个用于网络硬件和应用程序的高性能通信的通道,基于共享内存机制。可以将Netmap和Linux网络编程[4]需要用到的系统调用(read,write)进行对比,他们所要完成的功能是类似的。相对于系统调用,netmap的主要特点在于:buffer分配和数据复制的开销没有了,这是因为使用了共享内存并且提前分配了buffer。
那么问题是程序是怎么使用netmap机制的呢?通过在程序里面打开一个特殊的文件/dev/netmap,获得一个文件描述符,并且使用ioctl()系统调用选择一个设备,然后应该可以获取一块region,然后使用mmap()将文件描述符对应的文件对应到那个region。
netmap是作为内核模块来实施的,主要包括两部分。一是功能,实现了那些open,close,ioctl,poll/select等基本功能。另外一个是与设备相关的部分,netmap延伸了驱动的功能,负责传输数据(send/receive)(只要传输描述符ring的元数据)。因为做到了zero copy,所以能够达到高性能。
send(read)系统调用过程如下:
netmap send(read)的工作原理如下:
VALE原理
Netmap机制是实现VALE(Virtual local ethernet)高性能的核心所在。
VALE其实就是一个虚拟本地以太网交换机。它给它的每个 用户(hypervisor或者process)提供一个虚拟的网络接口(可以通过netmap的api来访问)。核心工作还是在netmap backend端,需要在后端增加交换机的逻辑,比如转发学习逻辑。然后进一步优化。
VALE作用于vSwitch的拓扑如下:
到现在为止Netmap已经列入了FreeBSD的内核,但是在linux下面使用还是需要编译这个模块并加载。
参考资料
[1]http://info.iet.unipi.it/~luigi/netmap/
[2]http://info.iet.unipi.it/~luigi/vale/
[3]http://info.iet.unipi.it/~luigi/papers/20121026-vale.pdf
[4]《Unix 网络编程》
p.s.因为只看过Vale的那篇论文,然后稍微浏览了下网页,认识不深刻,写的过于简单。想进一步了解的去官网应该可以学到很多~~
VALE作用于vSwitch的拓扑如下