存储 频道

分布式存储系统的实现

  五.数据文件

  数据文件包括三个文件:字符串文件、目录文件、数据文件。字符串文件主要是考虑到敬惜人工智能系统平台是个提供开放服务的平台,因此数据名中必须有指示用户名的部分,当用户数据量很大的时候,目录文件中这部分开销会比较大,而且用户名的长度是变化的,直接保存很麻烦,所以最后参考MS对.net中字符串的处理方式用一个字符串文件统一保存,其它需要使用到该字符串的地方使用一个固定长度的字符串ID号来代表。

  目录文件使用固定大小的32字节的块来保存每个数据的访问信息,所有的数据目录都要保存到内存中,所以目录信息占用的内存会极大,因此使用Hash树来进行管理,由于文件读写操作较慢,为了在重负载情况下在目录访问的安全性和目录访问的高并发性之间达成一个平衡使用了1K个锁对象,利用hash码的后10个bit来分散互斥访问的**概率。

  为了减少在修改数据时因为空间不足引起的空间回收与再分配,在32字节的目录信息块中使用了若干字节来跟踪数据的写、空间分配等操作,并按一定策略进行空间放大的预分配来尽量减少空间的回收与申请。

  六.数据文件的空间管理

  数据文件按1KBytes为单位进行分配与回收,只包括数据,所有和数据相关的信息,如位置、大小等信息全部定义在目录信息中。

  数据空间的管理被划分为32MBytes的大块,每个大块的空间由一个FSM(FileFreeSpaceManager)对象进行管理。FSM只关心本对象所负责的空间中尚未分配出去的空闲空间,并将其按空间大小分别按本大块内位置为顺序拉链,空闲空间链包括1K、2 K、4 K、8 K、16 K 以及32 K组共6条。16 K以下的空间直接从相应大小的链中取第一个即可,不足则依次向上一大小的链中进行查找,16 K以上的空间则需要先从32 K块组中按32 K大小向上取整后分配,剩余部分再加入到相应的空闲空间链中。

  七.用户接口

  用户接口包括直接读写接口以及事务接口。事务接口前面已经描述过,直接的数据操作接口为了防止对系统的滥用而要求利用安全模块下的登陆功能登陆到系统后才能使用。

  系统存取的都是字节数据,而引擎等应用约定使用的数据格式为XML,所以专门做了一个校验XML Schema的类为XML数据在读取时进行校验。

  直接的数据接口还包括一个封装了锁操作的UserLock类,用于提供给用户进行资源保护,事务处理也使用了该类。

  提供直接的数据接口的主要考虑是对于只读的应用操作来说,使用事务过于笨重了,另外对于限制了用户同时多重登陆的应用来说,直接进行写操作其实也很安全,而且存储系统本身又不负责任何数据管理工作,所以最终出于效率的考虑同时提供了事务处理接口和直接访问接口供应用程序自行选择,同时也要求应用程序自行负责数据的完整性。

  目前所提供的所有用户访问接口都是同步操作接口。当用户读取数据时,会在读请求队列中插入一个读请求(如果有相同 Key值的数据在读请求队列中就会将读请求合并,当然这一点意义不是很大,因为读操作很快,对同一个数据并发读的可能性很小,而第一个程序读到数据后就会保留在本地Cache中,后续的读操作根本就不需要从网络读取),然后会将客户程序阻塞以等待FS响应,该阻塞会在2s后超时(读请求本身也会在4s后超时)。因为目前平台还只是考虑敬惜本身的使用,为了降低用户程序的复杂性所以尚未考虑提供异步操作接口。

  结语

  分布式存储系统最终的实现使用了30多个文件,上万行代码,虽然很麻烦,搞的笔者两三个星期睡不好觉,也很粗糙,还有好几个功能都太繁琐。但达到了以最低成本来实现任何一台主机宕机对系统都没有任何影响的初衷,用户程序的使用更是非常简单而功能也很强大。尤其是通过开发这个分布式存储系统笔者对分布式系统有了实践经验,虽然限于时间太紧张所以系统还很粗糙,但进一步将其发展成为分布式数据库或是分布式计算平台都有了更大的可能性。

0
相关文章