ceph 目前是开源社区比较流行的分布式块存储系统,其以良好的架构,稳定性和完善的数据服务功能,获得的了广泛的部署和应用。

目前ceph 最大的问题是其性能相对较差,特别是无法发挥SSD等高速设备的硬件的性能。 Ceph 开源社区一直在优化ceph的性能问题。 目前的结果就是引入了新的object store,这就是最进合并入ceph master的BlueStore.

Bluestore的架构

如上图所示 :

BlueStore整体架构分为四个部分:

  • BlockDevice为最底层的块设备,BlueStore直接操作块设备,抛弃了XFS等本地文件系统。BlockDevice在用户态直接以linux系统实现的AIO直接操作块设备文件。
  • BlueFS是一个小的文件系统,其文件系统的文件和目录的元数据都保存在全部缓存在内存中,持久化保存在文件系统的日志文件中, 当文件系统重新mount时,重新replay该直接,就可以加载所有的元数据到内存中。其数据和日志文件都直接保存在依赖低层的BlockDevice中
  • RocksDB 是Facebook在leveldb上开发并优化的KV存储系统。BlueFS的主要的目的,就是支持RocksDB
  • BlueStore是最终基于RocksDB和BlockDevice实现的ceph的对象存储,其所有的元数据都保存在RocksDB这个KV存储系统中,包括collection,对象,omap,磁盘空间分配记录等都保存RocksDB里, 其对象的数据直接保存在BlockDevice

BlockDevice

BlockDevice 块设备,其对于一个物理块设备(目前也支持用XFS的一个大文件里实现),用来存储实际的数据。其实现在bluestore/BlockDevice.cc 和 bluestore/BlockDevice.h

其主要实现了异步写操作,写操作是通过 操作系统提供的异步io调用。 由于操作系统支持的aio操作只支持directIO,所以对BlockDevice的写操作直接写入磁盘,并且需要按照page对齐。其内部有一个aio_thread 线程,用来检查aio是否完成。其完成后,调用 aio_callback_t aio_callback; 回调函数通知调用方。 
目前BlocekDevice的读操作是同步读操作。 有待继续实现异步的读操作

BlueFS

BlueFs 既然是一个文件系统,就要解决的是元数据的分配管理,其次解决文件空间的分配和管理,以及磁盘空间的分配和管理。

由于BlueFS用来支持RocksDB,所以就不是一个通用的文件系统,它的功能足以支持RocksDB 就可以了。所以它只支持以下功能:

  • 文件只支持顺序写
  • 只支持两层目录

BlueFS的元数据

BlueFS中,文件的元数据由 bluefs_fnode_t 保存

struct bluefs_fnode_t {
uint64_t ino; //文件的ino
uint64_t size; //文件大小
utime_t mtime; // 修改时间
uint8_t prefer_bdev; //优先在该设备上分配空间
vector<bluefs_extent_t> extents; //文件在磁盘上分配的空间
......
} bluefs_extents_t 代表在磁盘上的分配的extents
struct bluefs_extent_t {
uint64_t offset; //块设备上的 extent偏移量
uint32_t length; // extent的长度
uint16_t bdev; //对于的块设备
......
}

目录对应的结构 Dir

struct Dir {
map<string,FileRef> file_map;
};

对于BlueFS

  • 所有的元数据(文件和目录)都需要缓存在内存中
  • 所有的元数据的修改都记录在BlueFS的日志中,也就是对于BlueFS,元数据的持久化保存在日志中,当重新mount文件系统时,只需要replay日志,就可以获取所有元数据
//BlueFS的元数据cache
map<string, Dir*> dir_map; ///< dirname -> Dir
ceph::unordered_map<uint64_t,FileRef> file_map; ///< ino -> File

BlueFS的读写

uint64_t size = 1048476 * 128;
string fn = get_temp_bdev(size);
BlueFS fs;
ASSERT_EQ(0, fs.add_block_device(0, fn));
fs.add_block_extent(0, 1048576, size - 1048576);
uuid_d fsid;
ASSERT_EQ(0, fs.mkfs(fsid));
ASSERT_EQ(0, fs.mount());
{
BlueFS::FileWriter *h;
ASSERT_EQ(0, fs.mkdir("dir"));
ASSERT_EQ(0, fs.open_for_write("dir", "file", &h, false));
bufferlist bl;
bl.append("foo");
h->append(bl);
bl.append("bar");
h->append(bl);
bl.append("baz");
h->append(bl);
fs.fsync(h);
fs.close_writer(h);
}
{
BlueFS::FileReader *h;
ASSERT_EQ(0, fs.open_for_read("dir", "file", &h));
bufferlist bl;
BlueFS::FileReaderBuffer buf(4096);
ASSERT_EQ(9, fs.read(h, &buf, 0, 1024, &bl, NULL));
ASSERT_EQ(0, strncmp("foobarbaz", bl.c_str(), 9));
delete h;
}
fs.umount();

