note:这里主要记录我对IO虚拟化的理解,希望这篇文章对想了解虚拟化IO的同学有点帮助。这是我在看论文[vale,a switched ethernet for virtual machines]的时候总结的有关io虚拟化技术,概括性的和思考结果比較多。细节内容比較少。

我们如果如今大部分的计算机服务都迁移到了虚拟化环境中(事实上是事实)。带来的主要优点是资源共享并降低开销。

虚拟机也是须要訪问外围设备的,比方磁盘和网络。

即使在非虚拟化环境中訪问网络也是非常有挑战性的技术(应用程序使用系统调用),所以到了虚拟机这一层面,訪问网络,要达到硬件的速度非常困难。所以要怎么处理虚拟化I/O呢?主要有三种方法来虚拟化I/O。各自是全虚拟化,半虚拟化以及Direct I/O accsss。他们在处理guest和hypervisor通信以及hypervisor和host架构上分别採用了不同的处理方式。


全虚拟化

        最简单的方法就是给guest操作系统一个虚拟网络接口。然后由hypervisor拦截下虚拟机的Accesses (to critical resources)。而且hypervisor中用一个模块来模拟网卡硬件的功能(emulator)。这样的方法非常直观易懂,在历史上来说,这也是第一种I/O虚拟化方式,最開始由VMware 和QEMU採纳。

(这仅仅是最主要的解释了,至于说怎么写一个模拟器?我没写过。感兴趣的能够google~~)



        当hypervisor截取到guest的packet之后。假设要发送到网络上(这里能够既包含内部网络也包含外部网络),就须要使用host的网络栈了,比方TCP/UDP sockets(封装)。


        全虚拟化看起来直观易懂。非常easy使用,环境配置简单。仅仅是模拟的开销会非常大,一般来说。那是一个非常庞大的系统(所以写个模拟器工作量非常大……)。

半虚拟化

上面讲了全虚拟化。和全虚拟化相对的就是半虚拟化,半虚拟化的意思就是说guest操作系统可以感知到自己是虚拟机。

那么对于I/O系统来说,仅仅要guest的驱动可以和hypervisor进行沟通,。

不同的hypervisor使用不同的技术来实现半虚拟化。比方说xen。就是通过事件通道,授权表以及共享内存的机制来使得虚拟机中的驱动(前端驱动)和host中的驱动(后端驱动)来通信。

最后由设备域的标准linux内核来处理IO。



        另外kvm使用virtio。和xen的半虚拟化网络驱动原理几乎相同。

还有就是比方VMware的Guest tools,和xen的半虚拟化机制应该也非常相似,一通百通。

那么半虚拟化相对全虚拟化有什么优点?尽管和全虚拟化一样,都是使用软件完毕虚拟化工作。可是因为机制不一样,这样的方式因为不像模拟器那么复杂。软件处理起来不至于那么慢,所以有更高的带宽,更好的性能。可是还是存在性能问题,仍然达不到硬件的速度。



break
到此为止,提一个问题,为什么软件实现的性能不好?比方达不到有硬件支持(以下会提到)的速度?难道硬件支持就一定快,软件就一定慢?能不能设计出一种软件比有硬件支持的更快呢?(这个问题边想边继续看吧,到文章的结尾处我会给出我的认识)

Direct I/O Access

前面的两种方式,不管是模拟还是沟通方式,都须要guest和hypervisor的交互,而这里要讲的这样的方式是为了避免guest和hypervisor的沟通,使得guest能够直接将流量发到硬件上面。

看起来非常奇怪是不是,可是这样的方式应该怎么做?host或hypervisor怎么将网卡的控制权转移给host?有没有一个网卡能够转移给多个虚拟机使用呢?(这仅仅是一点提示问题,你可能还能够想出很多其它的问题来。)为了解决这些问题,须要一套机制支持,这里主要表如今硬件的支持。



首先考虑一个简单的情形,将一个NIC分配给一个guest(host和其它guest都不能看到这个NIC),如今的方法是通过pci passthrough技术。

如今一般一个网卡是一个pci设备。当系统识别这个网卡后,在内存会分配一块相应的pci配置空间,为了支持pci passthrough。现代的cpu架构会提供一种机制将这块pci物理地址映射到guest操作系统的内存。比方intel的vt-d和amd的iommu(cpu对虚拟化的硬件支持)。然后通过软件比方,pci passthrough命令来使用一次这块硬件,实现映射的功能。可是是不是一定要用到CPU的虚拟化支持呢,我想仅仅要你牛逼,写个有映射功能和隔离机制的软件也能够做到相同的功能吧。

另外假设要将一个NIC分配给多个guest。我想就是SR-IOV技术了。就是将一个网卡虚拟出多个VF,然后将每一个VF通过pci passthrough分配给不同的guest。

这里除了cpu的虚拟化支持,比方intel的vt-d,也还须要网卡本身的虚拟化技术,须要虚拟出多个vf功能。以及邮箱机制等功能(我做不了硬件的虚拟化,仅仅讲功能需求)。



关于这三种方式,我的了解程度都不一样。尽管三种我都用过。全虚拟化的方式採用模拟器(写一个模拟器的难度太大,没有尝试过写,也没有读过代码);xen的半虚拟化机制看过源代码,调用它的api实现过一些功能。至于pci passthrough我以前使用82599网卡的SRIOV功能,将网卡虚拟化为多个vf,再将多个vf分配给多个虚拟机进行实验。这样虚拟机的带宽确实非常高。





