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. JavaScript中逻辑运算符的使用

    逻辑运算符用于对一个或多个布尔值进行逻辑运算.在JavaScript中有3个逻辑运算符,如下表所示. 运算符 描述 示例 && 逻辑与 a && b  //当a和b都为 ...

  2. nodejs连接数据库

    var express = require("express");var query = require("querystring");var mysql = ...

  3. ES6字符串模板

    这里做个简单的拓展,之前做vue组件时,经常用到拼接字符串,换行时用到\,既费时又麻烦.这里介绍个ES6字符串模板方法 旧版拼接(各种换行拼接) Vue.component('obj-prop',{ ...

  4. Leetcode724:寻找数组的中心索引(java、python3)

    寻找数组的中心索引 给定一个整数类型的数组 nums,请编写一个能够返回数组"中心索引"的方法. 我们是这样定义数组中心索引的:数组中心索引的左侧所有元素相加的和等于右侧所有元素相 ...

  5. scala学习(2)---option空值处理

    https://blog.csdn.net/shadowsama/article/details/78148919 https://www.cnblogs.com/mustone/p/5648914. ...

  6. 【LeetCode】9、Palindrome Number(回文数)

    题目等级:Easy 题目描述: Determine whether an integer is a palindrome. An integer is a palindrome when it rea ...

  7. A3. JVM 类加载器

    [概述] 虚拟机设计团队把类加载阶段中的 “通过一个类的全限定名来获取描述此类的二进制字节流” 这个动作放到 Java 虚拟机外部去实现,以便让应用程序自己决定如何去获取所需要的类.实现这个动作的代码 ...

  8. telnet mysql3306端口失败

    在linux上telnet远程mysql端口失败,经过上网查找后,找到多种方法. (1)我在本地的Navicat上新增了一个用户,主机名是linux的ip,也可以是 %(百分号代表这个用户可以在任何地 ...

  9. Java基础——面向对象(封装——继承——多态 )

    对象 对象: 是类的实例(实现世界中 真 实存在的一切事物 可以称为对象) 类: 类是对象的抽象描述 步骤: 1.定义一个类 (用于 描述人:) ( * 人:有特征和行为) 2.根据类 创建对象 -- ...

  10. python 爬取微信好友列表和个性签名,绘制个性签名云图

    python爬取微信好友列表和个性签名,绘制个性签名云图 1. 简要介绍 本次实验主要用到下面几个库 : 1)itchat---用于微信接口,实现生成QR码,用于微信扫描登陆 2)re(正则化)--- ...