ceph分布式文件系统概念及原理介绍

一:架构


展示了一个简单的 Ceph 生态系统。Ceph 客户端是 Ceph 文件系统的使用者。Ceph 元数据后台服务程序提供了元数据服务,而 Ceph 对象存储后台服务程序提供了实际的存储(数据及元数据)。最后, Ceph 监控提供了集群的管理。注意可以存在多个 Ceph 客户端,多个对象存储端点,许多元数据服务器(取决于文件系统的能力),和至少一对冗余监控

二:ceph写流程



三:CRUSH(Controlled Replication Under Scalable Hashing)是一种基于伪随机控制数据分布、复制的算法

Crush是一种伪随机的控制数据分布、复制的算法,Ceph是为大规模分布式存储而设计的,数据分布算法必须能够满足在大规模的集群下数据依然能够快速的准确的计算存放位置,同时能够在硬件故障或扩展硬件设备时做到尽可能小的数据迁移,Ceph的CRUSH算法就是精心为这些特性设计的,可以说CRUSH算法也是Ceph的核心之一

ceph客户端存储对象数据到RADOS集群上,不是客户端直接存储到osd上;首先客户端会根据ceph集群的配置,将客户端存储的对象数据切分多个固定大小的对象数据,然后再将这些固定大小的数据对象通过一致性hash算法将对象数据映射至存储池里的PG,然后由CRUSH算法计算以后,再将PG映射至对应osd,然后由mon返回osd的ID给客户端,客户端拿着mon给的osd相关信息主动联系对应osd所在节点osd进程,进行数据存储操作;

存储池由一系列的归置组组成,而CRUSH算法则根据集群运行图和集群状态,将各PG均匀、伪随机地分布到集群中的OSD之上

所谓伪随机是指,在osd都健康数量没有变化的情况下,同一PG始终映射相同的OSD

归置组在OSD守护进程和Ceph客户端之间生成了一个中间层,CRUSH算法负责将每个对象动态映射到一个归置组,然后再将每个归置组动态映射到一个或多个OSD守护进程,从而能够支持在新的OSD设备上线时动态进行数据重新平衡

命名空间

一个文件8M,分割成2个4M小文件 --》(IID,OID_1) (IID,OID_2)

划到2个配置组中

(PGID_1,IID,OID_1)

(PGID_2,IID,OID_2)

形成1个副本

(PGID_1,IID,OID_1) (PGID_1,IID,OID_1)

(PGID_2,IID,OID_2) (PGID_2,IID,OID_2)

通过CRUSH算法

(PGID_1,IID,OID_1) (PGID_2,IID,OID_2) disk1

(PGID_1,IID,OID_1) (PGID_2,IID,OID_2) disk2

下面这个式子简单的表明CRUSH的计算表达式:

CRUSH(X) -> (osd.1,osd.2.....osd.n)

式子中的X就是一个随机数。

下面通过一个计算PG ID的示例来看CRUSH的一个计算过程:

(1)Client输入Pool ID和对象ID;

(2)CRUSH获得对象ID并对其进行Hash运算;

(3)CRUSH计算OSD的个数,Hash取模获得PG的ID,比如0x48;

(4)CRUSH取得该Pool的ID,比如是1;

(5)CRUSH预先考虑到Pool ID相同的PG ID,比如1.48

四:基础概念

#目标

Ceph主要设计的初衷是变成一个可避免单节点故障的分布式文件系统,PB级别的扩展能力,而且是一种开源自由软件,许多超融合的分布式文件系统都是基于Ceph开发的

高扩展性:使用普通x86服务器,支持10~1000台服务器,支持TB到EB级的扩展。

高可靠性:没有单点故障,多数据副本,自动管理,自动修复。

高性能:数据分布均衡。

可用于对象存储,块设备存储和文件系统存储

数据具有强?致性,确保所有副本写?完成后才返回确认,适合读多写少的场景

去中?化,没有固定的中?节点,集群扩展灵活

ceph缺陷

去中?化的分布式解决?案,需要提前做好组件和节点部署规划设计

ceph扩容时,由于其数据分布均衡的特性,会导致整个存储系统性能下降

块设备具有优异的读写性能,但不能多处挂载同时读写

?件系统接?读写性能较块设备接?差,但具有优异的共享性

对象存储系统具有共享性?存储性能好于?件系统存储的存储

