发明内容
鉴于上述问题,提出了本申请实施例以便提供一种克服上述问题或者至少部分地解决上述问题的一种虚拟机的数据存储方法和相应的一种虚拟机的数据存储装置。
为了解决上述问题,本申请实施例公开了一种虚拟机的数据存储方法,包括:
在宿主机中接收虚拟机发送的原数据的写请求;
检测所述写请求的请求类型;
当所述请求类型为第一写请求时,将所述原数据存储至第一存储设备中。
可选地,还包括:
判断所述第一存储设备中脏数据的数据量是否超过预设的阈值;
若是,则将所述原数据发送至第二存储设备进行存储;
若否,则对存储在所述第一存储设备的所述原数据标记为脏数据。
可选地,还包括:
在设定的时间将存储在所述第一存储设备的脏数据发送至第二存储设备进行存储;
当存储成功时,取消所述脏数据的标记,以识别为原数据。
可选地,还包括:
当所述请求类型为第二写请求时,读取存储在所述第一存储设备的全部脏数据;
将读取的脏数据发送至第二存储设备进行存储;
当存储成功时,取消所述脏数据的标记,以识别为原数据。
可选地,还包括:
当所述请求类型为第三写请求时,将所述原数据存储至第一存储设备中;
将所述原数据发送至第二存储设备进行存储。
可选地,所述在宿主机中接收虚拟机发送的原数据的写请求的步骤包括:
由位于宿主机内核态中的块设备后端驱动接收、由位于虚拟机内核态中的块设备前端驱动发送的原数据的写请求。
可选地,所述检测所述写请求的请求类型的步骤包括:
由位于宿主机内核态中的块设备后端驱动从所述写请求中读取请求类型标识,以识别所述写请求的请求类型。
可选地,所述将所述原数据存储至第一存储设备中的步骤包括:
由位于宿主机内核态的缓存服务对象将所述原数据写入位于宿主机中的第一存储设备中;
更新所述原数据的索引信息。
可选地,所述将所述原数据发送至第二存储设备进行存储的步骤包括:
由所述缓存服务对象将所述原数据发送至位于宿主机用户态的存储客户端;
由所述存储客户端发送所述原数据至位于宿主机之外的第二存储设备进行存储。
可选地,所述在设定的时间将存储在所述第一存储设备的脏数据发送至第二存储设备进行存储的步骤包括:
当超过预设的休眠时间,唤醒位于宿主机内核态的回写线程;
由所述回写线程按照所述索引信息读取部分存储在所述第一存储设备的脏数据;
由所述回写线程将读取的脏数据发送至位于宿主机用户态的存储客户端;
由所述存储客户端发送所述脏数据至位于宿主机之外的第二存储设备进行存储;
当存储成功时,计算休眠时间;
对所述回写线程进行休眠。
可选地,所述读取存储在所述第一存储设备的全部脏数据的步骤包括:
由所述缓存服务对象唤醒位于宿主机内核态的回写线程;
由所述回写线程按照所述索引信息读取存储在所述第一存储设备的全部脏数据。
可选地,所述将读取的脏数据发送至第二存储设备进行存储的步骤包括:
由所述回写线程将读取的脏数据发送至位于宿主机用户态的存储客户端;
由所述存储客户端发送所述脏数据至位于宿主机之外的第二存储设备进行存储。
可选地,所述当存储成功时,取消所述脏数据的标记,以识别为原数据的步骤包括:
当所述回写线程接收到所述存储客户端返回的存储成功的消息时,取消所述脏数据的标记,以识别为原数据。
本申请实施例还公开了一种虚拟机的数据存储装置,包括:
写请求接收模块,用于在宿主机中接收虚拟机发送的原数据的写请求;
请求类型检测模块,用于检测所述写请求的请求类型;
第一快速存储模块,用于在所述请求类型为第一写请求时,将所述原数据存储至第一存储设备中。
可选地,还包括:
数据量判断模块,用于判断所述第一存储设备中脏数据的数据量是否超过预设的阈值;若是,则调用第一持久化存储模块,若否,则调用脏数据标记模块;
第一持久化存储模块,用于将所述原数据发送至第二存储设备进行存储;
脏数据标记模块,用于对存储在所述第一存储设备的所述原数据标记为脏数据。
可选地,还包括:
第二持久化存储模块,用于在设定的时间将存储在所述第一存储设备的脏数据发送至第二存储设备进行存储;
第一脏数据取消标记模块,用于在存储成功时,取消所述脏数据的标记,以识别为原数据。
可选地,还包括:
脏数据读取模块,用于在所述请求类型为第二写请求时,读取存储在所述第一存储设备的全部脏数据;
第三持久化存储模块,用于将读取的脏数据发送至第二存储设备进行存储;
第二脏数据取消标记模块,用于在存储成功时,取消所述脏数据的标记,以识别为原数据。
可选地,还包括:
第二快速存储模块,用于在所述请求类型为第三写请求时,将所述原数据存储至第一存储设备中;
第四持久化存储模块,用于将所述原数据发送至第二存储设备进行存储。
可选地,所述写请求接收模块包括:
驱动接收子模块,用于由位于宿主机内核态中的块设备后端驱动接收、由位于虚拟机内核态中的块设备前端驱动发送的原数据的写请求;
可选地,所述请求类型检测模块包括:
驱动检测子模块,用于由位于宿主机内核态中的块设备后端驱动从所述写请求中读取请求类型标识,以识别所述写请求的请求类型;
可选地,所述第一快速存储模块包括:
第一缓存服务写数据子模块,用于由位于宿主机内核态的缓存服务对象将所述原数据写入位于宿主机中的第一存储设备中;
第一索引信息更新子模块,用于更新所述原数据的索引信息。
可选地,所述第二快速存储模块包括:
第二缓存服务写数据子模块,用于由位于宿主机内核态的缓存服务对象将所述原数据写入位于宿主机中的第一存储设备中;
第二索引信息更新子模块,用于更新所述原数据的索引信息。
可选地,所述第一持久化存储模块包括:
第一存储客户端发送子模块,用于由所述缓存服务对象将所述原数据发送至位于宿主机用户态的存储客户端;
第一存储客户端存储子模块,用于由所述存储客户端发送所述原数据至位于宿主机之外的第二存储设备进行存储;
可选地,所述第四持久化存储模块包括:
第二存储客户端发送子模块,用于由所述缓存服务对象将所述原数据发送至位于宿主机用户态的存储客户端;
第二存储客户端存储子模块,用于由所述存储客户端发送所述原数据至位于宿主机之外的第二存储设备进行存储;
可选地,所述第二持久化存储模块包括:
第一回写线程唤醒子模块,用于在超过预设的休眠时间,唤醒位于宿主机内核态的回写线程;
部分脏数据读取子模块,用于由所述回写线程按照所述索引信息读取部分存储在所述第一存储设备的脏数据;
第三存储客户端发送子模块,用于由所述回写线程将读取的脏数据发送至位于宿主机用户态的存储客户端;
第三存储客户端存储子模块,用于由所述存储客户端发送所述脏数据至位于宿主机之外的第二存储设备进行存储;
休眠时间计算子模块,用于在存储成功时,计算休眠时间;
休眠子模块,用于对所述回写线程进行休眠。
可选地,所述脏数据读取模块包括:
第二回写线程唤醒子模块,用于由所述缓存服务对象唤醒位于宿主机内核态的回写线程;
全部脏数据读取子模块,用于由所述回写线程按照所述索引信息读取存储在所述第一存储设备的全部脏数据;
可选地,所述第三持久化存储模块包括:
第四存储客户端发送子模块,用于由所述回写线程将读取的脏数据发送至位于宿主机用户态的存储客户端;
第四存储客户端存储子模块,用于由所述存储客户端发送所述脏数据至位于宿主机之外的第二存储设备进行存储。
可选地,所述第一脏数据取消标记模块包括:
第一标记取消子模块,用于在所述回写线程接收到所述存储客户端返回的存储成功的消息时,取消所述脏数据的标记,以识别为原数据。
可选地,所述第二脏数据取消标记模块包括:
第二标记取消子模块,用于在所述回写线程接收到所述存储客户端返回的存储成功的消息时,取消所述脏数据的标记,以识别为原数据。
本申请实施例包括以下优点:
本申请实施例划分不同请求类型的写请求,按照不同的请求类型的写请求进行不同类型的写操作,对于虚拟机发送的普通写请求,则由宿主机存储至第一存储设备,避免直接持久化至第二存储设备,大大减少了存储的I/O路径,减少的时间和设备资源的消耗,提升了虚拟机环境下分布式存储的写性能。
本申请实施例对于普通写请求,写入到第一存储设备意味着写操作就已经完成,可以返回写操作的结果。
如果此时出现宕机,这部分数据将会丢失,但是,由于文件***的元数据并没有更新,因此,并不会导致文件***的不一致,保证数据的一致性要求能够实现。
本申请实施例考虑到普通写请求过多的时候可能导致快速缓存设备中存在大量脏数据的情况,对快速缓存设备中的脏数据的数据量(大小或数量)进行了限制。
若脏数据的数据量超过预设的阈值,表示存在较多的脏数据,所有超过该阈值的写请求将会直接发给第二存储设备进行存储,减少在第一存储设备所在宿主机宕机时导致的数据丢失。
本申请实施例实现了对刷新缓存写请求之前所有写请求的处理,保证之前所有的数据都已经写入到第二存储设备(如分布式文件***)才返回,实现了元数据更新之后的一致性要求。
本申请实施例对于带强制访问单元标志的写请求,通过直接将该原数据发送至第二存储设备(如分布式文件***),实现了数据的一致性要求。
具体实施方式
为使本申请的上述目的、特征和优点能够更加明显易懂,下面结合附图和具体实施方式对本申请作进一步详细的说明。
参照图1,示出了本申请的一种虚拟机的数据存储方法实施例1的步骤流程图,具体可以包括如下步骤:
步骤101,在宿主机中接收虚拟机发送的原数据的写请求;
一般而言,虚拟机技术通过在物理设备(又称宿主机)上添加一层虚拟机监控程序(Virtual Machine Monitor,VMM),从而实现虚拟化,如虚拟化处理器、虚拟内存管理器(Memory Management Unit,MMU)和虚拟I/O***等等。
在同一个物理设备中,可以生成多个不同的虚拟机,分别运行多个不同或相同的操作***
虚拟机监控程序又称为监管程序(Hypervisor),从应用程序的角度看,程序运行在虚拟机上同运行在宿主机上是一样的。
在实际应用中,虚拟机可以包括Hyper-V,Xen,KVM(Kernel-based VirtualMachine),Vmware等等。
为使本领域技术人员更好地理解本申请实施例,在本说明书中,将Xen作为虚拟机的一种示例进行说明。
Xen属于硬件虚拟化技术的一种实现方案,本质上是一种虚拟机监控器,可以运行在多个平台上,比如IA-32,x86-64和ARM。
Xen VMM允许多个虚拟***并发地运行在同一个硬件环境上,对虚拟***运行情况、硬件资源和其他计算机资源进行管理和分配。
Xen Hypervisor是Xen***中最重要的部分之一,运行在虚拟***和物理平台中,是最靠近物理层的也是具有最高的优先级的部分。Hypervisor负责调度在它之上运行的虚拟***。
Xen中最开始运行的第一个虚拟***,通常称为dom0,是一个拥有特权的***,对其他虚拟***的管理需要在这个***中进行。dom0还得到VMM的授权,可以直接对硬件进行访问。
dom0的操作***一般是修改过的操作***,被修改的操作***可以是Linux、NetBSD和Solaris。
不过,随着硬件技术的发展,未修改过的操作***也可以在一些硬件技术辅助下直接运行在Xen平台上,这些操作***包括Intel VT-x和AMD-V,主要是针对CPU(CentralProcessing Unit,中央处理器)特权级进行了修改。
为了有效地管理和控制程序执行,宿主机和虚拟机的操作***一般都设置有特权级,因此在硬件上对特权级做了很多支持,就Intel x86架构的CPU来说,一共有0~3四个特权级,0级最高,3级最低,硬件上在执行每条指令时都会对指令所具有的特权级做相应的检查。
从特权级的调度而言,当应用程序运行在3级特权级上时,可以称之为运行在用户态,因为这是最低特权级,是普通的用户进程运行的特权级,大部分用户直接面对的程序都是运行在用户态;反之,当应用程序运行在级特权级上时,就可以称之为运行在内核态。
在本申请实施例中,如图2所示,块设备(blockdevice)驱动可以分为块设备前端驱动211和块设备后端驱动201,块设备前端驱动部署在虚拟机210的内核态中,块设备后端驱动201部署在宿主机200的内核态中。
当然,块设备前端驱动211也可以在虚拟机210的用户态中,块设备后端驱动201也可以部署在宿主机的用户态中,本申请实施例对此不加以限制。
其中,块设备是指一种具有一定结构的随机存取设备,对这种设备的读写是按块进行的,使用缓冲区来存放暂时的数据,待检测到指定的条件后,从缓存一次性写入设备或者从设备一次性读到缓冲区。
块设备的应用在Linux中是一个完整的子***,在Linux中,驱动对块设备的I/O操作,会向块设备发出一个请求,在驱动中用request结构体描述。对于一些磁盘设备而言请求的速度很慢,这时候可以使用队列的机制把这些I/O请求添加到队列中,在驱动中用request_queue结构体描述。
在具体实现中,用户在虚拟机中的一些写操作,可以触发原数据的写请求,虚拟机也可以自动触发原数据的写请求(request)。
一般而言,每个写操作在后端可以对应2个以上的写请求,用于避免单点问题(如写数据失败)导致的服务不可用。
在本申请实施例中,划分不同请求类型的写请求,对写请求引入POSIX(可移植操作***接口)语义,实现了符合POSIX语义的数据一致性要求,并对数据的写流程进行修改,按照不同的请求类型的写请求进行不同类型的写操作。
因此,块设备前端驱动211可以在原数据的写请求中,写入请求类型的标识(即识别写请求的类型的信息),如在operation参数中添加请求类型的标识,传送至宿主机200内核态中的块设备前端驱动211。
相对而言,即由位于宿主机200内核态中的块设备后端驱动201接收、由位于虚拟机210内核态中的块设备前端驱动211发送的原数据的写请求。
进一步而言,在Xen中,块设备前端驱动211可以通过I/O环将写请求传送至块设备后端驱动201,即块设备后端驱动201可以通过I/O环接收块设备前端驱动211发送的写请求。
I/O环工作方式以生产者/消费者为基础,拓扑模型为环形结构。前端驱动(如块设备前端驱动211)需要转发I/O请求时,将请求依次写入I/O环中,后端驱动(如块设备后端驱动201)读取请求并将操作结果写入I/O环,最后由前端驱动读取结果。前端驱动是I/O请求的生产者和操作结果的消费者,而后端驱动则是I/O请求的消费者和操作结果的生产者。
步骤102,检测所述写请求的请求类型;
在具体实现中,如图2所示,可以由位于宿主机200内核态中的块设备后端驱动201从所述写请求中读取请求类型标识,如operation参数,以识别写请求的请求类型。
步骤103,当所述请求类型为第一写请求时,将所述原数据存储至第一存储设备中。
在本申请实施例中,可以设置第一写请求,该第一写请求又称之为普通写请求,请求类型标识可以是BLKIF_OP_WRITE。
普通写请求可以由write函数(用于写文件描述符)、fwrite函数(用于写数据块)等操作触发,通常并非对文件***的元数据(如索引数据(记录文件对应在块设备上的偏移和大小),目录数据等)进行更新。
需要说明的是,分布式存储通常要求单台物理设备宕机并不影响数据的一致性。
本申请实施例对于普通写请求,写入到第一存储设备意味着写操作就已经完成,可以返回写操作的结果。
如果此时出现宕机,这部分数据将会丢失,但是,由于文件***的元数据并没有更新,因此,并不会导致文件***的不一致,保证数据的一致性要求能够实现。
在具体实现中,如图2所示,可以由位于宿主机200内核态的缓存服务对象202将原数据写入位于宿主机202中的第一存储设备203中,以及,更新原数据的索引信息。
在本申请实施例中,第一存储设备为临时存储介质(如固态硬盘、内存等),并非持久化存储介质(如磁盘),其可以部署在宿主机中的,但是从架构上来说,也可以部署在虚拟机中。
整体上而言,第一存储设备离虚拟机越近,网络延迟越低,存储性能就越优,因此,第一存储设备又称快速存储设备。
此外,在索引信息中,记录了原数据在第一存储设备中的偏移、大小及在第二存储设备中的偏移等信息,若存储在第一存储设备成功时,则可以更新相关的信息,如第一存储设备中的偏移、大小等。
本申请实施例划分不同请求类型的写请求,按照不同的请求类型的写请求进行不同类型的写操作,对于虚拟机发送的普通写请求,则由宿主机存储至第一存储设备,避免直接持久化至第二存储设备,大大减少了存储的I/O路径,减少的时间和设备资源的消耗,提升了虚拟机环境下分布式存储的写性能。
参照图3,示出了本申请的一种虚拟机的数据存储方法实施例2的步骤流程图,具体可以包括如下步骤:
步骤301,在宿主机中接收虚拟机发送的原数据的写请求;
步骤302,检测所述写请求的请求类型;
步骤303,当所述请求类型为第一写请求时,将所述原数据存储至第一存储设备中;
步骤304,判断所述第一存储设备中脏数据的数据量是否超过预设的阈值;若是,则执行步骤305,若否,则执行步骤306;
脏数据,可以指未持久化至第二存储设备(持久化存储介质,如磁盘)的原数据,在索引信息中,具有一个脏数据标志位对该脏数据进行标识。
本申请实施例考虑到普通写请求过多的时候可能导致快速缓存设备中存在大量脏数据的情况,对快速缓存设备中的脏数据的数据量(大小或数量)进行了限制。
若脏数据的数据量超过预设的阈值,表示存在较多的脏数据,所有超过该阈值的写请求将会直接发给第二存储设备进行存储,减少在第一存储设备所在宿主机宕机时导致的数据丢失。
步骤305,将所述原数据发送至第二存储设备进行存储;
若脏数据的数据量超过预设的阈值,则表示第一存储设备中存储的脏数据的数据量较大,持久化压力较大,则可以直接发送至第二存储设备进行存储。
在具体实现中,如图2所示,可以由缓存服务对象202将原数据,通过Xen提供的Blktap接口205(用户级别的磁盘I/O接口)等方式,发送至位于宿主机200用户态的存储客户端206;
由存储客户端206通过网络220等方式,发送原数据至位于宿主机200之外的第二存储设备230进行存储。
由于分布式文件***不论是在数据的存储容量、可扩展性方面,还是在可靠性、可用性等方面都有比较大的优势,因此,第二存储设备多为分布式文件***,包括NFS(Network File System)、Coda、AFS(Andrew File System)、Sprite File System,HDFS(Hadoop Distributed File System)、盘古***等等。
以HDFS为例,HDFS主要是由元数据节点Namenode(master)、从元数据节点(Secondary namenode)和一系列的数据节点Datanode(worders)构成。
元数据节点Namenode负责管理HDFS的命名控件和元数据,它将所有文件夹和文件元数据存储在一个目录树中,这些信息自成在硬盘上保存为命名空间镜像(namespace)和修改日志(edit log)文件。其中还保存着一个文件由哪些块所组成,以这些块的分布,但是这些信息并不直接存在硬盘上,而是***启动时从各个节点收集起来的。
数据节点(Datanode)是***中真正存储数据地方,客户端(client)或元数据节点(Namenode)可以向数据节点(Datanode)请求读取或写入数据,它隔一定的时间就向元数据节点(Namenode)汇报一次它存储的数据信息。
从元数据节点(Secondary namenode)周期性地将元数据节点(Namenode)的数据文件跟修改日志合并,以防止日志文件过大。
当客户端(client)在HDFS***中进行写操作时,HDFS***会首先将客户端的操作记录在修改日志(edit log)中。
元数据节点(Namenode)在内存中保存文件的元数据信息,在记录修改日志(editlog)之后,修改内存中的数据结构,并且在每次写操作成功之前,系HDFS统都会对修改日志进行同步。
步骤306,对存储在所述第一存储设备的所述原数据标记为脏数据;
在具体实现中,可以在原数据的索引信息中,添加一脏数据标志位,以标识该原数据为脏数据。
步骤307,在设定的时间将存储在所述第一存储设备的脏数据发送至第二存储设备进行存储;
在本申请实施例中,可以通过PID(比例-积分-导数)控制算法等方式控制回写速率,持续将存储在第一存储设备的脏数据持久化至第二存储设备中。
在具体实现中,如图2所示,当超过预设的休眠时间,唤醒位于宿主机200内核态的回写线程204,该回写线程204为异步线程。
需要说明的是,该回写线程204也可以部署在宿主机的用户态,本申请实施例对此不加以限制。
由回写线程204按照索引信息(如偏移)读取存储在第一存储设备203的脏数据,以及,由回写线程204将读取的脏数据,通过Xen提供的Blktap接口205(用户级别的磁盘I/O接口)等方式,发送至位于宿主机200用户态的存储客户端206。
由存储客户端206通过网络220,发送脏数据至位于宿主机200之外的第二存储设备230(如分布式文件***)进行存储。
当存储成功时,通过当前脏数据的增量、脏数据的数据量以及当前回写速度等因素计算下一次回写的休眠时间,并对回写线程204进行休眠(delay),直至到达该休眠时间。
步骤308,当存储成功时,取消所述脏数据的标记,以识别为原数据。
若脏数据存储成功,则可以取消该脏数据的标记,例如,在索引信息中取消该脏数据的脏数据标志位,以识别为原数据。
在具体实现中,如图2所示,当回写线程204接收到存储客户端206返回的存储成功的消息时,取消脏数据的标记,以识别为原数据。
参照图4,示出了本申请的一种虚拟机的数据存储方法实施例3的步骤流程图,具体可以包括如下步骤:
步骤401,在宿主机中接收虚拟机发送的原数据的写请求;
步骤402,检测所述写请求的请求类型;
步骤403,当所述请求类型为第二写请求时,读取存储在所述第一存储设备的全部脏数据;
在本申请实施例中,可以设置第二写请求,该第二写请求又称为刷新缓存写请求,请求类型标识可以是BLKIF_OP_FLUSH_DISKCACHE。
刷新缓存写请求可以由sync(同步写,没有写到物理设备就不会返回)、fsync(负责将一个文件描述符打开的文件写到物理设备,而且是真正的同步写,没有写完成就不会返回,而且写的时候将文件本身的一些元数据都会更新到物理设备上去)、或者以O_SYNC(该描述符会对普通文件的写操作产生影响,若设置了该描述符,则对该文件的写操作会等到数据被写到磁盘上才算结束)打开物理设备进行相关写操作时等操作触发,通常非对文件***的元数据进行更新。
需要说明的是,分布式存储通常要求单台物理设备宕机并不影响数据的一致性。
对于一个刷新缓存写请求,由于通常都是对元数据操作的写请求,因此,通常要求在该写请求处理完时之前所有的写请求都已经完成。
本申请实施例实现了对刷新缓存写请求之前所有写请求的处理,保证之前所有的数据都已经写入到第二存储设备(如分布式文件***)才返回,实现了元数据更新之后的一致性要求。
在具体实现中,如图2所示,可以由缓存服务对象202唤醒位于宿主机200内核态的回写线程204。
由回写线程204按照索引信息(如偏移)读取存储在第一存储设备203的全部脏数据。
需要说明的是,在检测到刷新缓存写请求之后,可以将回写线程的休眠时间直接设置为0返回,这样在写完当前的脏数据之后并不会睡眠,而是会继续回写后续的脏数据。
步骤404,将读取的脏数据发送至第二存储设备进行存储;
在具体实现中,如图2所示,可以由回写线程204将读取的脏数据,通过Xen提供的Blktap接口205(用户级别的磁盘I/O接口)等方式,发送至位于宿主机200用户态的存储客户端206;
由存储客户端206通过网络220,发送脏数据至位于宿主机300之外的第二存储设备230(如分布式文件***)进行存储;
步骤405,当存储成功时,取消所述脏数据的标记,以识别为原数据。
若脏数据存储成功,则可以取消该脏数据的标记,例如,在索引信息中取消该脏数据的脏数据标志位,以识别为原数据。
在具体实现中,如图2所示,当回写线程204接收到存储客户端206返回的存储成功的消息时,取消脏数据的标记,以识别为原数据。
参照图5,示出了本申请的一种虚拟机的数据存储方法实施例4的步骤流程图,具体可以包括如下步骤:
步骤501,在宿主机中接收虚拟机发送的原数据的写请求;
步骤502,检测所述写请求的请求类型;
步骤503,当所述请求类型为第三写请求时,将所述原数据存储至第一存储设备中;
在具体实现中,如图2所示,可以由位于宿主机200内核态的缓存服务对象202将原数据写入位于宿主机202中的第一存储设备203中,以及,更新原数据的索引信息。
步骤504,将所述原数据发送至第二存储设备进行存储。
在本申请实施例中,可以设置第三写请求,该第三写请求又称为带强制访问单元标志的写请求,请求类型标识可以是BLKIF_OP_WRITE_BARRIER。
带强制访问单元标志的写请求,由虚拟机的内核添加,用于对特定数据必须落盘(持久化至第二存储设备)这类需求进行满足。
在一个示例中,用户态调用write写数据时,可以指定是否带O_DSYNC标志,如果带该标志,那么意味着该写请求是带强制访问单元标志的写请求,否则就是普通写请求。
此时,保证之前所有数据都已经落盘,那么可以调用fsync(),***会有一个刷新缓存写请求产生。
需要说明的是,分布式存储通常要求单台物理设备宕机并不影响数据的一致性。
本申请实施例对于带强制访问单元标志的写请求,通过直接将该原数据发送至第二存储设备(如分布式文件***),实现了数据的一致性要求。
在具体实现中,如图2所示,可以由缓存服务对象202将原数据,通过Xen提供的Blktap接口205(用户级别的磁盘I/O接口)等方式,发送至位于宿主机200用户态的存储客户端206;
由存储客户端206通过网络220等方式,发送原数据至位于宿主机200之外的第二存储设备230进行存储。
需要说明的是,对于方法实施例,为了简单描述,故将其都表述为一系列的动作组合,但是本领域技术人员应该知悉,本申请实施例并不受所描述的动作顺序的限制,因为依据本申请实施例,某些步骤可以采用其他顺序或者同时进行。其次,本领域技术人员也应该知悉,说明书中所描述的实施例均属于优选实施例,所涉及的动作并不一定是本申请实施例所必须的。
参照图6,示出了本申请的一种虚拟机的数据存储装置实施例的结构框图,具体可以包括如下模块:
写请求接收模块601,用于在宿主机中接收虚拟机发送的原数据的写请求;
请求类型检测模块602,用于检测所述写请求的请求类型;
第一快速存储模块603,用于在所述请求类型为第一写请求时,将所述原数据存储至第一存储设备中。
在本申请的一个实施例中,该装置还可以包括如下模块:
数据量判断模块,用于判断所述第一存储设备中脏数据的数据量是否超过预设的阈值;若是,则调用第一持久化存储模块,若否,则调用脏数据标记模块;
第一持久化存储模块,用于将所述原数据发送至第二存储设备进行存储;
脏数据标记模块,用于对存储在所述第一存储设备的所述原数据标记为脏数据。
在本申请的一个实施例中,该装置还可以包括如下模块:
第二持久化存储模块,用于在设定的时间将存储在所述第一存储设备的脏数据发送至第二存储设备进行存储;
第一脏数据取消标记模块,用于在存储成功时,取消所述脏数据的标记,以识别为原数据。
在本申请的一个实施例中,该装置还可以包括如下模块:
脏数据读取模块,用于在所述请求类型为第二写请求时,读取存储在所述第一存储设备的全部脏数据;
第三持久化存储模块,用于将读取的脏数据发送至第二存储设备进行存储;
第二脏数据取消标记模块,用于在存储成功时,取消所述脏数据的标记,以识别为原数据。
在本申请的一个实施例中,该装置还可以包括如下模块:
第二快速存储模块,用于在所述请求类型为第三写请求时,将所述原数据存储至第一存储设备中;
第四持久化存储模块,用于将所述原数据发送至第二存储设备进行存储。
在本申请的一个实施例中,所述写请求接收模块601可以包括如下子模块:
驱动接收子模块,用于由位于宿主机内核态中的块设备后端驱动接收、由位于虚拟机内核态中的块设备前端驱动发送的原数据的写请求;
在本申请的一个实施例中,所述请求类型检测模块602可以包括如下子模块:
驱动检测子模块,用于由位于宿主机内核态中的块设备后端驱动从所述写请求中读取请求类型标识,以识别所述写请求的请求类型;
在本申请的一个实施例中,所述第一快速存储模块603可以包括如下子模块:
第一缓存服务写数据子模块,用于由位于宿主机内核态的缓存服务对象将所述原数据写入位于宿主机中的第一存储设备中;
第一索引信息更新子模块,用于更新所述原数据的索引信息;
在本申请的一个实施例中,所述第二快速存储模块可以包括如下子模块:
第二缓存服务写数据子模块,用于由位于宿主机内核态的缓存服务对象将所述原数据写入位于宿主机中的第一存储设备中;
第二索引信息更新子模块,用于更新所述原数据的索引信息。
在本申请的一个实施例中,所述第一持久化存储模块可以包括如下子模块:
第一存储客户端发送子模块,用于由所述缓存服务对象将所述原数据发送至位于宿主机用户态的存储客户端;
第一存储客户端存储子模块,用于由所述存储客户端发送所述原数据至位于宿主机之外的第二存储设备进行存储;
在本申请的一个实施例中,所述第四持久化存储模块可以包括如下子模块:
第二存储客户端发送子模块,用于由所述缓存服务对象将所述原数据发送至位于宿主机用户态的存储客户端;
第二存储客户端存储子模块,用于由所述存储客户端发送所述原数据至位于宿主机之外的第二存储设备进行存储。
在本申请的一个实施例中,所述第二持久化存储模块可以包括如下子模块:
第一回写线程唤醒子模块,用于在超过预设的休眠时间,唤醒位于宿主机内核态的回写线程;
部分脏数据读取子模块,用于由所述回写线程按照所述索引信息读取部分存储在所述第一存储设备的脏数据;
第三存储客户端发送子模块,用于由所述回写线程将读取的脏数据发送至位于宿主机用户态的存储客户端;
第三存储客户端存储子模块,用于由所述存储客户端发送所述脏数据至位于宿主机之外的第二存储设备进行存储;
休眠时间计算子模块,用于在存储成功时,计算休眠时间;
休眠子模块,用于对所述回写线程进行休眠。
在本申请的一个实施例中,所述脏数据读取模块可以包括如下子模块:
第二回写线程唤醒子模块,用于由所述缓存服务对象唤醒位于宿主机内核态的回写线程;
全部脏数据读取子模块,用于由所述回写线程按照所述索引信息读取存储在所述第一存储设备的全部脏数据;
在本申请的一个实施例中,所述第三持久化存储模块可以包括如下子模块:
第四存储客户端发送子模块,用于由所述回写线程将读取的脏数据发送至位于宿主机用户态的存储客户端;
第四存储客户端存储子模块,用于由所述存储客户端发送所述脏数据至位于宿主机之外的第二存储设备进行存储。
在本申请的一个实施例中,所述第一脏数据取消标记模块可以包括如下子模块:
第一标记取消子模块,用于在所述回写线程接收到所述存储客户端返回的存储成功的消息时,取消所述脏数据的标记,以识别为原数据。
在本申请的一个实施例中,所述第二脏数据取消标记模块可以包括如下子模块:
第二标记取消子模块,用于在所述回写线程接收到所述存储客户端返回的存储成功的消息时,取消所述脏数据的标记,以识别为原数据。
对于装置实施例而言,由于其与方法实施例基本相似,所以描述的比较简单,相关之处参见方法实施例的部分说明即可。
本说明书中的各个实施例均采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似的部分互相参见即可。
本领域内的技术人员应明白,本申请实施例的实施例可提供为方法、装置、或计算机程序产品。因此,本申请实施例可采用完全硬件实施例、完全软件实施例、或结合软件和硬件方面的实施例的形式。而且,本申请实施例可采用在一个或多个其中包含有计算机可用程序代码的计算机可用存储介质(包括但不限于磁盘存储器、CD-ROM、光学存储器等)上实施的计算机程序产品的形式。
在一个典型的配置中,所述计算机设备包括一个或多个处理器(CPU)、输入/输出接口、网络接口和内存。内存可能包括计算机可读介质中的非永久性存储器,随机存取存储器(RAM)和/或非易失性内存等形式,如只读存储器(ROM)或闪存(flash RAM)。内存是计算机可读介质的示例。计算机可读介质包括永久性和非永久性、可移动和非可移动媒体可以由任何方法或技术来实现信息存储。信息可以是计算机可读指令、数据结构、程序的模块或其他数据。计算机的存储介质的例子包括,但不限于相变内存(PRAM)、静态随机存取存储器(SRAM)、动态随机存取存储器(DRAM)、其他类型的随机存取存储器(RAM)、只读存储器(ROM)、电可擦除可编程只读存储器(EEPROM)、快闪记忆体或其他内存技术、只读光盘只读存储器(CD-ROM)、数字多功能光盘(DVD)或其他光学存储、磁盒式磁带,磁带磁磁盘存储或其他磁性存储设备或任何其他非传输介质,可用于存储可以被计算设备访问的信息。按照本文中的界定,计算机可读介质不包括非持续性的电脑可读媒体(transitory media),如调制的数据信号和载波。
本申请实施例是参照根据本申请实施例的方法、终端设备(***)、和计算机程序产品的流程图和/或方框图来描述的。应理解可由计算机程序指令实现流程图和/或方框图中的每一流程和/或方框、以及流程图和/或方框图中的流程和/或方框的结合。可提供这些计算机程序指令到通用计算机、专用计算机、嵌入式处理机或其他可编程数据处理终端设备的处理器以产生一个机器,使得通过计算机或其他可编程数据处理终端设备的处理器执行的指令产生用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的装置。
这些计算机程序指令也可存储在能引导计算机或其他可编程数据处理终端设备以特定方式工作的计算机可读存储器中,使得存储在该计算机可读存储器中的指令产生包括指令装置的制造品,该指令装置实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能。
这些计算机程序指令也可装载到计算机或其他可编程数据处理终端设备上,使得在计算机或其他可编程终端设备上执行一系列操作步骤以产生计算机实现的处理,从而在计算机或其他可编程终端设备上执行的指令提供用于实现在流程图一个流程或多个流程和/或方框图一个方框或多个方框中指定的功能的步骤。
尽管已描述了本申请实施例的优选实施例,但本领域内的技术人员一旦得知了基本创造性概念,则可对这些实施例做出另外的变更和修改。所以,所附权利要求意欲解释为包括优选实施例以及落入本申请实施例范围的所有变更和修改。
最后,还需要说明的是,在本文中,诸如第一和第二等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者终端设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者终端设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者终端设备中还存在另外的相同要素。
以上对本申请所提供的一种虚拟机的数据存储方法和一种虚拟机的数据存储装置,进行了详细介绍,本文中应用了具体个例对本申请的原理及实施方式进行了阐述,以上实施例的说明只是用于帮助理解本申请的方法及其核心思想;同时,对于本领域的一般技术人员,依据本申请的思想,在具体实施方式及应用范围上均会有改变之处,综上所述,本说明书内容不应理解为对本申请的限制。