1、Ceph是什么?

Ceph是一个开源的分布式存储系统,同时支持对象存储、块设备、文件系统

可同事提供三种接口:

对象存储:也称为基于对象的存储,其中的文件被拆分成多个部分并散布在多个存储服务器,在对象存储中,数据会被分解为称为“对象”的离散单元,并保存在单个存储库中,而不是作为文件夹中的文件或服务器上的块来保存,对象存储需要一个简单的 HTTP 应用编程接口 (API),以供大多数客户端(各种语言)使用

块存储:需要格式化,将文件直接保存到磁盘上。

文件存储:提供数据存储的接口,是由操作系统针对块存储的应用,即由操作系统提供存储接口,应用程序通过调用操作系统将文件保存到块存储进行持久化

数据分为元数据和数据:

元数据即是文件的属性信息(文件名、权限(属主、属组)、大小、时间戳等),在分布式存储中当客户端或者应用程序产生的客户端数据被写入到分布式存储系统的时候,会有一个服务(Name Node)提供文件元数据的路由功能,即告诉应用程序去哪个服务器去请求文件内容,然后再有(Data Node)提供数据的读写请求及数据的高可用功能

2、什么是块存储/对象存储/文件系统存储?

对象存储:也就是通常意义的键值存储,其接口就是简单的GET、PUT、DEL 和其他扩展,代表主要有 Swift 、S3 以及 Gluster 等。

块存储:这种接口通常以 QEMU Driver 或者 Kernel Module 的方式存在,这种接口需要实现 Linux 的 Block Device 的接口或者 QEMU 提供的 Block Driver 接口,如 Sheepdog,AWS 的 EBS,青云的云硬盘和阿里云的盘古系统,还有 Ceph 的 RBD(RBD是Ceph面向块存储的接口)。在常见的存储中 DAS、SAN 提供的也是块存储。

文件系统存储:通常意义是支持 POSIX 接口,它跟传统的文件系统如 Ext4 是一个类型的,但区别在于分布式存储提供了并行化的能力,如 Ceph 的 CephFS (CephFS是Ceph面向文件存储的接口),但是有时候又会把 GlusterFS ,HDFS 这种非POSIX接口的类文件存储接口归入此类。当然 NFS、NAS也是属于文件系统存储。

3、ceph的特点

高性能:

(1)摒弃了传统的集中式存储元数据寻址的⽅案,采⽤CRUSH算法,数据分布均衡,并⾏度⾼。
(2)考虑了容灾域的隔离,能够实现各类负载的副本放置规则,例如跨主机、跨机房、机架感知等。
(3)能够⽀持上千个存储节点的规模,⽀持TB到PB级的数据。

⾼可⽤性:

(1)副本数可以灵活控制。
(2)⽀持故障域分隔,数据强⼀致性。
(3)多种故障场景⾃动进⾏修复⾃愈。
(4)没有单点故障,⾃动管理。

⾼可扩展性:

(1)去中⼼化。
(2)扩展灵活。
(3)随着节点增加⽽线性增⻓。

特性丰富:

(1)⽀持三种存储接⼝:块存储、⽂件存储、对象存储。
(2)⽀持⾃定义接⼝,⽀持多种语⾔驱动。

4、ceph组织架构

对象存储 swift 流程 对象存储ceph_对象存储 swift 流程

 

对象数据的底层存储服务是由多个存储主机(host)组成的存储集群,该集群也被称之为RADOS(reliable automatic distributed object store)存储集群,即可靠的、自动化的、分布式的对象存储系统。 

librados 是RADOS 存储集群的API,支持C/C++/JAVA/python/ruby/php/go等编程语言客户端。

 ceph的逻辑架构图:

对象存储 swift 流程 对象存储ceph_数据_02

RADOS:Reliable Autonomic Distributed Object Store。RADOS是ceph存储集群的基础。在ceph中,所有数据都以对象的形式存储,并且无论什么数据类型,RADOS对象存储都将负责保存这些对象。RADOS层可以确保数据始终保持一致。

