由于FileStore底层仍然通过操作系统自带的本地文件系统管理磁盘,所以为了能够使用本地文件系统,所有针对RADOS的操作都需要转换成POSIX语义。
所以引入了BlueStore直接管理文件。
1.设计原理
文件系统提供的核心操作就是读和写,BlueStore也是。
对于文件系统,读操作除非缓存命中,否则都是从磁盘读出数据;而对于写操作,一般都是写入内存即可应答,再由文件系统合适组织写入磁盘,以此达到加速写性能。
但由于内存掉电数据会丢失,为了保证可靠性,BlueStore采用日志、双写来加速写操作,也就是先写入缓存NVRAM或者SSD,再写入磁盘。
BlueStore引入日志后,接踵而来的问题是,NVRAM或者SSD可以充当缓存的原因是I/O时延非常低,但是对于海量数据的写入,时延已经不是瓶颈,数据传输的时间才是瓶颈,所以当有海量数据写操作时,写日志虽然写进缓存很快,但是仍有大部分时间消耗给数据传输,再由于双写,性能损失反而更加严重。
所以BlueStore的写操作采用首尾块非对齐部分采用写日志RMW策略,中间对齐的大部分数据采用重定向写COW策略
BlueStore提供的读写API的粒度是PG,读是并发的,写是排他的。也就是同一时间两个线程可以同步执行读同一个PG的数据,但是只能互斥写同一个PG。
读请求是同步的,但出于效率考虑,写请求是异步的,所以对每一个PG还有一个FIFO队列OpSequencer来给写请求保序。
同步异步的意思是线程没有读完会阻塞,没有写完不会阻塞。
2.磁盘数据结构
BlueStore的对象类似于文件,我们知道文件是依靠每个文件专属的元数据inode记录了本文件的大小、文件数据所在的扇区地址等信息。BlueStore的元数据结构叫onode,也是记录了对象大小和数据位置等信息,具体如下:
其中size是对象大小、而extent_map_shards则记录了extent-map在RocksDB数据库的索引,也就是说每个对象有一个onode,onode包含了一张extent-map,而extent-map很大所以存储在数据库中。
extent-map记录了对象数据在磁盘的地址。extent-map具体如下:
其中extent_map包含了对象的若干个逻辑数据段extent(每个逻辑段并不一定连续且与磁盘块对齐)。
extent具体如下:
其中blob记录了该逻辑段对应的磁盘物理段。
blob_offset用于逻辑段extent的强制对齐,从而方便了映射磁盘物理段:
blob结构具体如下:
由于每个逻辑段extent在物理磁盘上并不一定连续,属于逻辑段和物理段是一对多的关系,所以表中extents记录了多个物理段pextent。
pextent结构具体如下:
上述的offset、length一定是块的整数倍。
整体结构图如下:
3.缓存机制
缓存替换算法本质是对于未来的读写请求序列,依靠时空局部性原理进行预测,因此如果请求序列完全随机,那么任何算法不可避免存在误淘汰的可能。