张 璐 杨东芳
(1.驻马店职业技术学院信息工程系,河南 驻马店463000;2.黄河交通学院机电工程学院,河南 焦作454950)
随着计算机科学技术的飞速发展,信息逐渐被数据化,海量小文件的存储给系统带来巨大的压力。首先文件系统在存储小文件时需要反复请求存储的地址,分配存储空间,海量的小文件一起存储就会占用服务器的内存从而超出计算机硬件的极限;其次,海量小文件的存储使检索效率降低。现有的存储系统由于内存的现状,当存放文件积累到一定数量,就没法做到有效管理,从而导致检索效率降低,甚至导致系统崩溃。因此,解决小文件访问性能瓶颈的问题越来越迫切。
结构化存储是在数据库中将小文件整合成一个大文件一次性写入,将小文件的内容作为二进制字符串的大字段存入数据库中,由于每个字段都是固定的,而小文件则是在一定范围内变化的,为了保证数据不因字段长度不够而丢失,故在设计数据库时会将字段设计得相对比较大,这样就使小文件内容的存储占据了大量的空白数据,造成磁盘资源的浪费,也会使数据库在进行I/O操作时操作时间变长[1]。
归档文件是将文件合并后放入文件存档设备,在文件系统上创建一个文件系统进行工作,虽然采用创建归档文件来处理小文件能够降低内存的使用效率,但创建归档文件的同时会创建一个副本,需要同样大小的磁盘空间,而且一旦创建后,归档文件就不能再改变,所以要增加或删除文件时必须重新创建文件。
在分布式文件系统上设计一个小文件优化器,将小文件在优化器中进行合并,并且建立索引,这样所有操作都在优化器中完成,而大文件直接存储在文件系统,虽然避免了海量小文件存储的麻烦,但如果小文件索引多到无法估计,就对优化器磁盘的容量提出挑战。
构建结构体是将相同扩展名的小文件进行合并,元数据存储于结构体的成员中,通过建立结构体中各文件间的存储索引[2]。访问时只需读取要查找文件的扩展名,然后访问名称节点,名称节点根据该扩展名返回一个索引块列表;最后用户根据这个块列表访问相应的数据结构体,在数据结构体中根据元数据进行截取,查找到原先的小文件进行截取并返回。虽然将多个小文件合并成一个大文件的方案能使原先小文件占用的名称节点服务器的内存成倍数地降低,但是由于结构体在定义时已经设定了成员的大小,所以对于同类型但大小不一的小文件,传统的合并方法会浪费大量的存储空间。
在归档文件方法和文件优化器处理思想的基础上进行改进,能够使文件优化器的功能由传统的结构化数据库来实现。数据库能存储海量块小的元数据,能快速建立索引,检索速度比较快;而分布式文件系统可以多个存储磁头并行读写,文件的存储和读取带宽较大,能够突破数据库存取的I/O瓶颈问题。文件系统与数据库系统各尽其能,弥补了对方的不足[3-4]。由于实时存储系统在这一时刻和下一时刻传入的文件类型可能不同,不属于同一个业务,可以根据他们不同的访问字段来对部分常用字段建立非聚集索引,在不过分影响插入效率的前提下提高用户查找文件的速度。
在合并文件时需要创建文件头,记录大文件中包含的小文件个数以及每个小文件的大小,并且与小文件放置在同一块大缓存内,在数据库中记录文件的元数据信息及相应的大文件和在大文件中的具体位置,与构建结构体进行文件合并的方法相比,创建文件头的合并机制更适合于文件大小有变动的海量小文件的合并,在进行文件读取时通过查询数据库来获取文件的逻辑地址并且对文件进行访问。
首先,创建一个PingFile的类,其中包括:Name:大文件的文件名称;size[count]:用于记录每个小文件的大小;*addr[count]:用于记录每个小文件的内存地址;timecount:用于记录当前PingFile存在的时间;current:用于记录当前状态传入的参数,要求存入PingFile的相对位置。count表示大文件中小文件数量的上限,timelimit表示等待时间的上限,当等待时间或数量达到上限时,开启线程将PingFile中小文件的缓存按照表1的结构形式合并为一个大缓存并存入到文件系统中,提交本次数据库的事务,完成一次小文件的合并及其元数据的入库。程序接收到传入的小文件,根据传入的相关参数将文件块存入大的缓存区内,并将小文件在大文件中的相对位置和大文件的命名作为元数据,放在数据库事务中,以便保持数据库和文件系统的一致性,然后继续等待下一文件的传入。当缓存区的文件达到合成条件时,将缓存块生成数据文件存放在文件系统中,数据库再次提交事务(见表1)。
表1 大文件缓存结构
在读取文件时,首先根据查找信息在数据库中查找相应的数据条目,如果找不到就直接返回,如果找到就遍历所有的结果集,找到大文件的地址以及小文件在大文件中的相对位置,然后对大文件进行解析,根据小文件的存储位置在缓存中取出小文件并返回给用户,完成文件的读取操作。
表2 合并文件个数与合并、读取时间关系表
图1 合并文件个数与合并、读取时间关系图
使用本地文件系统将300个不同的图形文件(32KB至512KB不等)进行合并,之后对其进行逐一读取,最后得到的图形文件与原文件完全相同,其可行性得到了验证。表2为512KB大小不同数目的小文件合并读取的时间对比(时间为十次测试的平均值,每次读取的是第30个小文件)。从图1可以看出,合并与读取所用时间基本和合并个数呈线性关系。
针对文件系统实时存储海量小文件不方便,提出了基于数据库的小文件合并方法,即对大量小文件的数据进行批量处理,在保证存取前后系统的稳定性和文件正确性的前提下,大幅度提高了文件系统对小文件存储效率。通过文件系统与数据库的结合,解决了文件系统的检索瓶颈和数据库I/O瓶颈问题,减少了存储时间。但是需要指出的是,由于进行了文件合并,如果要对单个小文件进行修改操作,则需要对大文件中的片段进行解析、扩展或者缩减,会造成单个小文件更新操作的不方便。所以,该方法适用于量多块小、时间分布均匀且更新频度较小的数据仓库类的工作业务流程。
[1]江柳.HDFS下小文件存储优化相关技术研究[D],北京邮电大学,2010.
[2]http://hadoop.apache.org/mapreduce/docs/r0.21.0/hadoopp_archives.html.
[3]刘小俊,徐正全,潘少明.一种结合RDBMS和Hadoop的海量小文件存储方法[J].武汉大学学报,2013(1):27-31.
[4]泰冬雪.基于Hadoop的海量小文件处理方法的研究[D].辽宁大学,2011.