librados:librados库,为应用程度提供访问接口。同时也为块存储、对象存储、文件系统提供原生的接口。

RADOSGW:网关接口,提供对象存储服务。它使用librgw和librados来实现允许应用程序与Ceph对象存储建立连接。并且提供S3 和 Swift 兼容的RESTful API接口。

RBD:块设备,它能够自动精简配置并可调整大小,而且将数据分散存储在多个OSD上。

CephFS:Ceph文件系统,与POSIX兼容的文件系统,基于librados封装原生接口。

5、Ceph的核心组件及逻辑架构

对象存储 swift 流程 对象存储ceph_数据_03

5.2、Ceph的核心组件

Monitor(ceph-mon)ceph监视器:

在一个主机上运行的一个守护进程,用于维护集群状态映射(maintains maps of the cluster state),比如ceph 集群中有多少存储池、每个存储池有多少PG 以及存储池和PG的映射关系等, monitor map, manager map, the OSD map, the MDS map,and the CRUSH map,这些映射是Ceph 守护程序相互协调所需的关键群集状态,此外监视器还负责管理守护程序和客户端之间的身份验证(认证使用cephX 协议)。通常至少需要三个监视器才能实现冗余和高可用性。
监视器,维护集群状态的多种映射,同时提供认证和日志记录服务,包括有关monitor 节点端到端的信息,其中包括 Ceph 集群ID,监控主机名和IP以及端口。并且存储当前版本信息以及最新更改信息,通过 "ceph mon dump"查看 monitor map。

 Managers(ceph-mgr)的功能:

在一个主机上运行的一个守护进程,Ceph Manager 守护程序(ceph-mgr)负责跟踪运行时指标和Ceph 集群的当前状态,包括存储利用率,当前性能指标和系统负载。Ceph Manager 守护程序还托管基于python 的模块来管理和公开Ceph 集群信息,包括基于Web的Ceph 仪表板和REST API。高可用性通常至少需要两个管理器。

Ceph OSDs(对象存储守护程序ceph-osd):

即对象存储守护程序,但是它并非针对对象存储。提供存储数据,操作系统上的一个磁盘就是一个OSD 守护程序。是物理磁盘驱动器,将数据以对象的形式存储到集群中的每个节点的物理磁盘上。OSD负责存储数据、处理数据复制、恢复、重新平衡。完成存储数据的工作绝大多数是由 OSD daemon 进程实现。在构建 Ceph OSD的时候,建议采用SSD 磁盘以及xfs文件系统来格式化分区。此外OSD还对其它OSD进行心跳检测,检测结果汇报给Monitor。通常至少需要3 个Ceph OSD 才能实现冗余和高可用性。

MDS(ceph 元数据服务器ceph-mds):Ceph 元数据,主要保存的是Ceph文件系统(NFS/CIFS)的元数据。注意:ceph的块存储和ceph对象存储都不需要MDS。

Object:Ceph最底层的存储单元是Object对象,每个Object包含元数据和原始数据

pool:存储池、分区,存储池的大小取决于底层的存储空间

PG(placement group):

PG是一个逻辑概念,我们linux系统中可以直接看到对象,但是无法直接看到PG。它在数据寻址时类似于数据库中的索引:每个对象都会固定映射进一个PG中,所以当我们要寻找一个对象时,只需要先找到对象所属的PG,然后遍历这个PG就可以了,无需遍历所有对象。而且在数据迁移时,也是以PG作为基本单位进行迁移,ceph不会直接操作对象

一个pool 内部可以有多个PG 存在,pool 和PG 都是抽象的逻辑概念,一个pool 中有多少个PG 可以通过公式计算。引入PG这一层其实是为了更好的分配数据和定位数据。

OSD(Object Storage Daemon,对象存储设备):每一块磁盘都是一个 osd,一个主机由一个或多个 osd 组成

