Blobstore中结构的划分,Blobstore是如何管理块的分配呢?

blobstore是位于spdk bdev之上的blob管理层,用于与用户态文件系统blobstore filesystem (blobfs)集成,从而代替传统的文件系统,支持更上层的服务,如数据库mysql、k-v存储引擎rocksdb以及分布式存储系统ceph、cassandra等。以rocksdb为例,通过blobfs作为rocksdb的存储后端的优势在于,i/o经由blobfs与blobstore下发到bdev,随后由spdk用户态driver写入磁盘。整个i/o流从发起到落盘均在用户态操作,完全bypass内核。此外,可以充分利用spdk所提供的异步、无锁化、zero copy、轮询等机制,大幅度减少额外的系统开销。它们之间的关系如下所示(以nvme bdev为例):
blobfs在管理文件时,主要依赖于blobstore对blob的分配与管理。blob类似于文件的概念,而又不完全等同于文件,其并不支持所有文件的posix接口。blobfs与blobstore的关系可以理解为blobstore实现了对blob的管理,包括blob的分配、删除、读取、写入、元数据的管理等,而blobfs是在blobstore的基础上进行封装的一个轻量级文件系统,用于提供部分对于文件操作的接口,并将对文件的操作转换为对blob的操作,blobfs中的文件与blobstore中的blob一一对应。在blobstore下层,与spdk bdev层对接。spdk bdev层类似于内核中的通用块设备层,是对底层不同类型设备的统一抽象管理,例如nvme bdev、malloc bdev、aio bdev等。
blobstore中结构的划分
在blobstore中,将ssd中的块划分为多个抽象层,主要由logical block、page、cluster、blob组成,它们之间的关系如下所示:
logical block:与块设备中所提供的逻辑块相对应,通常为512b或4kib。
page:由多个连续的logical block构成,通常一个page的大小为4kib,因此一个page由八个或一个logical block构成,取决于logical block的大小。在blobstore中,page是连续的,即从ssd的lba 0开始,多个或一个块构成page 0,接下来是page 1,依次类推。
cluster:由多个连续的page构成,通常一个cluster的大小默认为1mib,因此一个cluster由256个page构成。cluster与page一样,是连续的,即从ssd的lba 0开始的位置依次为cluster 0到cluster n。
blob:blobstore中主要的操作对象为blob,与blobfs中的文件相对应,提供read、write、create、delete等操作。一个blob由多个cluster构成,但构成blob中的cluster并不一定是连续的。
那么blobstore是如何管理块的分配呢?
在blobstore中,会将cluster 0作为一个特殊的cluster。该cluster用于存放blobtore的所有信息以及元数据,对每个blob数据块的查找、分配都是依赖cluster 0中所记录的元数据所进行的。cluster 0的结构如下:
cluster 0中的第一个page作为super block,blobstore初始化后的一些基本信息都存放在super block中,例如cluster的大小、已使用page的起始位置、已使用page的个数、已使用cluster的起始位置、已使用cluster的个数、blobstore的大小等信息。
cluster 0中的其它page将组成元数据域(metadata region)。元数据域主要由以下几部分组成:
metadata page allocation:用于记录所有元数据页的分配情况。在分配或释放元数据页后,将会对metadata page allocation中的数据做相应的修改。
cluster allocation:用于记录所有cluster的分配情况。在分配新的cluster或释放cluster后会对cluster allocation中的数据做相应的修改。
blob id allocation:用于记录blob id的分配情况。对于blobstore中的所有blob,都是通过唯一的标识符blob id将其对应起来。在元数据域中,将会在blob allocation中记录所有的blob id分配情况。
metadata pages region:元数据页区域中存放着每个blob的元数据页。每个blob中所分配的cluster都会记录在该blob的元数据页中,在读写blob时,首先会通过blob id定位到该blob的元数据页,其次根据元数据页中所记录的信息,检索到对应的cluster。对于每个blob的元数据页,并不是连续的。
对于一个blob来说,metadata page记录了该blob的所有信息,数据存放于分配给该blob的cluster中。在创建blob时,首先会为其分配blob id以及metadata page,其次更新metadata region。当对blob进行写入时,首先会为其分配cluster,其次更新该blob的metadata page,最后将数据写入,并持久化到磁盘中。
为了实现对磁盘空间的动态分配管理,blobstore中为每个blob分配的cluster并不是连续的。对于每个blob,通过相应的结构维护当前使用的cluster以及metadata page的信息:clusters与pages。cluster中记录了当前该blob所有cluster的lba起始地址,pages中记录了当前该blob所有metadata page的lba起始地址。
blobstore实现了对磁盘空间分配的动态管理,并保证断电不丢失数据,因此blob具有persistent特性。blobstore中的配置信息与数据信息均在super block与metadata region中管理,在重启后,若要保持persistent,可以通过blobstore中所提供的load操作。
注意:
blob的persistent主要是针对nvme这类bdev。对于malloc bdev,由于其本身的性质,是无法保证blob的persistent,需要重启后进行重新配置。
下面通过文件的读写来讲解blobfs与blobstore中的i/o流程:
文件读取:文件读取操作的流程图如下所示:
为了提高文件的读取效率,blobfs在内存中提供了cache buffer。在文件读写时,首先会进行read ahead操作,将一部分数据从磁盘预先读取到内存的buffer中。其后,根据cache buffer的大小,对文件的i/o进行切分,使每个i/o的最大长度不超过一个cache buffer的大小。对于拆分后的文件i/o,会根据其offset在cache buffer tree中查找相应的buffer。若存在,则直接从cache buffer中读取数据,进行memcpy。而对于没有缓存到cache buffer中的数据,将会对该文件的读取,转换到该文件对应的blob进行读取。对blob读取时候,根据已打开的blob结构中记录的信息,可以获取该blob所有cluster的lba起始位置,并根据读取位置的offset信息,计算相应的lba地址。最后向spdk bdev层发送异步的读请求,并等待i/o完成。blobfs所提供的读操作为同步读,i/o完成后会在callback函数中,通过信号量通知blobfs完成信号,至此文件读取结束。
对于cache buffer tree,其结构如下所示:
cache buffer tree是由多层树结构组成。最底层level 0叶子节点为buffer node,是用于存放数据的buffer。level 0以上的其它层中,均为tree node,用于构建树的索引结构。在文件读写的时候,根据文件结构中的根节点以及读取位置的offset信息,在树结构中通过索引查找buffer node的位置,即从level n,逐步定位到对应的level 0的叶子节点。
文件写入:文件写入操作的流程图如下所示:
blobfs目前用于支持上层的rocksdb,在rocksdb的抽象环境层中提供文件的接口,目前仅支持append类型的写操作。在进行文件写入时,首先会根据文件当前的写入位置检查是否符合cache buffer写入需求,若满足,则直接将数据写入到cache buffer中,同时触发异步的flush操作。在flush的过程中,blobfs触发blob的写操作,将cache buffer中的数据,写入到文件对应blob的相应位置。若不满足cache buffer的写入需求,blobfs则直接触发文件对应的blob的写操作。blobstore首先为该blob分配cluster,根据计算得到的写入lba信息,向spdk bdev层发送异步的写请求,将数据写入,并更新相应的元数据。对于元数据的更新,出于性能考虑,当前对元数据的更新都在内存中操作,当用户使用强制同步或卸载blobstore时,更新后的元数据信息才会同步到磁盘中。此外,blob结构中维护了两份可变信息(指cluster与metadata page)的元数据,分别为clean与active。clean中记录的是当前磁盘的元数据信息,而active中记录的是当前在内存中更新后的元数据信息。同步操作会将clean中记录的信息与active记录的信息相匹配。
总结
blobstore实现对blob管理,blob类似与文件的概念,但又不完全等同于文件,blob没有完全遵循文件的posix接口,因此避免与文件混淆,在spdk中称之为blob而不是file。blobstore filesystem (blobfs)是基于blobstore实现的轻量级文件系统,对blobstore进行封装,提供一些文件的常用接口,如read、write、open、sync等,其目的在于作为文件系统支持更上层的应用,例如rocksdb。但其本质仍然是blobstore,因此命名为blobfs。目前spdk基于维护了rocksdb的一个分支,该分支下的rocksdb在环境抽象层主要通过blobfs进行对接,i/o可以经由blobfs绕过内核i/o栈。关于rocksdb的搭建与测试步骤,可以参考[3]。

巴西中央银行将在2020年11月启动一个新的基于区块链技术的支付系统
全球光伏产业面临整合
5G从热炒的概念到万元终端正在加速贴近用户越来越触手可及
煤磨选粉机冲刷磨损的修复方法
抢先看!爱心链首登世界区块链大会 慈善竞拍加措活佛书法全场瞩目
Blobstore中结构的划分,Blobstore是如何管理块的分配呢?
AMD宣布Pervasive AI 开发者挑战赛,以激发令人兴奋的现实应用
通过ARM9扩展串口和LCD接口实现155B转换卡的设计
高亮度LED之"封装光通"原理技术探析
什么是LTDF石墨烯?为什么它是复合材料的最佳选择?
智能制造能力成熟度国家标准正式发布
从300万高价AI画作 看计算机视觉的商业应用
三星Galaxy S10将采用无线快速充电2.0技术从此结束15w充电
2018年中国大陆电竞显示器全年出货量达到126万台
工业自动化开关量输入输出采集控制网关
储能连接器出现的问题主要有几方面(采购问答)
单片机脉冲计数器程序详解
人工智能进入工业大生产阶段
消防余压探测器的安装须知
苹果新版iPhone支持中国移动3G网络实现全球化的原因