发明内容
本发明实施例提供了一种基于嵌入式文件系统的流式数据写入方法,以解决现有技术中存在的数据写入效率低下、吞吐和并发性能不够高的问题。
为了实现上述目的,本申请实施例提供了一种基于嵌入式文件系统的流式数据写入方法,所述方法包括:
接收待写入磁盘的流式数据;
将接收的流式数据以链表结构进行组织,并将所述流式数据缓存于存储区,当缓存的流式数据的长度达到设定的阈值时,触发将缓存的流式数据写入磁盘的写操作;
从缓存中分离流式数据:
查询所述文件的元数据,获取存储文件内容的磁盘位置信息,根据所述磁盘位置信息,计算本次欲写入磁盘的流式数据长度,所述长度须为磁盘扇区大小的整数倍,且对应区段的数据在物理上和逻辑上均保持连续;
从缓存中取出所述长度的流式数据,取出数据的操作实则从缓存数据的链表中分离出一个所述长度的子链表:根据所述长度找到分离节点,从所述分离节点处截取流式数据,分离后的子链表对应的数据长度应与本次欲写入磁盘的流式数据长度相等;
将分离出的流式数据写入磁盘;
调用下层写接口将分离出的流式数据写入磁盘,写入数据时采用异步非阻塞模式,而非阻塞在将数据写入磁盘的过程中,待文件系统收到数据写入磁盘成功的消息后,尝试触发下一次写操作。
优选地,所述接收待写入磁盘的流式数据之前,所述方法还包括:
接收到一个新的流式数据写入请求后,判断系统中是否存在所述文件;
如果不存在,则需要请求方手动建立所述文件;
如果存在,则为所述请求新建一个写任务,获取所述文件的元数据,并为所述任务分配存储空间。
优选地,所述写请求的参数包括文件名、写入文件的起始偏移和写入文件的结束偏移。
优选地,所述方法还包括:
为所述写请求建立写任务,为所述写任务分配任务空间,将所述文件名的哈希值、待写入数据的起始偏移和待写入数据的结束偏移存入所述任务空间。
优选地,所述方法还包括对任务进行预处理:
如果所述待写入流式数据的起始偏移对应于磁盘扇区(头扇区)中的位置不在扇区头,则从磁盘中读出头扇区数据并缓存;如果所述待写入流式数据的结束偏移对应于磁盘扇区(尾扇区)中的位置不在扇区尾,则从磁盘中读出尾扇区数据并缓存。
优选地,将分离出的流式数据写入磁盘,所述方法还包括:
计算当前写操作对应的起始偏移和结束偏移;
如果所述当前写操作对应的起始偏移等于写任务的起始偏移,则所述当前写操作为第一次写操作;如果所述当前写操作对应的结束偏移等于写任务的结束偏移,则当前写操作为最后一次写操作。
优选地,执行第一次写操作时,所述方法还包括:
当第一次写操作对应的起始偏移对应于磁盘扇区中的位置不为扇区头时,则将第一次写操作对应的起始偏移与扇区头对齐,并利用缓存的头扇区数据填充第一次写操作中扩充的数据。
优选地,执行最后一次写操作时,所述方法还包括:
当最后一次写操作对应的结束偏移对应于磁盘扇区中的位置不为扇区尾时,则将最后一次写操作对应的结束偏移与扇区尾对齐,并利用缓存的尾扇区数据填充最后一次写操作扩充的数据。
优选地,执行写操作时,从缓存的流式数据中取出指定长度的待写数据,具体包括:
根据当次写操作欲写入磁盘的数据长度,找到分离节点,将缓存流式数据的链表从分离节点后截断,复制所述分离点,将复制的分离点作为剩余链表的头结点,调整原始分离节点和复制分离点中的数据起始偏移和数据长度。
优选地,文件系统收到上一批数据写入磁盘成功的消息后,所述方法还包括:
写操作既可在缓存的数据量达到设定阈值时被触发,也可由数据写入磁盘成功的消息触发,两种触发方式通过任务锁进行互斥,确保同一时间只有一个写任务被触发;
当文件系统收到上一批数据写入磁盘成功的消息后,尝试触发下一次写操作,若任务锁尚未被抢占,则下一次写任务触发成功;否则,触发失败。
本发明实施例提供的基于嵌入式文件系统的流式数据写入方法,将接收的流式数据以链表结构进行组织,且每次写入磁盘的流式数据为一段逻辑和物理上均连续的数据,确保了流式数据写入的时序正常,写入流式数据时采用异步IO机制,还支持多核协作,提高了流式数据写入的效率。写入流式数据成功后,文件系统下层的写接口会发送写操作成功的通知消息,所述消息将触发下一次写操作。
实施例一
下面以图1为例详细说明本发明实施例一提供的基于嵌入式文件系统的流式数据写入方法,图1为本发明实施例提供的基于嵌入式文件系统的流式数据写入方法流程图,在本发明实施例中实施主体可以为文件系统。图2为本发明实施例提供的基于嵌入式文件系统的流式数据写入方法的消息驱动流程图。结合图1和图2所示,该方法包括如下步骤:
步骤101、接收待写入磁盘的流式数据;
流式数据指将数据看作是数据流的形式来处理,数据块是数据流的最小组成单元。这里接收的流式数据来自内容分发网络(Content DeliveryNetwork,CDN)分发的流式数据。
具体地,在接收写入文件的流式数据之前,还包括以下步骤来为写请求创建一个新的写任务:
步骤11,接收到一个新的流式数据写入请求后,判断系统中是否存在所述文件;
写请求的参数包括文件名、写入文件的起始偏移和写入文件的结束偏移。
具体地,计算待写的所述文件的文件名的哈希值,通过文件名哈希值来查找文件在文件系统中的索引号。
步骤12,如果不存在,则需要请求方手动建立所述文件;
步骤13,如果存在,则为所述请求新建一个写任务,通过找到的索引号从对应的索引节点中获取所述文件的元数据,并为所述任务分配存储空间,将所述文件名的哈希值、待写入数据的起始偏移和待写入数据的结束偏移存入所述任务空间。
在一个具体的例子中,上述步骤具体过程可以是:当收到一个写入流式数据的请求时,首先判断待写的文件是否存在于文件系统中。若所述待写文件不存在于文件系统中,则写请求失败,需要用户在请求前先手动新建此文件,再发起写入流式数据的请求。若所述待写文件存在文件系统中,通过找到的索引号可从对应的索引节点中获取该文件的元数据信息,并为该写请求新建一个写任务,为写任务分配存储空间,并将文件名哈希值、待写入流式数据的起始偏移和待写入流式数据的结束偏移等信息存入任务空间。
所述方法还包括对任务进行预处理:
具体地,写任务新建成功后,首先对写任务进行预处理:提取本次写任务的起始偏移和结束偏移,分别计算起始偏移和结束偏移对应于磁盘扇区中的位置,若起始偏移对应于磁盘扇区中的位置不为零,即不在扇区头,则将起始偏移对应的扇区中的数据读出并缓存;同理,若结束偏移对应于磁盘扇区中的位置不为扇区尾,也将结束偏移对应的扇区中的数据读出并缓存。当头/尾扇区的数据读取完成后,下层接口会以消息的形式报告读取结果,文件系统收到头/尾扇区数据成功读出的消息后,任务预处理完成,文件系统向用户报告任务就绪状态,用户收到报告后,才可从CDN接收流式数据。
步骤102、将接收的流式数据以链表结构进行组织,并将所述流式数据缓存于存储区,当缓存的流式数据的长度达到设定的阈值时,触发将缓存的流式数据写入磁盘的写操作;
链表的结构是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的,链表中每一个元素称为结点,链表由一系列结点组成,结点可以在运行时动态生成。
具体地,图3为流式数据以链表结构缓存的示意图,如图3所示,链表中的每一个节点代表了一块数据,该数据按流式数据格式进行封装。文件系统收到来自CDN的流式数据后,通过链表进行组织并缓存,每个节点中的数据长度取决于流式数据的封装格式,且除了最后一个缓存节点,所有节点中缓存的数据长度都相同,相邻节点缓存的数据在逻辑上具有连续性,而同一节点中缓存的数据却不保证在物理上连续,也就是说同一节点中缓存的数据可能被写入到物理上不相邻的扇区中。
当缓存的流式数据的长度达到设定的阈值时,便触发将流式数据写入磁盘的写操作,文件系统向下层接口提交流式数据,由下层接口将数据写入磁盘。
具体地,在所述触发将所述流式数据写入磁盘的写操作之后,还包括以下步骤来判断当前写操作是否为第一次写操作或最后一次写操作:
步骤21,计算当前写操作对应的起始偏移和结束偏移;
步骤22,如果当前写操作对应的起始偏移等于写任务的起始偏移,则所述当前写操作为第一次写操作;当第一次写操作对应的起始偏移对应于磁盘扇区中的位置不为扇区头时,则将第一次写操作对应的起始偏移与扇区头对齐,并利用缓存的头扇区数据填充第一次写操作中扩充的数据。
具体地,对于第一次写操作,需判断起始偏移对应于磁盘扇区中的位置是否为扇区头,若第一次写操作对应的起始偏移对应于磁盘扇区中的位置不为扇区头,则将第一次写操作的起始偏移移至该扇区头对应的偏移位置处,并利用缓存中的头扇区数据对应补齐。
步骤23,如果当前写操作对应的结束偏移等于写任务的结束偏移,则当前写操作为最后一次写操作。
当最后一次写操作对应的结束偏移对应于磁盘扇区中的位置不为扇区尾时,则将最后一次写操作对应的结束偏移与扇区尾对齐,并利用缓存的尾扇区数据填充最后一次写操作扩充的数据。
具体地,对于最后一次写操作,需判断结束偏移对应于磁盘扇区中的位置是否为扇区尾,若最后一次写操作对应的结束偏移对应于磁盘扇区中的位置不为扇区尾,则将最后一次写操作的结束偏移移至该扇区尾对应的偏移位置处,并利用缓存中的尾扇区数据对应补齐。
经过上述步骤的预处理和补齐后的写任务能确保每次写操作对应的起始偏移和结束偏移恰好对应于扇区头和尾,同时每次写入磁盘的数据长度也为扇区大小的整数倍,这满足了下层写接口的调用要求,保障了流式数据的正确写入。
步骤103、查询所述文件的元数据,获取存储文件内容的磁盘位置信息,根据所述磁盘位置信息,计算本次欲写入磁盘的流式数据长度,所述长度须为磁盘扇区大小的整数倍,且对应区段的数据在物理上和逻辑上均保持连续;
具体地,如图4所示为本发明实施例提供的写入流式数据的时序图,每次写操作被触发后,文件系统根据存放待写数据的磁盘位置信息、当前缓存的数据长度和设定的单次写入磁盘的最大数据长度,来计算出本次写操作将要写入磁盘的流式数据的长度,由该长度表征的本次写操作将要写入磁盘的数据可保证在物理上和逻辑上均连续。计算该长度的原则是在不超过设定的最大值前提下,单次写操作尽可能多地将当前缓存区中的数据写入磁盘。
步骤104、从缓存中取出所述长度的流式数据,取出数据的操作实则从缓存数据的链表中分离出一个所述长度的子链表:根据所述长度找到分离节点,从所述分离节点处截取流式数据,分离后的子链表对应的数据长度应与本次欲写入磁盘的流式数据长度相等;
根据当次写操作欲写入磁盘的数据长度,找到分离节点,将缓存流式数据的链表从分离节点后截断,复制所述分离点,将复制出的分离点作为剩余链表的头结点,调整原始分离节点和复制分离点中的数据起始偏移和数据长度。
具体地,文件系统从缓存中取出相应长度的数据,且取出的数据即为本次写操作将要写入磁盘的数据。其中,从缓存中取出一段数据实质上是从一个长链表中分离出子链表的过程,首先依次累加链表中节点数据的长度,当累加的数据长度大于等于本次写操作欲写入磁盘的数据长度时,即找到了链表的分离节点,分离节点中也存放着一块按既定格式封装的流式数据,而本次写操作可能只需要将给节点中的一部分数据写入,节点中剩余数据需在下次写操作中被写入磁盘。
在一个具体的例子中,每次写操作被触发后,文件系统会从缓存数据中取出指定长度的数据,从缓存中取出数据实际上就是从长链表中分离出一个子链表的过程,图5是本发明实施例中从分离节点处截取子链表的示意图,如图5所示,首先从头结点依次累加链表节点中的数据长度,找到链表的分离节点i,由于链表节点不可切分,而本次写操作中不需要将节点i中的数据全部写入磁盘,故复制节点i,将复制出的节点命名为i’,将链表从分离节点的尾部切断,并将节点i作为分离出的子链表的尾节点,而节点i’作为剩余链表的头结点,调整节点i和i’中的起始偏移和有效数据长度,确保分离出的子链表中所有节点累加的数据长度等于本次写操作待写入磁盘的数据长度,同时还需保证节点i和节点i’中有效数据长度之和与复制前节点i中的数据长度相同,即保证分离前后缓存中数据长度和内容不变。
步骤105、将分离出的流式数据写入磁盘;
步骤106、调用下层写接口将分离出的流式数据写入磁盘,写入数据时采用异步非阻塞模式,而非阻塞在将数据写入磁盘的过程中,待文件系统收到数据写入磁盘成功的消息后,尝试触发下一次写操作。
文件系统收到上一批数据写入磁盘成功的消息后,所述方法还包括:
写操作既可在缓存的数据量达到设定阈值时被触发,也可由数据写入磁盘成功的消息触发,两种触发方式通过任务锁进行互斥,确保同一时间只有一个写任务被触发。
当文件系统收到上一批数据写入磁盘成功的消息后,尝试触发下一次写操作,若任务锁尚未被抢占,则下一次写任务触发成功;否则,触发失败。
执行写操作的过程实际上是传入子链表地址、写入长度、写入磁盘的起始扇区号等信息,从而调用下层接口将分离出的数据写入磁盘的过程,写入数据采用异步IO机制,即调用后立即返回。下层接口将数据写入磁盘后会以消息的形式报告写入完成情况,文件系统收到上一次写入数据成功的消息后,尝试触发下一次写操作,若触发成功则执行下一次写操作,若文件系统收到上一次写入数据失败的消息,则向用户报告异常,由用户主动结束本次写操作。
文件系统收取来自CDN的流式数据,当缓存的数据达到一定量时,文件系统会尝试触发写操作,当收到上一次写入数据成功的消息后,文件系统也会尝试执行下一次写操作。所述方法采用任务锁的机制,确保同一时刻只能有一次写操作被触发,任何时候,只要写操作被触发则将任务锁打开,待收到上次写入数据成功的消息后才将任务锁关闭,当任务锁处于打开状态时,尝试执行下一次写操作的任何请求都会被拒绝。
当所有数据都已经被成功写入磁盘后,文件系统向用户报告完成,若某次写入磁盘出错,文件系统则向用户报告异常。用户收到任务完成或异常的消息后,主动调用由文件系统提供的结束任务的接口,结束任务时会清理掉任务相关的缓存空间和任务空间。
因此,本发明实施例提供的基于嵌入式文件系统的流式数据写入方法,将接收的流式数据以链表的结构进行组织,当缓存的流式数据的长度达到设定的阈值时,触发将所述流式数据写入磁盘的写操作。当写操作被触发后,文件系统在所述链表中选取分离节点,从所述分离点处截取子链表,从而了从缓存中分离出了当次写操作将要写入磁盘的数据,且该段数据为一段逻辑和物理上均连续的数据,数据长度为磁盘扇区大小的整数倍,从而满足了下层接口对写入磁盘的接口的调用要求,确保了流式数据的正确写入,所述方法采用异步IO机制,而非阻塞在写数据的过程中,待上一批流式数据写入成功后,文件系统下层写接口发送数据写入成功的通知消息,该消息可驱动下一次写操作,此外,所述方法还支持多核协,提高了流式数据写入的效率,保证了流式数据的高并发写入。
专业人员应该还可以进一步意识到,结合本文中所公开的实施例描述的各示例的单元及算法步骤,能够以电子硬件、计算机软件或者二者的结合来实现,为了清楚地说明硬件和软件的可互换性,在上述说明中已经按照功能一般性地描述了各示例的组成及步骤。这些功能究竟以硬件还是软件方式来执行,取决于技术方案的特定应用和设计约束条件。专业技术人员可以对每个特定的应用来使用不同方法来实现所描述的功能,但是这种实现不应认为超出本发明实施例的范围。
以上所述的具体实施方式,对本发明实施例的、技术方案和有益效果进行了进一步详细说明,所应理解的是,以上所述仅为本发明实施例的具体实施方式而已,并不用于限定本发明实施例的保护范围,凡在本发明实施例的精神和原则之内,所做的任何修改、等同替换、改进等,均应包含在本发明实施例的保护范围之内。