RADOS:RADOS全称Reliable Autonomic Distributed Object Store,是Ceph集群的精华,用户实现数据分配、Failover等集群操作

Libradio:Librados是Rados提供库,因为RADOS是协议很难直接访问,因此上层的RBD、RGW和CephFS都是通过librados访问的,目前提供PHP、Ruby、Java、Python、C和C++支持。

CRUSH:CRUSH是Ceph使用的数据分布算法,类似一致性哈希,让数据分配到预期的地方

RBD:RBD全称RADOS block device,是Ceph对外提供的块设备服务

RGW:RGW全称RADOS gateway,是Ceph对外提供的对象存储服务,接口与S3和Swift兼容

CephFS:CephFS全称Ceph File System,是Ceph对外提供的文件系统服务

Ceph 的管理节点:

1.ceph 的常用管理接口是一组命令行工具程序,例如rados、ceph、rbd 等命令,ceph 管理员可以从某个特定的ceph-mon 节点执行管理操作
2.推荐使用部署专用的管理节点对ceph 进行配置管理、升级与后期维护,方便后期权限管理,管理节点的权限只对管理人员开放,可以避免一些不必要的误操作的发生。

 5.2、一个ceph集群的组成部分

若干的Ceph OSD(对象存储守护程序)
至少需要一个Ceph Monitors 监视器(1,3,5,7...)
两个或以上的Ceph 管理器managers,运行Ceph 文件系统客户端时
还需要高可用的Ceph Metadata Server(文件系统元数据服务器)。
RADOS cluster:由多台host 存储服务器组成的ceph 集群
OSD(Object Storage Daemon):每台存储服务器的磁盘组成的存储空间
Mon(Monitor):ceph 的监视器,维护OSD 和PG 的集群状态,一个ceph 集群至少要有一个mon,可以是一三五七等等这样的奇数个。
Mgr(Manager):负责跟踪运行时指标和Ceph 集群的当前状态,包括存储利用率,当前性
能指标和系统负载等。

 

6、Ceph数据写入流程

在说明ceph数据写入流程之前之前,先介绍几个概念和它们之间的关系。

存储数据与object的关系:当用户要将数据存储到Ceph集群时,存储数据都会被分割成多个object,每个object都有一个object id,每个object的大小是可以设置的,默认是4MB,object可以看成是Ceph存储的最小存储单元。

object与pg的关系:由于object的数量很多,所以Ceph引入了pg的概念用于管理object,每个object最后都会通过CRUSH计算映射到某个pg中,一个pg可以包含多个object。

pg与osd的关系:pg也需要通过CRUSH计算映射到osd中去存储,如果是二副本的,则每个pg都会映射到二个osd,比如[osd.1,osd.2],那么osd.1是存放该pg的主副本,osd.2是存放该pg的从副本,保证了数据的冗余。

pg和pgp的关系:pg是用来存放object的,pgp相当于是pg存放osd的一种排列组合,我举个例子,比如有3个osd,osd.1、osd.2和osd.3,副本数是2,如果pgp的数目为1,那么pg存放的osd组合就只有一种,可能是[osd.1,osd.2],那么所有的pg主从副本分别存放到osd.1和osd.2,如果pgp设为2,那么其osd组合可以两种,可能是[osd.1,osd.2]和[osd.1,osd.3],一般来说应该将pg和pgp的数量设置为相等。

pg和pool的关系:pool也是一个逻辑存储概念,我们创建存储池pool的时候,都需要指定pg和pgp的数量,逻辑上来说pg是属于某个存储池的,就有点像object是属于某个pg的

(1)PG是指定存储池存储对象的目录有多少个,PGP是存储池PG的OSD分布组合个数
(2)PG的增加会引起PG内的数据进行分裂,分裂相同的OSD上新生成的PG当中
(3)PGP的增加会引起部分PG的分布进行变化,但是不会引起PG内对象的变动

