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. 基于Web和二维码的文件传输服务

    在工作中难免需要对外提供一些我们抓取的log或者操作视频之类的资料,但由于工作环境日渐规范和严格,公司的网络环境和客户的网络环境是被独立开来的.这样做的好处不必多说,但同时也给我们工作带来的诸多不便. ...

  2. Intellij IDEA Ultimate Edition 14.1 破解

    key:IDEA value:61156-YRN2M-5MNCN-NZ8D2-7B4EW-U12L4 (2) key:huangwei value:97493-G3A41-0SO24-W57LI-Y2 ...

  3. iOS与导航相关的都在这

    // 设置导航背景图片 (一旦设置背景图片(变为不透明),透明层不起作用) [self.navigationBar setBackgroundImage:[UIImage imageNamed:@&q ...

  4. DHTML 简介

    DHTML, 动态的 html, 不是一门语言, 是多项技术综合体的简称.其中包括了 html, CSS, DOM, javascript. HTML : 负责提供标签, 对数据进行封装,目的是便于对 ...

  5. Delphi中MD5实现方法(转)

    原来写过一个计算MD5的程序,是用了一个叫MD5.pas的单元,使用起来还算简单,但还有更简单的办法,安装了indy就会有IdHashMessageDigest单元(delphi 7默认安装indy) ...

  6. mysq查询语句包含中文以及中文乱码,字符集 GBK、GB2312、UTF8的区别

    一.查看mysql 字符集设置情况 使用Navicat for Mysql查看工具,打开命令列界面,输入show variables like '%char%';如下图,查看当前mysql字符集设置情 ...

  7. 【MonogDB】The description of index(二) Embedded and document Index

    In this blog, we will talk about another the index which was called "The embedded ". First ...

  8. 001-Bitcoin比特币与BlockChain区块链技术

    一.比特币历史 2008 年 10 月 31 日,一个网名叫中本聪(英文翻译过来滴)的家伙发布比特币唯一的白皮书:<Bitcoin:A Peer-to-PeerElectronic Cash S ...

  9. Android开发中string.xml文件的使用

    为什么需要把应用中出现的文字单独存放在string.xml文中呢? 一:是为了国际化,Android建议将在屏幕上显示的文字定义在strings.xml中,如果今后需要进行国际化,比如我们开发的应用本 ...

  10. CodeForces - 220B Little Elephant and Array (莫队+离散化 / 离线树状数组)

    题意:N个数,M个查询,求[Li,Ri]区间内出现次数等于其数值大小的数的个数. 分析:用莫队处理离线问题是一种解决方案.但ai的范围可达到1e9,所以需要离散化预处理.每次区间向外扩的更新的过程中, ...