作者:吴香伟 发表于 2017/02/19
版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明


简单回顾下Ceph OSD后端存储引擎的历史。

为解决事务原子性问题,最早的FileStore存储引擎引入了Journal机制,一个IO先同步写日志,再异步写文件,这在解决原子性问题的同时也引入了写放大的问题,一次IO两次落盘。NewStore通过Onode索引解耦Object和文件,让IO直接写文件,写成功后更新Onode元数据,从而避免两次落盘问题(特殊情况下还是需要先写日志)。NewStore虽然解决了写放大问题,但不够彻底,无法消除本地文件系统带来的消耗。于是,BlockStore登场,在NewStore基础上抛开本地文件系统直接管理裸块设备。直接管理磁盘首先要做两件事情:

(1) 磁盘空间分配;

(2) 将Object数据映射到磁盘;

本文重点分析BlueStore对这两个问题的解决。

概念

Onode 代表一个Object,类似于VFS中的Inode索引节点;
lextent Object的逻辑范围;
blob 为Onode分配的一组磁盘空间,可以被多个lextent共享;
pextent 一段连续的物理磁盘空间,默认最小单位为4K字节。一个blob的磁盘空间由多段不连续的物理磁盘空间组成。

磁盘空间分配

概念。
Block 大小为4K字节的一段磁盘空间;
BmapEntry 为一整型,整型的每个bit位代表一个Block;
Zone 一组空间上连续的Block的集合,Block数目默认为1024;
Span 一组空间上连续的Zone的集合,Zone数目默认为1024;

磁盘分配器Allocator将裸块设备划分成固定大小的Block,分配、释放磁盘空间时以Block作为最小单元。目前BlueStore提供了两种磁盘分配策略,一种称为Stupid,另一种称为Bitmap,Bitmap为默认配置,本节重点分析Bitmap磁盘管理。Bitmap(位图)管理磁盘空间的基本思路是,使用一个bit位的两种状态0或者1来表示一个Block空闲或已分配两种状态。Bitmap是本地FS管理磁盘的一种常用方式,对于一个已经格式化过的块设备,文件系统会在Superblock中持久化元数据,记录哪些Block已被使用哪些Block空闲。BlueStore同样需要记录这些信息,不过将它记录在KV数据库,OSD进程启动时从KV中加载Block块状态,构建出如上图所示的树形结构。

树形结构的每个节点会统计以此为根的子树中包含的空闲磁盘空间和已分配磁盘空间的字节数,这在分配连续大块的磁盘空间时可以跳过空间不足的子树,快速定位到剩余空间能够满足要求的子树,从而提高分配效率。不过,树形结构也会带来一些问题。两棵相邻子树会将原本连续的磁盘空间分隔开,可能存在这样的情况,左边子树中最右边的Block是空闲的,右边子树的最左边Block是空闲的,那么将两棵子树合并在一起也能够分配出一段连续空间。对于这个问题,BlueStore只考虑Zone内不同BmapEntry间的情况,对粒度更大的子树就不做考虑了。

Object数据对齐

向bluestore_min_alloc_size对齐。
bluestore_min_alloc_size是Onode申请磁盘空间的最小单元,固态硬盘默认为64K字节,HDD默认4K字节。Onode每次申请磁盘空间的大小都是bluestore_min_alloc_size的整数倍,申请到的磁盘空间由blob结构来管理。

如何确定是否要为一个写IO分配磁盘空间,分配多少磁盘空间?

Onode对磁盘空间的分配是“精简配置”模式,对一个只在1024K到1088K位置有数据的Object,只要为其分配64K字节而不是1088K字节的磁盘空间。上图给出了写IO修改范围和Object旧数据间的重叠关系,假设IO修改范围和旧范围都足够大,那么每个旧范围可能都有自己独立的磁盘空间。通过把IO修改范围对齐到bluestore_min_alloc_size,将IO修改范围分割成3部分:头部、中间部分和尾部。对中间部分,直接丢弃重叠的旧范围所分配的磁盘空间,为中间部分重新分配物理上连续的磁盘空间;对头部和尾部,考虑将IO修改范围应用到已分配的磁盘空间。

为什么单独为中间部分重新分配磁盘空间,而不为头、尾部分也重新分配磁盘空间?
跟中间部分重叠的若干旧范围,这些旧范围分配的磁盘空间在物理上可能并不连续,在不连续的物理磁盘中读取逻辑上连续的数据, 性能必然会低。第二个原因是这些旧范围中的旧数据,即将被新数据覆盖,已经成为无效数据,弃之并不可惜。头部和尾部可能需要新分配磁盘空间,也可能直接使用已分配的磁盘空间。在使用已有磁盘空间的情况下,已有磁盘空间中包含旧数据,这些旧数据可能与新数据有重叠部分(如上图的尾部),可能和新数据没有重叠部分(如上图的头部)。已有磁盘空间中没有和新数据重叠的数据仍然是有效数据,如果重新分配磁盘空间则需要将这部分有效数据迁移到新磁盘空间,得不偿失。

向bdev_block_size对齐。
bdev_block_size是磁盘能分配的最小单元,默认4K字节。传统机械硬盘的最小读写单元是扇区,扇区大小为512字节,如果写入的数据小于512字节,则需要先读取扇区内容合并后再写入。SSD最小读写单元是页,页大小为4K字节。读取,合并,再写入,将严重降低写性能,不可不考虑。解决方法很直接,对没对齐的修改数据,补零,将其对齐到bdev_block_size大小。