以下这个图表明了存储数据,object、pg、pool、osd、存储磁盘的关系

对象存储 swift 流程 对象存储ceph_元数据_04

ceph 集群部署好之后,要先创建存储池才能向ceph 写入数据,文件在向ceph 保存之前要先进行一致性hash 计算,计算后会把文件保存在某个对应的PG 的,此文件一定属于某个pool 的一个PG,在通过PG 保存在OSD 上。数据对象在写到主OSD 之后再同步对从OSD 以实现数据的高可用。

对象存储 swift 流程 对象存储ceph_文件系统_05

第一步: 计算文件到对象的映射:

假如file 为客户端要读写的文件, 文件会被切分成若干个对象(object),默认为4M,每个对象都会有一个唯一的oid(object id),OID由ino + ono组成
ino:inode number (INO),File 的元数据序列号,File 的唯一id。
ono:object number (ONO),File 切分产生的某个object 的序号,默认以4M 切分一个块大小。
比如:一个文件FileID为A,它被切成了两个对象,一个对象编号0,另一个编号1,那么这两个对象的oid则为A0与A1。Oid的好处是可以唯一标示每个不同的对象,并且存储了对象与文件的从属关系。

第二步:通过hash 算法计算出文件对应的pool 中的PG:

对象时如何映射进PG的?还记得OID么?首先使用静态hash函数对OID做hash取出特征码,用特征码与mask取模,得到的序号则是PGID

mask=PG数量-1
hash(oid) & mask -> pgid

第三步: 通过CRUSH 把对象映射到PG 中的OSD: 通过CRUSH 算法得到OSD列表,PG -> OSD 映射:CRUSH(pgid)  ->  (osd1,osd2,osd3)

第四步:PG 中的主OSD 将对象写入到硬盘。

第五步: 主OSD 将数据同步给备份OSD,并等待备份OSD 返回确认。

第六步: 备份OSD返回确认后,主OSD 将写入完成返回给客户端。

Ceph中数据写入,会有三次映射

(1)File -> object映射
(2)Object -> PG映射,hash(oid) & mask -> pgid
(3)PG -> OSD映射,CRUSH算法

 

7、CRUSH算法简介 

Controllers replication under scalable hashing #可控的、可复制的、可伸缩的一致性 hash算法。

Ceph 使用 CURSH 算法来存放和管理数据,它是 Ceph 的智能数据分发机制。Ceph 使用CRUSH 算法来准确计算数据应该被保存到哪里,以及应该从哪里读取,和保存元数据不同的是,CRUSH 按需计算出元数据,因此它就消除了对中心式的服务器/网关的需求,它使得Ceph 客户端能够计算出元数据,该过程也称为 CRUSH 查找,然后和 OSD 直接通信。

1.如果是把对象直接映射到 OSD 之上会导致对象与 OSD 的对应关系过于紧密和耦合,当OSD 由于故障发生变更时将会对整个 ceph 集群产生影响。
2.于是 ceph 将一个对象映射到 RADOS 集群的时候分为两步走:
首先使用一致性 hash 算法将对象名称映射到 PG 2.7
然后将 PG ID 基于 CRUSH 算法映射到 OSD 即可查到对象
3.以上两个过程都是以”实时计算”的方式完成,而没有使用传统的查询数据与块设备的对应表的方式,这样有效避免了组件的”中心化”问题,也解决了查询性能和冗余问题。使得 ceph集群扩展不再受查询的性能限制。
4.这个实时计算操作使用的就是 CRUSH 算法
Controllers replication under scalable hashing #可控的、可复制的、可伸缩的一致性 hash算法。
CRUSH 是一种分布式算法,类似于一致性 hash 算法,用于为 RADOS 存储集群控制数据的分配。

 

8、Ceph元数据保存方式