上述代码来自test_bluefs.cc的BlueFS的测试代码,展示了 BlueFS文件系统的使用。

  1. 文件系统调用函数fs.add_block_device 来添加设备到BlueFS中。

    • 创建了以新的BlockDevice
    • 把该设备添加到bdev列表中,并添加相应的IOContext 到ioc中
  2. 调用 fs.add_block_extent把设备的空间添加到bluefs中
  3. 调用函数fs.mkdir创建目录
  4. 调用函数 fs.open_for_write 打开一个文件,如果不存在,就创建
  5. 调用h->append 写数据,目前数据都只是Cache在内存zhong
  6. 最后调用 fs.fsync,本函数真正的把bluefs的 数据和元数据写入磁盘

RocksDB on BlueFS

如何在BlueFS上实现RocksDB? 对RocksDB, 只要实现 rocksdb::EnvWrapper接口即可。BlueRocksEnv.cc 和 BlueRocksEnv.h 实现了class BlueRocksEnv 来完成此工作。

Bluestore 实现

BlueStore的元数据

Bluestore的 所有的元数据都以KV对的形式写入RocksDB中,主要有以下的元数据

  1. 保存BlueStore的超级块信息,在KV中, 以PREFIX_SUPER为Key的前缀 
    const string PREFIX_SUPER = “S”; // field -> value
  2. 保存Collection的元数据信息bluestore_cnode_t 
    const string PREFIX_COLL = “C”; // collection name -> cnode_t
  3. 保存对象的元数据信息 
    const string PREFIX_OBJ = “O”; // object name -> onode_t

    需要主要的是,onode 和 enode的信息 都 以PREFIX_OBJ 为前缀,只是同一个对象的onode和 enode的信息的key不同来区分。

  4. 保存 overly 信息 
    const string PREFIX_OVERLAY = “V”; // u64 + offset -> data

  5. 保存对象的omap 信息 
    const string PREFIX_OMAP = “M”; // u64 + keyname -> value

  6. 保存 write ahead log 信息 
    const string PREFIX_WAL = “L”; // id -> wal_transaction_t

  7. 保存块设备的空闲extent信息 
    const string PREFIX_ALLOC = “B”; // u64 offset -> u64 length (freelist)

onode 
数据结构onode 保存了BlueStore中一个对象的数据结构,字段和Filestore差不多,这里就不详细介绍。 
Enode 
数据结构Enode定义了一个共享的extent,也就是这段数据被多个对象共享,一个对象的onode里保存一个enode数据结构,记录该对象被共享的extent.这个shared extent 用来对象基于extent的Copy-on-write 机制

struct Enode : public boost::intrusive::unordered_set_base_hook<> {
atomic_t nref; //< reference count
uint32_t hash;
string key; //< key under PREFIX_OBJ where we are stored
EnodeSet *enode_set; //< reference to the containing set bluestore_extent_ref_map_t ref_map;
boost::intrusive::unordered_set_member_hook<> map_item;

数据结构bluestore_extent_ref_map_t 定义了shared extent 被哪些对象引用

struct bluestore_extent_ref_map_t {
struct record_t {
uint32_t length;
uint32_t refs;
......
};
......
map<uint64_t,record_t> ref_map;
}

BlueStore的数据读写

Bluestore的数据写入分为两类:

  1. 数据是整块覆盖写,也就是min_alloc_size对齐的写入。对于这一类写入:

    • 重新分配新的存储空间
    • 把数据写入新分配存储空间
    • 删除旧的存储空间
  2. partial write,在这种情况下,部分块的写入,在这种情况下: 
    • overly write
    • wal write 
      这种两种方式都是先把数据写入 KV 存储中,后续再apply到实际的存储空间中,不同之处在于触发条件不同。

总结

BlueStore 其实是实现了用户态的一个文件系统。为了实现简单,又使用了RocksDB来实现了BlueStore的 所有的元数据的管理,简化了实现。

优点在于:

    • 对于整块数据的写入,数据直接aio的方式写入磁盘,避免了filestore的先写日志,后apply到实际磁盘的两次写盘。
    • 对于随机IO,直接WAL的形式,直接写入RocksDB 高性能的KV存储中

      http://www.cnblogs.com/lucas-sre/p/7096856.html

      ceph后端支持多种存储引擎,以插件式的方式来进行管理使用,目前支持filestore,kvstore,memstore以及最新的bluestore,目前默认使用的filestore

      Ceph OSD从filestore 转换到 bluestore的方法

ceph存储 ceph Bluestore的架构的更多相关文章

  1. ceph存储引擎bluestore解析

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

  2. 深度长文:深入理解Ceph存储架构

    点击上方"开源Linux",选择"设为星标" 回复"学习"获取独家整理的学习资料! 本文是一篇Ceph存储架构技术文章,内容深入到每个存储特 ...