break:对于那个问题。私以为软件执行的速度不一定比纯硬件慢。软件归根结底也是表如今cpu上执行(推荐看看csapp《深入理解计算机系统》)。相同一个功能,软件的不同设计导致执行的速度非常可能不同。有的快,有的慢。当软件的设计非常完美的时候,这个时候影响软件执行的瓶颈就是CPU频率和内存带宽。对于实现交换机功能这种软件。假设这个交换机设计合理,基本上能达到cpu的频率。假设相应的物理网卡的带宽小于这个值,那么这个软件交换机相对于物理网卡而言。设计非常棒。我们会认为虚拟机的网络IO性能真的是相当棒。

另外假设网卡带宽大于cpu主频或内存带宽的时候,此时假设交换机软件也设计相当棒的时候,瓶颈就表如今cpu主频上。





p.s.因为比較懒,没有绘图。希望不影响理解,有些观点没有展开,细节讲的过少。有些没有重点。会慢慢改动补充,欢迎评论与建议:-I 

I/O虚拟化的更多相关文章

  1. [原] KVM 虚拟化原理探究(1)— overview

    KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...

  2. BIOS中未启用虚拟化支持系列~~例如:因此无法安装Hyper-V

    异常处理汇总-服务器系列:http://www.cnblogs.com/dunitian/p/4522983.html 一般都是启动一下CUP虚拟化就可以了 比如华硕的:

  3. [原] KVM 虚拟化原理探究 —— 目录

    KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...

  4. [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化

    KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...

  5. [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化

    KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...

  6. [原] KVM 虚拟化原理探究(4)— 内存虚拟化

    KVM 虚拟化原理探究(4)- 内存虚拟化 标签(空格分隔): KVM 内存虚拟化简介 前一章介绍了CPU虚拟化的内容,这一章介绍一下KVM的内存虚拟化原理.可以说内存是除了CPU外最重要的组件,Gu ...

  7. [原] KVM 虚拟化原理探究(3)— CPU 虚拟化

    KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...

  8. [原] KVM 虚拟化原理探究(2)— QEMU启动过程

    KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...

  9. Linux虚拟化学习笔记<一>

    关于虚拟化,原理的东西是非常复杂的,要想完全理解,没有足够的耐心是不不能完全学透这部分内容的.那下面我主要以资源汇总的形式把一些资料罗列出来,帮助大家快速理解虚拟化,快速使用和配置. 为什么要虚拟化: ...

  10. ITTC数据挖掘平台介绍(七)强化的数据库, 虚拟化,脚本编辑器

    一. 前言 好久没有更新博客了,最近一直在忙着找工作,目前差不多尘埃落定.特别期待而且准备的都很少能成功,反而是没怎么在意的最终反而能拿到,真是神一样的人生. 言归正传,一直以来,数据挖掘系统的数据类 ...

随机推荐

  1. 程序员必知的LinuxShell命令

    程序员必知的LinuxShell命令 grep (Globle Regular Expression Print全局正则表达式) 命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的 ...

  2. SQL SERVER 执行计划各字段注释

    SET SHOWPLAN_ALL使 Microsoft® SQL Server™ 不执行 Transact-SQL 语句.相反,SQL Server 返回有关语句执行方式和语句预计所需资源的详细信息. ...

  3. c3p0参数详解

    <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数.Default: 3 --> <property name="acquireIncrement"& ...

  4. axios方法get及post代码示例

    show: function(){ //get方式 //赋值给变量self var self = this; var url = "hotcity.json"; axios.get ...

  5. tp系统常量

    ThinkPHP的公共入口文件里定义了系统常量 RUNTIME_PATH----系统运行时目录 LIB_PATH-----------系统核心类库目录 CORE_PATH--------Think类库 ...

  6. ThinkPHP---辅助方法

    [三]Tp常见的辅助方法 原生SQL语句里除了目前所使用的基本操作增删改查,还有类似于group.where.order.limit等这样的字句. ThinkPHP封装了相应的子句方法:封装的方法都在 ...

  7. Java基本数据类型、包装类与String类之间的转换

    一.基本数据类型与包装类之间的转换: import org.junit.Test; public class MainTest { /** * 基本数据类型与包装类之间的转换 */ @Test pub ...

  8. Python学习-字符串的基本知识

    字符串的基本知识 根据所展示形式的不同,字符串也可以分为两类 原始字符串: 使用单引号包括:‘liuwen’ 使用双引号包括:"liuwen" 使用3个单引号包括 :'''liuw ...

  9. Python学习第二阶段,Day2,import导入模块方法和内部原理

    怎样导入模块和导入包?? 1.模块定义:代码越来越多的时候,所有代码放在一个py文件无法维护.而将代码拆分成多个py文件,同一个名字的变量互不影响,模块本质上是一个.py文件或者".py&q ...

  10. Liunx学习笔记(三) 文件权限

    一.文件权限 1.查看文件权限 (1)文件权限 在 Linux 中对于文件有四种访问权限,列举如下: 可读取:r,Readable 可写入:w,Writable 可执行:x,Execute 无权限:- ...