本地存储常规架构
通用的云本地存储常规架构如下图所示。以MySQL数据库为例,它通过POSIX API与云主机内核交互,云主机内核包括一个标准文件系统和标准的块设备接口;云主机内核下面是云物理机内核,它自上而下由标准文件系统、标准块设备接口、硬件驱动和硬件组成。当数据库发起IO访问时,要经过7个模块才能到达硬件;请求完成后,再经过7个模块才能返回给应用层,路径相当之长。云主机内核和云物理机内核中都包括标准文件系统和块设备层,也就是说同样的模块可能在云主机内跑了一遍,还需要在云物理机上再运行一遍,功能上重叠,实现方式上也基本类似;重叠的模块导致请求访问时的路径很长,对于业务和数据库性能造成的直观影响是延迟高、性能差。(红包场景下,高性能本地存储技术将硬件性能发挥到极致-阿里云开发者社区)
现状
对使用本地存储的虚拟机,当前最常见的模式是,在宿主机系统上划分好一块区域提供给虚机当数据盘使用,在虚机内有一套文件系统,宿主机上还有一套文件系统。
一种是qcow2模式:
Openstack平台中,本地盘的使用一般会在宿主机上划分好一个lvm逻辑卷,将lvm逻辑卷mount到云管理平台指定的挂载点,如/var/lib/nova/instances,这样虚机使用的系统盘和数据盘的容量都是来自于分配好的lvm。
创建虚机时,基础镜像会先下载到/var/lib/nova/instances/_base,然后基于基础镜像再派生出虚机的系统盘disk;
对于虚机使用的数据盘,会在_base目录下创建一个指定大小的raw文件,这个raw文件虚拟大小显示为数据盘大小,比如100G的数据盘, _base目录下会有ephemeral_100_0706d66,虚机的数据盘再基于_base目录下的 ephemeral_100_0706d66,派生出数据盘disk.eph0。
一种是lvm格式:
lvm会在本地vg里创建指定大小的lvm卷
再怎么做高性能本地盘前,我们需要深入看下虚机是如何使用I/O设备的,看下I/O设备如何进行虚拟化。
I/O设备虚拟化
I/O设备虚拟化有三种方案:纯软件模拟,半虚拟化如virtio,硬件虚拟化(SR-IOV,VT-d)。一般来说,虚机使用半虚拟化virtio技术,虚机内安装磁盘前端驱动,主要是virtio-blk和virtio-scsi。网卡的前端驱动用的是virtio-net。
virtio pci设备
在QEMU中,virtio设备是QEMU为Guest操作系统模拟的PCI设备,这个设备可以是传统的PCI设备或PCIe设备,遵循PCI-SIG定义的PCI规范,可以具有配置空间、中断配置等功能。
PCI设备包括厂商ID和设备ID,virtio向PCI-SIG注册了PCI厂商ID 0x1AF4和设备ID,其中不同的设备ID代表不同的设备类型,如面向存储的virtio-blk和virtio-scsi设备ID分别为0x1001和0x1004。(https://lingxiankong.github.io/2014-11-17-virtio-blk.html)