  3. 高性能arm运行ceph存储基准测试

    关于arm 之前wdlab对外发布过一次约500个节点的arm的ceph集群,那个采用的是微集群的结构,使用的是双核的cortex-a9 ARM处理器,运行速度为1.3 GHz,内存为1 GB,直接焊 ...

  4. 初试 Centos7 上 Ceph 存储集群搭建

    转载自:https://cloud.tencent.com/developer/article/1010539 1.Ceph 介绍 Ceph 是一个开源的分布式存储系统,包括对象存储.块设备.文件系统 ...

  5. 我所了解的各公司使用的 Ceph 存储集群 (携程、乐视、有云、宝德云、联通等)

    Ceph 作为软件定义存储的代表之一,最近几年其发展势头很猛,也出现了不少公司在测试和生产系统中使用 Ceph 的案例,尽管与此同时许多人对它的抱怨也一直存在.本文试着整理作者了解到的一些使用案例. ...

  6. Ceph 存储集群

    Ceph 存储集群 Ceph 作为软件定义存储的代表之一,最近几年其发展势头很猛,也出现了不少公司在测试和生产系统中使用 Ceph 的案例,尽管与此同时许多人对它的抱怨也一直存在.本文试着整理作者了解 ...

  7. Ceph基础知识和基础架构认识

    1  Ceph基础介绍 Ceph是一个可靠地.自动重均衡.自动恢复的分布式存储系统,根据场景划分可以将Ceph分为三大块,分别是对象存储.块设备存储和文件系统服务.在虚拟化领域里,比较常用到的是Cep ...

  8. Ceph 基础知识和基础架构认识

    1  Ceph基础介绍 Ceph是一个可靠地.自动重均衡.自动恢复的分布式存储系统,根据场景划分可以将Ceph分为三大块,分别是对象存储.块设备存储和文件系统服务.在虚拟化领域里,比较常用到的是Cep ...

  9. 什么是Ceph存储?什么是分布式存储?简单明了带你学Ceph--<1>

    Ceph存储介绍 为什么要用Ceph Ceph是当前非常流行的开源分布式存储系统,具有高扩展性.高性能.高可靠性等优点,同时提供块存储服务(rbd).对象存储服务(rgw)以及文件系统存储服务(cep ...

随机推荐

  1. PAT 1017 Queueing at Bank (模拟)

    1017. Queueing at Bank (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, Yue Supp ...

  2. mysql 中调用存储过程之后,连接断开不可用

    解决方法: 由 mysql_real_connect(&m_mysql,host,user,passwd,Db,0,NULL,0) == NULL 改为 mysql_real_connect( ...

  3. python 里面的单下划线与双下划线的区别(私有和保护)

    Python 用下划线作为变量前缀和后缀指定特殊变量. _xxx 不能用'from moduleimport *'导入 __xxx__ 系统定义名字 __xxx 类中的私有变量名 核心风格:避免用下划 ...

  4. python基础之类和对象、对象之间的交互、类名称空间与对象/实例名称空间

    一 面向对象初识 Python要么是面向过程要么是面向对象. 概念及优缺点: 面向过程的程序设计的核心是过程,过程即解决问题的步骤,面向过程的设计就好比精心设计好一条流水线,考虑周全什么时候处理什么东 ...

  5. 一.MySQL入门基础

    1.关于cmd界面无法启动mysql: 1)必须要使用管理员身份运行cmd程序 2)如果下载MySQL5.7版本的,在windows服务上Mysql的名字默认是MySQL57,因此在cmd运行 net ...

  6. mysql数据库表插入单条数据/批量插入数据

    1.创建表格 reate table trade( id int(4) not null primary key auto_increment, product varchar(30) null, p ...

  7. 【POJ3615】Cow Hurdles 最短路,你若LCA,我仍不拦你。

    NOIP2013货车运输.仅仅只是数据范围小了很多. 不到150s打完而且AC. . 额.当然.我写的是Floyd. 写LCA的真过分. #include <cstdio> #includ ...

  8. WEB安全验收参考文档——From Github

    文章https://xianzhi.aliyun.com/forum/read/793.html 里面涉及到了web安全验收参考文档: 其实github上老外对此也做过一些整理.详情参考:https: ...

  9. python学习之路-第七天-python面向对象编程简介

    面向对象编程 在python中,同样是类和对象作为重要的组成部分. 而且在python中基本数据类型如int都是有封装类的,都有自己的方法,应该是和java里面的Integer类似吧 类包括域和方法: ...

  10. html-2, a img ul li ol dl dt dd 标签与列表标签的简单使用

    <!-- a:  a{ /*清除a标签的下划线*/ text-decoration: none; }  (1)超链接 href 超链接的地址 target: _self 默认 在当前中打开链接地 ...