原本本篇是想介绍前端组件化开发用户界面,发现框架还未实现文件存储,本来计划是后续设计开发的,索性把计划提早,因此本篇将介绍基于Raft实现分布式的文件存储引擎。html
既然是分布式存储,就须要解决如下几个关键问题:前端
开始时想设计为一个集群对应一个BlobMetaRaftGroup,后来考虑到单个RaftGroup可能会压力较大,因此改成每一个Application对应一个BlobMetaRaftGroup。每一个元数据状态机主要存储如下各项信息:git
确认了须要存储哪些信息后,就须要确认如何将这些数据映射至底层的KV存储,既要保证高效又要方便Api检索这些元数据,通过一些尝试后最终定为如下方案。github
TypeFlag | AppId | 目录名称UTF8编码 |
---|---|---|
8bit | 8bit | n bit |
目录Id | Chunk RaftGroup数量 | Chunk RaftGroupIds |
---|---|---|
128bit | 16bit | n * 64bit |
TypeFlag | AppId | 目录Guid | 分隔占位 | 名称UTF8编码 |
---|---|---|---|---|
8bit | 8bit | 128bit | 8bit | n bit |
文件Id | 文件大小 | Chunk RaftGroupId |
---|---|---|
128bit | 32bit | 64bit |
根据上述设计,每一个目录下的文件分红了多个存储组(BlobChunkRaftGroup),原本想用MemoryMapFile来实现底层Chunk存储,但考虑到有更重要的功能要实现因此暂偷懒直接利用Linux文件系统来存储文件,状态机Apply文件写命令时,将文件直接写入节点运行时blob/ChunkRaftGroupId/目录下。浏览器
根据以上设计在经历了1个月的编码后已初步实现(其中约一半时间在更改架构,抛弃了Mono依赖,改成Hosting CoreCLR,性能提高1倍),在框架IDE内每一个Application内有个"BlobStore"节点,以下图所示可测试上传文件,而后经过浏览器访问上传至/pub目录内的文件(http://{地址:端口}/blob/{app名称}/{文件路径} eg: http://xx.xx.xx.xx:5000/blob/sys/imgs/aa.jpg)
缓存
做者简单测试了一下经过框架WebHost下载文件的性能(测试时还没有实现缓存元数据, 虚拟机I74C8G),以下图所示:
架构
本实现适用于存储大量小文件,如业务单证的附件,或者用于OA系统做为文档库。目前只是实现了基本的上传下载功能,删除、重命名、Chunk合并等功能还没有实现,另待未来框架实现反向索引后再实现全文搜索功能。并发
框架已更新,如何安装测试请参考AppBoxFuture(一): Hello Future!。若是您有问题或Bug报告,请留言或在Github提交Issue。app