Ceph 对象数据的元数据信息放在哪里呢? 对象数据的元数据以 key-value 的形式存在,在RADOS 中有两种实现:xattrs 和 omap

8.1、xattrs(扩展属性)

是将元数据保存在对象对应文件的扩展属性中并保存到系统磁盘上,这要求支持对象存储的本地文件系统(一般是 XFS)支持扩展属性

8.2、omap(object map对象映射):

omap:是 object map 的简称,是将元数据保存在本地文件系统之外的独立 key-value 存储系统中,在使用 filestore 时是 leveldb,在使用 bluestore 时是 rocksdb,由于 filestore存在功能问题(需要将磁盘格式化为XFS格式)及元数据高可用问题等问题,因此在目前ceph主要使用 bluestore

8.2.1、blustore和rocksdb:

由于 levelDB 依然需要需要磁盘文件系统的支持,后期 facebok 对 levelDB 进行改进为RocksDB https://github.com/facebook/rocksdb,RocksDB 将对象数据的元数据保存在RocksDB,但是 RocksDB 的数据又放在哪里呢?放在内存怕丢失,放在本地磁盘但是解决不了高可用,ceph 对象数据放在了每个 OSD 中,那么就在在当前 OSD 中划分出一部分空间,格式化为 BlueFS 文件系统用于保存 RocksDB 中的元数据信息(称为 BlueStore),并实现元数据的高可用,BlueStore 最大的特点是构建在裸磁盘设备之上,并且对诸如 SSD 等新的存储设备做了很多优化工作。

对全 SSD 及全 NVMe SSD 闪存适配
绕过本地文件系统层,直接管理裸设备,缩短 IO 路径
严格分离元数据和数据,提高索引效率
使用 KV 索引,解决文件系统目录结构遍历效率低的问题
支持多种设备类型
解决日志“双写”问题
期望带来至少 2 倍的写性能提升和同等读性能
增加数据校验及数据压缩等功能

RocksDB 通过中间层 BlueRocksDB 访问文件系统的接口。这个文件系统与传统的 Linux文件系统(例如 Ext4 和 XFS)是不同的,它不是在 VFS 下面的通用文件系统,而是一个用户态的逻辑。BlueFS 通过函数接口(API,非 POSIX)的方式为 BlueRocksDB 提供类似文件系统的能力

对象存储 swift 流程 对象存储ceph_对象存储 swift 流程_06

BlueStore 的逻辑架构如上图所示,模块的划分都还比较清晰,下面是各模块的作用:

Allocator:负责裸设备的空间管理分配。

RocksDB:rocksdb 是 facebook 基于 leveldb 开发的一款 kv 数据库,BlueStore 将元数据全部存放至 RocksDB 中,这些元数据包括存储预写式日志、数据对象元数据、Ceph 的 omap数据信息、以及分配器的元数据 。

BlueRocksEnv:这是 RocksDB 与 BlueFS 交互的接口;RocksDB 提供了文件操作的接口EnvWrapper(Env 封装器),可以通过继承实现该接口来自定义底层的读写操作,BlueRocksEnv 就是继承自 EnvWrapper 实现对 BlueFS 的读写。

BlueFS:BlueFS 是 BlueStore 针对 RocksDB 开发的轻量级文件系统,用于存放 RocksDB产生的.sst 和.log 等文件。

BlockDecive:BlueStore 抛弃了传统的 ext4、xfs 文件系统,使用直接管理裸盘的方式;BlueStore 支持同时使用多种不同类型的设备,在逻辑上 BlueStore 将存储空间划分为三层:慢速(Slow)空间、高速(DB)空间、超高速(WAL)空间,不同的空间可以指定使用不同的设备类型,当然也可使用同一块设备。

BlueStore 的设计考虑了 FileStore 中存在的一些硬伤,抛弃了传统的文件系统直接管理裸设备,缩短了 IO 路径,同时采用 ROW 的方式,避免了日志双写的问题,在写入性能上有了极大的提高