核心组件
先总体介绍一下:

Monitor(ceph-mon):维护集群Cluster Map的状态,维护集群的Cluster MAP?进制表,保证集群数据的?致性。Cluster MAP描述了对象块存储的物理位置,以及?个将设备聚合到物理位置的桶列表,map中包含monitor组件信息,manger 组件信息,osd 组件信息,mds 组件信息,crush 算法信息。还负责ceph集群的身份验证功能,client 在连接ceph集群时通过此组件进?验证。
OSD(ceph-osd):OSD全称Object Storage Device,?于集群中所有数据与对象的存储。ceph 管理物理硬盘时,引?了OSD概念,每?块盘都会针对的运??个OSD进程。换句话说,ceph 集群通过管理 OSD 来管理物理硬盘。负责处理集群数据的复制、恢复、回填、再均衡,并向其他osd守护进程发送?跳,然后向Mon提供?些监控信息。当Ceph存储集群设定数据有两个副本时(?共存两份),则?少需要三个OSD守护进程即三个OSD节点,集群才能达到active+clean状态,实现冗余和?可?。
Manager(ceph-mgr):?于 收集ceph集群状态、运?指标,?如存储利?率、当前性能指标和系统负载。对外提供 ceph dashboard(ceph ui)和 resetful api。Manager组件开启?可?时,?少2个实现?可?性。
MDS(ceph-mds):Metadata server,元数据服务。为ceph ?件系统提供元数据计算、缓存与同步服务(ceph 对象存储和块存储不需要MDS)。同样,元数据也是存储在osd节点中的,mds类似于元数据的 代理缓存服务器,为 posix ?件系统?户提供性能良好的基础命令(ls,find等)不过只是在需要使?CEPHFS时,才需要配置MDS节点。
Object:Ceph最底层的存储单元是Object对象,每个Object包含元数据和原始数据。
PG:PG全称Placement Grouops,是?个逻辑的概念,?个PG包含多个OSD。引?PG这?层其实是为了更好的分配数据和定位数据。
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对外提供的?件系统服务


mds流程


1.osd

每个OSD节点可以设置一个目录作为实际存储区域,也可以是一个分区、一整块硬盘

每个OSD监听4个端口,分别用于接收客户请求、传输数据、发送心跳、同步数据等操作

osd节点默认监听tcp的6800到6803端口,如果同一台服务器上有多个OSD节点,则依次往后排序

当新的存储节点(OSD)被加?集群后,会在已有数据中随机抽取?部分数据迁移到新节点

client 创建cluster handler。
client 读取配置?件。
client 连接上monitor,获取集群map信息。
client 读写io 根据crshmap 算法请求对应的主osd数据节点。
主osd数据节点同时写?另外两个副本节点数据。
等待主节点以及另外两个副本节点写完数据状态。
主节点及副本节点写?状态都成功后,返回给client,io写?完成。

每个OSD上分布很多PG, 并且每个PG会?动散落在不同的OSD上

2.pg和PGP

PG是用来存放Object的,PGP相当于是PG存放OSD的一种排列组合

创建一个名为testpool包含6个PG和6个PGP的存储池

ceph osd pool create testpool 6 6

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

一般来说应该将PG和PGP的数量设置为相等

当需要将PG从一个OSD移动到另一个OSD时,PG的数量会对性能产生影响

即PG过少,那么对应一个PG存储的数据就越多,则移动PG会占用过多的网络带宽,从而影响正常客户端的使用

即PG过多,对应每个PG维护的数据较少,但是集群需要花费很多CPU和内存来维护和追踪PG的信息;从而造成集群的计算资源和内存资源造成影响,从而进一步影响客户端使用

即一个ceph集群总PG数量=每个OSD上的pg数量×OSD的数量,然后除以副本数量

即总pg数量/存储池个数,就是平均一个存储的PG数量

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

对象时如何映射进PG的?还记得OID么?首先使用静态hash函数对OID做hash取出特征码,用特征码与PG的数量去模,得到的序号则是PGID。由于这种设计方式,PG的数量多寡直接决定了数据分布的均匀性,所以合理设置的PG数量可以很好的提升CEPH集群的性能并使数据均匀分布。

最后PG会根据管理员设置的副本数量进行复制,然后通过crush算法存储到不同的OSD节点上(其实是把PG中的所有对象存储到节点上),第一个osd节点即为主节点,其余均为从节点。

