vhost-user 简介

什么是 vhost-user

在 vhost 的方案中,由于 vhost 实现在内核中,guest 与 vhost 的通信,相较于原生的 virtio 方式性能上有了一定程度的提升,从 guest 到 kvm.ko 的交互只有一次用户态的切换以及数据拷贝。这个方案对于不同 host 之间的通信,或者 guest 到 host nic 之间的通信是比较好的,但是对于某些用户态进程间的通信,比如数据面的通信方案,openvswitch 和与之类似的 SDN 的解决方案,guest 需要和 host 用户态的 vswitch 进行数据交换,如果采用 vhost 的方案,guest 和 host 之间又存在多次的上下文切换和数据拷贝,为了避免这种情况,业界就想出将 vhost 从内核态移到用户态。这就是 vhost-user 的实现。

vhost-user 的实现

vhost-user 和 vhost 的实现原理是一样,都是采用 vring 完成共享内存,eventfd 机制完成事件通知。不同在于 vhost 实现在内核中,而 vhost-user 实现在用户空间中,用于用户空间中两个进程之间的通信,其采用共享内存的通信方式。

vhost-user 基于 C/S 的模式,采用 UNIX 域套接字(UNIX domain socket)来完成进程间的事件通知和数据交互,相比 vhost 中采用 ioctl 的方式,vhost-user 采用 socket 的方式大大简化了操作。

vhost-user 基于 vring 这套通用的共享内存通信方案,只要 client 和 server 按照 vring 提供的接口实现所需功能即可,常见的实现方案是 client 实现在 guest OS 中,一般是集成在 virtio 驱动上,server 端实现在 qemu 中,也可以实现在各种数据面中,如 OVS,Snabbswitch 等虚拟交换机。

如果使用 qemu 作为 vhost-user 的 server 端实现,在启动 qemu 时,我们需要指定 -mem-path 和 -netdev 参数,如:

$ qemu -m 1024 -mem-path /hugetlbfs,prealloc=on,share=on \
-netdev type=vhost-user,id=net0,file=/path/to/socket \
-device virtio-net-pci,netdev=net0

指定 -mem-path 意味着 qemu 会在 guest OS 的内存中创建一个文件,share=on 选项允许其他进程访问这个文件,也就意味着能访问 guest OS 内存,达到共享内存的目的。

-netdev type=vhost-user 指定通信方案,file=/path/to/socket 指定 socket 文件。

当 qemu 启动之后,首先会进行 vring 的初始化,并通过 socket 建立 C/S 的共享内存区域和事件机制,然后 client 通过 eventfd 将 virtio kick 事件通知到 server 端,server 端同样通过 eventfd 进行响应,完成整个数据交互。

几个例子

开源社区中实现了一个项目 Vapp,主要是用来测试 vhost-user 的 C/S 模式的,github 地址如下:

https://github.com/virtualopensystems/vapp.git

使用:

$ git clone https://github.com/virtualopensystems/vapp.git
$ cd vapp
$ make
// 运行 server 端
$ ./vhost -s ./vhost.sock
// 运行 client 端
$ ./vhost -q ./vhost.sock

通过以上步骤,就可以启动 vhost-user 的 C/S 模式。

另外还有例子就是集成在虚拟交换机 Snabbswitch 上的 vhost-user,通过以下方式获得 vhost-user 分支:

$ git clone -b vhostuser --recursive https://github.com/SnabbCo/snabbswitch.git
$ cd snabbswitch
$ make
测试:
$ sudo src/snabbswitch -t apps.vhost.vhost_user

还有例子就是 qemu 上的实现,这也是最原早的实现,同样通过以下方式来获得使用:

$ git clone -b vhost-user-v5 https://github.com/virtualopensystems/qemu.git
$ mkdir qemu/obj
$ cd qemu/obj/
$ ../configure --target-list=x86_64-softmmu
$ make -j

除此之外,还有很多的实现,如 OVS 和 DPDK 上都有实现,这实际上是集成了 vhost-user 的通用 API。

总结

virtio,vhost,vhost-user 是基于场景和性能而提出的三种 guest 和 host 之间的通信方案,三种方案,各有优劣。

vhost-user 用在很多数据面之上的进程间通信,效率高。


PS:对云计算感兴趣的小伙伴可以关注我的微信公众号:aCloudDeveloper,专注云计算领域,坚持分享干货。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Linyb极客之路

高并发之降级

在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流。之前已经有一些文章介绍过缓存和限流了。本文将详细聊聊降级。

2102
来自专栏IT大咖说

打开API网关设计的一扇窗

摘要 API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。 ? ...

4626
来自专栏码神联盟

碎片化 | 第一阶段-05-Java环境变量配置技巧-视频

如清晰度低,可转PC网页观看高清版本: http://v.qq.com/x/page/y0565t5tzd6.html Java环境变量配置技巧 在开发过...

3719
来自专栏finleyMa

(转) 网站统计中的数据收集原理及实现

原文地址:http://blog.codinglabs.org/articles/how-web-analytics-data-collection-syste...

2011
来自专栏杨建荣的学习笔记

MySQL备份和恢复工具图谱

之前没有认真整理,感觉备份工具就是mysqldump,xtrabackup了,但是如果认真想一想,其实会发现还是有很多其他丰富的功能。 比如数据的逻辑...

28910
来自专栏黑泽君的专栏

Github全面学习笔记

==================================================== 如何创建分支branch?   分支可以方便同时处理...

2282
来自专栏腾讯移动品质中心TMQ的专栏

专治时间长 —5分钟测试Android覆盖安装

一、痛点 ? 覆盖安装测试,作为一项基本的测试类型是不可或缺的。它存在的主要价值: 验证老版本覆盖升级到新版本,用户和系统数据能够正确迁移,以及保障用户升级后的...

36010
来自专栏Golang语言社区

Golang - 调度剖析【第一部分】

首先,Golang 调度器的设计和实现让我们的 Go 程序在多线程执行时效率更高,性能更好。这要归功于 Go 调度器与操作系统(OS)调度器的协同合作。不过在本...

1342
来自专栏Android 开发者

[译] 正确实现 linkedPurchaseToken 以避免重复订阅

你是否在使用 Google Play 的订阅功能?要确保你的后端服务实现的方式是正确的。

2104
来自专栏小狼的世界

AWStats日志文件中的一些术语解析

Number of visits made by all visitors. 所有用户的访问总数。

984

扫码关注云+社区

领取腾讯云代金券