中间部分已经按照bdev_block_size对齐,原因是,中间部分按照bluestore_min_alloc_size对齐,而bluestore_min_alloc_size已经按照bdev_block_size对齐,故而中间部分默认已经bdev_block_size对齐。对首、尾部分又可以再分为两种情况:一种情况是对齐后,补零部分和Object的旧数据没有重叠,如上图(b)和(c)所示;另一种情况是对齐后,补零部分和Object的旧数据重叠,如上图(a)所示,这种情况不能直接补零,否则将覆盖旧数据。针对覆盖旧数据的问题,先从磁盘读取数据本应该补零的数据,用这部分数据填充新数据以达到对齐的目的。

Ceph BlueStore 解析:Object IO到磁盘的映射的更多相关文章

  1. [ ceph ] BlueStore 存储引擎介绍

    为什么需要 BlueStore 首先,Ceph原本的FileStore需要兼容Linux下的各种文件系统,如EXT4.BtrFS.XFS.理论上每种文件系统都实现了POSIX协议,但事实上,每个文件系 ...

  2. 开源实践分享:Ceph bluestore部署实践

    https://blog.51cto.com/99cloud/2119884 Ceph bluestore部署 首先为大家分享Ceph bluestore具体该如何部署,使用环境如下• 单节点• Ce ...

  3. ceph存储引擎bluestore解析

    原文链接:http://www.sysnote.org/2016/08/19/ceph-bluestore/ ceph后端支持多种存储引擎,以插件式的方式来进行管理使用,目前支持filestore,k ...

  4. ceph存储 ceph Bluestore的架构

    ceph 目前是开源社区比较流行的分布式块存储系统,其以良好的架构,稳定性和完善的数据服务功能,获得的了广泛的部署和应用. 目前ceph 最大的问题是其性能相对较差,特别是无法发挥SSD等高速设备的硬 ...

  5. Ceph Bluestore首测

    Bluestore 作为 Ceph Jewel 版本推出的一个重大的更新,提供了一种之前没有的存储形式,一直以来ceph的存储方式一直是以filestore的方式存储的,也就是对象是以文件方式存储在o ...

  6. ceph bluestore与 filestore 数据存放的区别

    一. filestore 对象所在的PG以文件方式放在xfs文件中 1 查看所有的osd硬盘,跟其他linux其他硬盘一样,被挂载一个目录中. [root@hz-storage1 ~]# df -h ...

  7. ceph bluestore的db分区应该预留多大的空间

    前言 关于bluestore的db应该预留多少空间,网上有很多资料 如果采用默认的 write_buffer_size=268435456 大小的话 那么几个rocksdb的数据等级是 L0: in ...

  8. C# IO操作磁盘上的txt

    using System.IO; //写入并导出到磁盘 StreamWriter sw = new StreamWriter(@"H:\text.txt"); sw.WriteLi ...

  9. 网络IO和磁盘IO详解

    1. 缓存IO 缓存I/O又被称作标准I/O,大多数文件系统的默认I/O操作都是缓存I/O.在Linux的缓存I/O机制中,数据先从磁盘复制到内核空间的缓冲区,然后从内核空间缓冲区复制到应用程序的地址 ...

随机推荐

  1. iOS第三方常用类库

    1.AFNetworking AFNetworking 采用 NSURLConnection + NSOperation, 主要方便与服务端 API 进行数据交换, 操作简单, 功能强大, 现在许多人 ...

  2. js-权威指南学习笔记8

    第8章 函数 1.参数有形参和实参的区别,形参相当于函数中定义的变量,实参是在运行时的函数调用时传入的参数. 2.函数表达式可以包含名称,这在递归时很有用. 3.函数定义表达式特别适合用来定义那些只会 ...

  3. mongodb学习(五) 查询

    1. 按条件查询: db.users.find({"name":"MM1"}) 2.find的第二个参数可以指定要返回的字段:这里1 表示要显示的字段,0 表示 ...

  4. iOS 之 获取View所在控制器

    1. UIResponder UIViewController *uvc; UIResponder* nextResponder = [self.superview.superview.supervi ...

  5. java 之 Spring 框架(Java之负基础实战)

    1.Spring是什么 相当于安卓的MVC框架,是一个开源框架.一般用于轻型或中型应用. 它的核心是控制反转(IoC)和面向切面(AOP). 主要优势是分层架构,允许选择使用哪一个组件.使用基本的Ja ...

  6. GWAS

    GWAS的数据形式:SNP数据,即各个SNP位点的aa,Aa,AA基因型与疾病状态(0正常,1患病)的样例-对照数据. 在遗传流行病学上,全基因组关联研究(Genome Wide Associatio ...

  7. iOS 之 Strong与Weak,_unsafe _unretained与weak区别

    1. 在ARC中 strong(强引用) 相当于retain, weak(弱引用) 相当于assign.ARC下,strong告诉编译器自动插入retain.但是在ARC下,代理协议的属性依然用ass ...

  8. 转:找不到include xgpio.h;Unresolved include xgpio.h

    这个文档讲解的是在SDK下出现的问题,如果在ISE下编译是有错的,不能正常进入SDK,那这篇文档不适合你. 问题是这样的.根据教程<XILINX FPGA Verilog编程大全>做SOC ...

  9. xshell安装运行时提示缺少mfc110.dll

    下载最新的mfc110.dll文件 https://pan.baidu.com/share/link?shareid=1932421734&uk=1784696518&app=zd 之 ...

  10. 如何使用PDO查询Mysql来避免SQL注入风险?ThinkPHP 3.1中的SQL注入漏洞分析!

    当我们使用传统的 mysql_connect .mysql_query方法来连接查询数据库时,如果过滤不严,就有SQL注入风险,导致网站被攻击,失去控制.虽然可以用mysql_real_escape_ ...