下面是一段ceph中的伪代码,简要描述了ceph的数据存储流程

一个推荐配置是每OSD对应50-100个PG

Total PGs = ((Total_number_of_OSD * 100) / max_replication_count) / pool_count

结算的结果往上取靠近2的N次方的值。比如总共OSD数量是160,复制份数3,pool数量也是3,那么按上述公式计算出的结果是1777.7。取跟它接近的2的N次方是2048,那么每个pool分配的PG数量就是2048

100 - 250

在更改pool的PG数量时,需同时更改PGP的数量。PGP是为了管理placement而存在的专门的PG,它和PG的数量应该保持一致。如果你增加pool的pg_num,就需要同时增加pgp_num,保持它们大小一致,这样集群才能正常rebalancing。下面介绍如何修改pg_num和pgp_num。
(1)检查rbd这个pool里已存在的PG和PGP数量:
$ ceph osd pool get rbd pg_num
pg_num: 128
$ ceph osd pool get rbd pgp_num
pgp_num: 128
(2)检查pool的复制size,执行如下命令:
$ ceph osd dump |grep size|grep rbd
pool 2 'rbd' replicated size 3 min_size 2 crush_ruleset 0 object_hash rjenkins pg_num 128 pgp_num 128 last_change 45 flags hashpspool stripe_width 0
(3)使用上述公式,根据OSD数量、复制size、pool的数量,计算出新的PG数量,假设是256.
(4)变更rbd的pg_num和pgp_num为256:
$ ceph osd pool set rbd pg_num 256
$ ceph osd pool set rbd pgp_num 256
(5)如果有其他pool,同步调整它们的pg_num和pgp_num,以使负载更加均衡


#关系案例

存储数据与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],是不是很像我们高中数学学过的排列组合,pgp就是代表这个意思。一般来说应该将pg和pgp的数量设置为相等

先创建一个名为testpool包含6个PG和6个PGP的存储池

ceph osd pool create testpool 6 6

通过写数据后我们查看下pg的分布情况,使用以下命令

ceph pg dump pgs | grep ^1 | awk '{print $1,$2,$15}'

dumped pgs in format plain

1.1 75 [3,6,0]

1.0 83 [7,0,6]

1.3 144 [4,1,2]

1.2 146 [7,4,1]

1.5 86 [4,6,3]

1.4 80 [3,0,4]

第1列为pg的id,第2列为该pg所存储的对象数目,第3列为该pg所在的osd

我们扩大PG再看看

ceph osd pool set testpool pg_num 12

再次用上面的命令查询分布情况:

1.1 37 [3,6,0]

1.9 38 [3,6,0]

1.0 41 [7,0,6]

1.8 42 [7,0,6]

1.3 48 [4,1,2]

1.b 48 [4,1,2]

1.7 48 [4,1,2]

1.2 48 [7,4,1]

1.6 49 [7,4,1]

1.a 49 [7,4,1]

1.5 86 [4,6,3]

1.4 80 [3,0,4]

我们可以看到pg的数量增加到12个了,pg1.1的对象数量本来是75的,现在是37个,可以看到它把对象数分给新增的pg1.9了,刚好是38,加起来是75,而且可以看到pg1.1和pg1.9的osd盘是一样的。

而且可以看到osd盘的组合还是那6种

我们增加pgp的数量来看下,使用命令:

ceph osd pool set testpool pgp_num 12

再看下

1.a 49 [1,2,6]

1.b 48 [1,6,2]

1.1 37 [3,6,0]

1.0 41 [7,0,6]

1.3 48 [4,1,2]

1.2 48 [7,4,1]

1.5 86 [4,6,3]

1.4 80 [3,0,4]

1.7 48 [1,6,0]

1.6 49 [3,6,7]

1.9 38 [1,4,2]

1.8 42 [1,2,3]

再看pg1.1和pg1.9,可以看到pg1.9不在[3,6,0]上,而在[1,4,2]上了,该组合是新加的,可以知道增加pgp_num其实是增加了osd盘的组合

通过实验总结:

(1)PG是指定存储池存储对象的目录有多少个,PGP是存储池PG的OSD分布组合个数

(2)PG的增加会引起PG内的数据进行分裂,分裂相同的OSD上新生成的PG当中

(3)PGP的增加会引起部分PG的分布进行变化,但是不会引起PG内对象的变动


3.pool

Pool是管理员自定义的命名空间,像其他的命名空间一样,用来隔离对象与PG。我们在调用API存储,即使用对象存储时,需要指定对象要存储进哪一个POOL中。除了隔离数据,我们也可以分别对不同的POOL设置不同的优化策略,比如副本数、数据清洗次数、数据块及对象大小等

存储池默认副本数为2(osd_pool_default_size = 2)

官方建议

确定 pg_num 取值是强制性的,因为不能自动计算。下面是几个常用的值:

?少于 5 个 OSD 时可把 pg_num 设置为 128

?OSD 数量在 5 到 10 个时,可把 pg_num 设置为 512

?OSD 数量在 10 到 50 个时,可把 pg_num 设置为 4096

?OSD 数量大于 50 时,你得理解权衡方法、以及如何自己计算 pg_num 取值

其结果汇总后应该接近 2 的幂


4.mon

Mon节点监听于tcp的6789端口

Mon节点中保存了最新的版本集群数据分布图(Cluster Map)的主副本

客户端在使用时,需要挂载Mon节点的6789端口,下载最新的Cluster Map,通过CRUSH算法获得集群中各OSD的IP地址,然后再与OSD节点直接建立连接来传输数据

5.CephFS

cephfs:文件系统存储

在创建CephFS时,要至少创建两个Pool,一个用于存储数据,另一个用于存放元数据



6.RBD

rbd: 块存储

RBD 具有丰富的企业特性,如自动精简配置( thin proviioning) 、动态调整容量、快照、写时复制以及缓存

RBD 由 Ceph Rados 层提供支持,因此每个块设备都分布多个 Ceph 节点上

7.radosgw

radosgw:对象网关接口(对象存储)

#分层结构

基于RADOS层的上一层是LIBRADOS,LIBRADOS是一个库,它允许应用程序通过访问该库来与RADOS系统进行交互,支持多种编程语言,比如C、C++、Python等

基于LIBRADOS层开发的又可以看到有三层,分别是RADOSGW、RBD和CEPH FS

RADOSGW:RADOSGW是一套基于当前流行的RESTFUL协议的网关,并且兼容S3和Swift

RBD:RBD通过Linux内核客户端和QEMU/KVM驱动来提供一个分布式的块设备

CEPH FS:CEPH FS通过Linux内核客户端和FUSE来提供一个兼容POSIX的文件系统



无论使用哪种存储方式(对象、块、挂载),存储的数据都会被切分成对象(Objects)。Objects size大小可以由管理员调整,通常为2M或4M。每个对象都会有一个唯一的OID,由ino与ono生成,虽然这些名词看上去很复杂,其实相当简单。ino即是文件的File ID,用于在全局唯一标示每一个文件,而ono则是分片的编号。比如:一个文件FileID为A,它被切成了两个对象,一个对象编号0,另一个编号1,那么这两个文件的oid则为A0与A1。Oid的好处是可以唯一标示每个不同的对象,并且存储了对象与文件的从属关系。由于ceph的所有数据都虚拟成了整齐划一的对象,所以在读写时效率都会比较高

但是对象并不会直接存储进OSD中,因为对象的size很小,在一个大规模的集群中可能有几百到几千万个对象。这么多对象光是遍历寻址,速度都是很缓慢的;并且如果将对象直接通过某种固定映射的哈希算法映射到osd上,当这个osd损坏时,对象无法自动迁移至其他osd上面(因为映射函数不允许)。为了解决这些问题,ceph引入了归置组的概念,即PG

8.Ceph 权限

Ceph 把数据以对象的形式存于各存储池中。Ceph 用户必须具有访问存储池的权限才能够读写数据。

另外,Ceph 用户必须具有执行权限才能够使用 Ceph 的管理命令。

Ceph 用 “能力”( capabilities, caps )这个术语来描述给认证用户的授权,这样才能使用 Mon、 OSD 和 MDS 的功能。

能力也用于限制对某一存储池内的数据或某个命名空间的访问。 Ceph 管理员用户可在创建或更新普通用户时赋予他相应的能力。

Monitor 能力: Monitor 能力包括 r 、 w 、 x 和 allow profile {cap}

OSD 能力: OSD 能力包括 r 、 w 、 x 、 class-read 、 class-write 和 profile osd

MDS 能力: MDS 能力比较简单,只需要 allow 或者空白,也不会解析更多选项

allow 描述: 在守护进程的访问设置之前,仅对 MDS 隐含 rw 。

r 描述: 授予用户读权限,对 monitor 具有读权限才能获取 CRUSH map。

w 描述: 授予用户写对象的权限。

x 描述: 授予用户调用类方法的能力,即同时有读和写,且能在 monitor 上执行 auth 操作。

class-read 描述: 授予用户调用类读取方法的能力, x 的子集。

class-write 描述: 授予用户调用类写入方法的能力, x 的子集

profile osd 描述: 授权一个用户以 OSD 身份连接其它 OSD 或 Monitor

profile mds 描述: 授权一个用户以 MDS 身份连接其它 MDS 或 Monitor

rofile bootstrap-osd 描述: 授权用户自举引导一个 OSD

profile bootstrap-mds 描述: 授权用户自举引导一个 MDS



#文件系统区别

(1)对象存储:

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

(2)块存储:

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

(3)文件系统存储:

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

三种接口的总结

概括?下,块设备速度快,对存储的数据没有进?组织管理,但在?多数场景下,?户数据读写不?便(以块设备位置offset + 数据的length来记录数据位置,读写数据)。?在块设备上构建了?件系统后,?件系统帮助块设备组织管理数据,数据存储对?户更加友好(以?件名来读写数据)。Ceph?件系统接?解决了“Ceph块设备+本地?件系统”不?持多客户端共享读写的问题,但由于?件系统结构的复杂性导致了存储性能较Ceph块设备差。对象存储接?是?种折中,保证?定的存储性能,同时?持多客户端共享读写


#特性介绍

假设文件A存储在B、C、D三台OSD,那么用户就会再次直接访问3台OSD服务器去读取数据。

这时候由于是3台OSD同时对外传输数据,所以传输的速度就加快了。当OSD服务器数量越多,这种读写速度的提升就越大,通过此种方式,实现了读写快的目的

在数据迁移时,也是以PG作为基本单位进行迁移,ceph不会直接操作对象


#命令介绍

#查看pg信息

ceph pg stat

#获取存储池的状态

ceph osd pool stats

#获取存储池大小和空间使用情况

ceph df

#获取详细信息

ceph df detail

#查看OSD信息

ceph osd dump

ceph osd tree

#查看mon信息

ceph mon stat

ceph quorum_status

#查看mon版本

ceph --admin-daemon /var/run/ceph/ceph-mon.ceph1.asok version

#获取osd地址

ceph daemon osd.0 config get public_addr

#文件系统相关

ceph fs new

这条命令创建一个新的文件系统,文件系统名称和元数据池名称很清晰明了。指定的数据池是默认数据池,一旦设置便无法更改,每个文件系统都有自己的一组MDS守护程序分配给等级,因此请确保你有足够的备用守护程序来容纳新文件系统

ceh fs ls

列出已有的文件系统

ceph fs rm [–yes-i-really-mean-it]

销毁CephFS文件系统,这会从FSMap擦除有关文件系统状态的信息,元数据池和数据池保持不变,必须分别销毁

ceph fs get

获取有关命名文件系统的信息,包括设置和等级,这是来自fs dump命令的相同信息的子集

ceph fs set

更改文件系统上的设置,这些设置特定于命名文件系统,并且不影响其他文件系统

ceph fs add_data_pool

将数据池添加到文件系统,该池可用于文件布局,作为存储文件数据的备用位置

ceph fs rm_data_pool

此命令从文件系统的数据池列表中删除指定的池,如果有任何文件具有已删除数据池的布局,则文件数据将不可用,无法删除默认数据池(在创建文件系统时创建的第一个数据池)

ceph fs set max_file_size

CephFS具有可配置的最大文件大小,默认情况下为1TB,如果希望在CephFS中存储大文件,则可以将此限制设置得更高,它是一个64位字段。 将max_file_size设置为0不会禁用该限制,它将仅限制客户端的权限为仅有权限创建空文件

通过设置down 参数来关闭CephFS集群

ceph fs set down true

恢复集群

ceph fs set down false

这还将恢复max_mds的先前值,以某种方式关闭MDS守护程序,以便将日记刷新到元数据池,并停止所有客户端的I / O操作