ceph学习

一、什么是Ceph?
二、Ceph的核心组件
三、Ceph的架构
四、Ceph的寻址
五、数据的操作流程
六、集群维护
七、OSD增加流程
八、ceph的POOL、PG、PGP、OSD
1、pool
2、pg
PG 概念
PG特点
3、pgp
一、什么是Ceph?
  Ceph是一种为优秀的性能、可靠性和可扩展性而设计的统一的、分布式的存储系统。Ceph 独一无二地用统一的系统提供了对象、块、和文件存储功能,它可靠性高、管理简便、并且是开源软件。 Ceph 的强大足以改变贵公司的 IT 基础架构、和管理海量数据的能力。Ceph 可提供极大的伸缩性——供成千用户访问 PB 乃至 EB 级的数据。 Ceph 节点以普通硬件和智能守护进程作为支撑点, Ceph 存储集群组织起了大量节点,它们之间靠相互通讯来复制数据、并动态地重分布数据。
二、Ceph的核心组件
Ceph的核心组件包括Ceph OSD、Ceph Monitor和Ceph MDS三大组件。
Ceph OSD:OSD的英文全称是Object Storage Device,它的主要功能是存储数据、复制数据、平衡数据、恢复数据等,与其它OSD间进行心跳检查等,并将一些变化情况上报给Ceph Monitor。一般情况下一块硬盘对应一个OSD,由OSD来对硬盘存储进行管理,当然一个分区也可以成为一个OSD。
Ceph Monitor:由该英文名字我们可以知道它是一个监视器,负责监视Ceph集群,维护Ceph集群的健康状态,同时维护着Ceph集群中的各种Map图,比如OSD Map、Monitor Map、PG Map和CRUSH Map,这些Map统称为Cluster Map,Cluster Map是RADOS的关键数据结构,管理集群中的所有成员、关系、属性等信息以及数据的分发,比如当用户需要存储数据到Ceph集群时,OSD需要先通过Monitor获取最新的Map图,然后根据Map图和object id等计算出数据最终存储的位置。
Ceph MDS:全称是Ceph MetaData Server,主要保存的文件系统服务的元数据,但对象存储和块存储设备是不需要使用该服务的。
查看各种Map的信息可以通过如下命令:ceph osd(mon、pg) dump
三、Ceph的架构
架构图:

Ceph系统逻辑层次结构:
自下向上,可以将Ceph系统分为四个层次:
(1)基础存储系统RADOS(Reliable, Autonomic, Distributed Object Store,即可靠的、自动化的、分布式的对象存储)
顾名思义,这一层本身就是一个完整的对象存储系统,所有存储在Ceph系统中的用户数据事实上最终都是由这一层来存储的。而Ceph的高可靠、高可扩展、高性能、高自动化等等特性本质上也是由这一层所提供的。因此,理解RADOS是理解Ceph的基础与关键。
RADOS集群主要由2种节点组成。一种是负责数据存储和维护功能的OSD,另一种则是若干个负责完成系统状态监测和维护的monitor。
(2)基础库librados
  这一层的功能是对RADOS进行抽象和封装,并向上层提供API,以便直接基于RADOS(而不是整个Ceph)进行应用开发。特别要注意的是,RADOS是一个对象存储系统,因此,librados实现的API也只是针对对象存储功能的。
  RADOS采用C++开发,所提供的原生librados API包括C和C++两种。物理上,librados和基于其上开发的应用位于同一台机器,因而也被称为本地API。应用调用本机上的librados API,再由后者通过socket与RADOS集群中的节点通信并完成各种操作。
(3)高层应用接口
  这一层包括了三个部分:RADOS GW(RADOS Gateway)、 RBD(Reliable Block Device)和Ceph FS(Ceph File System),其作用是在librados库的基础上提供抽象层次更高、更便于应用或客户端使用的上层接口。
  RADOS GW是一个提供与Amazon S3和Swift兼容的RESTful API的gateway,以供相应的对象存储应用开发使用。RADOS GW提供的API抽象层次更高,但功能则不如librados强大。因此,开发者应针对自己的需求选择使用。
  RBD则提供了一个标准的块设备接口,常用于在虚拟化的场景下为虚拟机创建volume。目前,Red Hat已经将RBD驱动集成在KVM/QEMU中,以提高虚拟机访问性能。
  Ceph FS是通过Linux内核客户端和FUSE来提供一个兼容POSIX的文件系统。
四、Ceph的寻址
ceph的寻址采用的是CRUSH算法

File —— 此处的file就是用户需要存储或者访问的文件。当用户要将数据存储到Ceph集群时,存储数据都会被分割成多个object。
Ojbect —— 每个object都有一个object id,每个object的大小是可以设置的,默认是4MB,object可以看成是Ceph存储的最小存储单元。
PG(Placement Group)—— 顾名思义,PG的用途是对object的存储进行组织和位置映射。由于object的数量很多,所以Ceph引入了PG的概念用于管理object,每个object最后都会通过CRUSH计算映射到某个pg中,一个pg可以包含多个object。
OSD —— 即object storage device,PG也需要通过CRUSH计算映射到osd中去存储,如果是二副本的,则每个pg都会映射到二个osd,比如[osd.1,osd.2],那么osd.1是存放该pg的主副本,osd.2是存放该pg的从副本,保证了数据的冗余。
(1)File -> object映射
  这次映射的目的是,将用户要操作的file,映射为RADOS能够处理的object。其映射十分简单,本质上就是按照object的最大size对file进行切分,相当于RAID中的条带化过程。这种切分的好处有二:一是让大小不限的file变成最大size一致、可以被RADOS高效管理的object;二是让对单一file实施的串行处理变为对多个object实施的并行化处理。
  每一个切分后产生的object将获得唯一的oid,即object id。其产生方式也是线性映射,极其简单。图中,ino是待操作file的元数据,可以简单理解为该file的唯一id。ono则是由该file切分产生的某个object的序号。而oid就是将这个序号简单连缀在该file id之后得到的。举例而言,如果一个id为filename的file被切分成了三个object,则其object序号依次为0、1和2,而最终得到的oid就依次为filename0、filename1和filename2。
  这里隐含的问题是,ino的唯一性必须得到保证,否则后续映射无法正确进行。
(2)Object -> PG映射
  在file被映射为一个或多个object之后,就需要将每个object独立地映射到一个PG中去。这个映射过程也很简单,如图中所示,其计算公式是:
  hash(oid) & mask -> pgid
  由此可见,其计算由两步组成。首先是使用Ceph系统指定的一个静态哈希函数计算oid的哈希值,将oid映射成为一个近似均匀分布的伪随机值。然后,将这个伪随机值和mask按位相与,得到最终的PG序号(pgid)。根据RADOS的设计,给定PG的总数为m(m应该为2的整数幂),则mask的值为m-1。因此,哈希值计算和按位与操作的整体结果事实上是从所有m个PG中近似均匀地随机选择一个。基于这一机制,当有大量object和大量PG时,RADOS能够保证object和PG之间的近似均匀映射。又因为object是由file切分而来,大部分object的size相同,因而,这一映射最终保证了,各个PG中存储的object的总数据量近似均匀。
  从介绍不难看出,这里反复强调了“大量”。只有当object和PG的数量较多时,这种伪随机关系的近似均匀性才能成立,Ceph的数据存储均匀性才有保证。为保证“大量”的成立,一方面,object的最大size应该被合理配置,以使得同样数量的file能够被切分成更多的object;另一方面,Ceph也推荐PG总数应该为OSD总数的数百倍,以保证有足够数量的PG可供映射。
(3)PG -> OSD映射
  第三次映射就是将作为object的逻辑组织单元的PG映射到数据的实际存储单元OSD。如图所示,RADOS采用一个名为CRUSH的算法,将pgid代入其中,然后得到一组共n个OSD。这n个OSD即共同负责存储和维护一个PG中的所有object。前已述及,n的数值可以根据实际应用中对于可靠性的需求而配置,在生产环境下通常为3。具体到每个OSD,则由其上运行的OSD deamon负责执行映射到本地的object在本地文件系统中的存储、访问、元数据维护等操作。
  Ceph通过三次映射,完成了从file到object、PG和OSD整个映射过程。通观整个过程,可以看到,这里没有任何的全局性查表操作需求。
五、数据的操作流程
以file写入过程为例,对数据操作流程进行说明。
为简化说明,便于理解,此处进行若干假定。首先,假定待写入的file较小,无需切分,仅被映射为一个object。其次,假定系统中一个PG被映射到3个OSD上。
基于上述假定,则file写入流程可以被下图表示:

如图所示,当某个client需要向Ceph集群写入一个file时,首先需要在本地完成上面叙述的寻址流程,将file变为一个object,然后找出存储该object的一组三个OSD。这三个OSD具有各自不同的序号,序号最靠前的那个OSD就是这一组中的Primary OSD,而后两个则依次是Secondary OSD和Tertiary OSD。
  找出三个OSD后,client将直接和Primary OSD通信,发起写入操作(步骤1)。Primary OSD收到请求后,分别向Secondary OSD和Tertiary OSD发起写入操作(步骤2、3)。当Secondary OSD和Tertiary OSD各自完成写入操作后,将分别向Primary OSD发送确认信息(步骤4、5)。当Primary OSD确信其他两个OSD的写入完成后,则自己也完成数据写入,并向client确认object写入操作完成(步骤6)。
  之所以采用这样的写入流程,本质上是为了保证写入过程中的可靠性,尽可能避免造成数据丢失。同时,由于client只需要向Primary OSD发送数据,因此,在Internet使用场景下的外网带宽和整体访问延迟又得到了一定程度的优化。
  当然,这种可靠性机制必然导致较长的延迟,特别是,如果等到所有的OSD都将数据写入磁盘后再向client发送确认信号,则整体延迟可能难以忍受。因此,Ceph可以分两次向client进行确认。当各个OSD都将数据写入内存缓冲区后,就先向client发送一次确认,此时client即可以向下执行。待各个OSD都将数据写入磁盘后,会向client发送一个最终确认信号,此时client可以根据需要删除本地数据。
  分析上述流程可以看出,在正常情况下,client可以独立完成OSD寻址操作,而不必依赖于其他系统模块。因此,大量的client可以同时和大量的OSD进行并行操作。同时,如果一个file被切分成多个object,这多个object也可被并行发送至多个OSD。
从OSD的角度来看,由于同一个OSD在不同的PG中的角色不同,因此,其工作压力也可以被尽可能均匀地分担,从而避免单个OSD变成性能瓶颈。
  如果需要读取数据,client只需完成同样的寻址过程,并直接和Primary OSD联系。
六、集群维护
  从上面的学习,我们知道由若干个monitor共同负责整个Ceph集群中所有OSD状态的发现与记录,并且共同形成cluster map的master版本,然后扩散至全体OSD以及client。OSD使用cluster map进行数据的维护,而client使用cluster map进行数据的寻址。
  在集群中,各个monitor的功能总体上是一样的,其相互间的关系可以被简单理解为主从备份关系。monitor并不主动轮询各个OSD的当前状态。正相反,OSD需要向monitor上报状态信息。常见的上报有两种情况:一是新的OSD被加入集群,二是某个OSD发现自身或者其他OSD发生异常。在收到这些上报信息后,monitor将更新cluster map信息并加以扩散。
  Cluster map的实际内容包括:
Montior Map: 包含集群的 fsid 、位置、名字、地址和端口,也包括当前版本、创建时间、最近修改时间。要查看监视器图,用 ceph mon dump 命令。
OSD Map: 包含集群 fsid 、创建时间、最近修改时间、存储池列表、副本数量、归置组数量、 OSD 列表及其状态(如 up 、 in )。要查看OSD运行图,用 ceph osd dump 命令。
OSD状态的描述分为两个维度:up或者down(表明OSD是否正常工作),in或者out(表明OSD是否在至少一个PG中)。因此,对于任意一个OSD,共有四种可能的状态:
—— Up且in:说明该OSD正常运行,且已经承载至少一个PG的数据。这是一个OSD的标准工作状态;
—— Up且out:说明该OSD正常运行,但并未承载任何PG,其中也没有数据。一个新的OSD刚刚被加入Ceph集群后,便会处于这一状态。而一个出现故障的OSD被修复后,重新加入Ceph集群时,也是处于这一状态;
—— Down且in:说明该OSD发生异常,但仍然承载着至少一个PG,其中仍然存储着数据。这种状态下的OSD刚刚被发现存在异常,可能仍能恢复正常,也可能会彻底无法工作;
—— Down且out:说明该OSD已经彻底发生故障,且已经不再承载任何PG。
PG Map::** 包含归置组版本、其时间戳、最新的 OSD 运行图版本、占满率、以及各归置组详情,像归置组 ID 、 up set 、 acting set 、 PG 状态(如 active+clean ),和各存储池的数据使用情况统计。
CRUSH Map::** 包含存储设备列表、故障域树状结构(如设备、主机、机架、行、房间、等等)、和存储数据时如何利用此树状结构的规则。要查看 CRUSH 规则,执行 ceph osd getcrushmap -o {filename} 命令;然后用 crushtool -d {comp-crushmap-filename} -o {decomp-crushmap-filename} 反编译;然后就可以用 cat 或编辑器查看了。
MDS Map: 包含当前 MDS 图的版本、创建时间、最近修改时间,还包含了存储元数据的存储池、元数据服务器列表、还有哪些元数据服务器是 up 且 in 的。要查看 MDS 图,执行 ceph mds dump 。
七、OSD增加流程
(1)一个新的OSD上线后,首先根据配置信息与monitor通信。Monitor将其加入cluster map,并设置为up且out状态,再将最新版本的cluster map发给这个新OSD。收到monitor发来的cluster map之后,这个新OSD计算出自己所承载的PG(为简化讨论,此处我们假定这个新的OSD开始只承载一个PG),以及和自己承载同一个PG的其他OSD。然后,新OSD将与这些OSD取得联系。如图:

(2)如果这个PG目前处于降级状态(即承载该PG的OSD个数少于正常值,如正常应该是3个,此时只有2个或1个。这种情况通常是OSD故障所致),则其他OSD将把这个PG内的所有对象和元数据复制给新OSD。数据复制完成后,新OSD被置为up且in状态。而cluster map内容也将据此更新。这事实上是一个自动化的failure recovery过程。当然,即便没有新的OSD加入,降级的PG也将计算出其他OSD实现failure recovery,如图:

(3)如果该PG目前一切正常,则这个新OSD将替换掉现有OSD中的一个(PG内将重新选出Primary OSD),并承担其数据。在数据复制完成后,新OSD被置为up且in状态,而被替换的OSD将退出该PG(但状态通常仍然为up且in,因为还要承载其他PG)。而cluster map内容也将据此更新。这事实上是一个自动化的数据re-balancing过程,如图:

(4)如果一个OSD发现和自己共同承载一个PG的另一个OSD无法联通,则会将这一情况上报monitor。此外,如果一个OSD deamon发现自身工作状态异常,也将把异常情况主动上报给monitor。在上述情况下,monitor将把出现问题的OSD的状态设为down且in。如果超过某一预订时间期限,该OSD仍然无法恢复正常,则其状态将被设置为down且out。反之,如果该OSD能够恢复正常,则其状态会恢复为up且in。在上述这些状态变化发生之后,monitor都将更新cluster map并进行扩散。这事实上是自动化的failure detection过程。
八、ceph的POOL、PG、PGP、OSD
1、pool
一个 Pool 是 Ceph 中的一些对象的逻辑分组,它并不表示一个连续的分区,而只是一个逻辑概念,类似于将二进制数据打了tag一样然后根据tag归类一样。它类似于 LVM 中的 Volume Group,类似于一个命名空间。RBD Image 类似于 LVM 中的 Logical Volume。RBD Image 必须且只能在一个 Pool 中。Pool 由若干个PG组成。其属性包括:
所有性和访问权限
对象副本数目
PG 数目
CRUSH 规则集合
Ceph Pool 有两种类型:
Replicated pool:拷贝型 pool,通过生成对象的多份拷贝来确保在部分 OSD 丢失的情况下数据不丢失。这种类型的 pool 需要更多的裸存储空间,但是它支持所有的 pool 操作。
Erasure-coded pool:纠错码型 pool(类似于 Software RAID)。在这种 pool 中,每个数据对象都被存放在 K+M 个数据块中:对象被分成 K 个数据块和 M 个编码块;pool 的大小被定义成 K+M 块,每个块存储在一个 OSD 中;块的顺序号作为 object 的属性保存在对象中。可见,这种 pool 用更少的空间实现存储,即节约空间;纠删码实现了高速的计算,但有2个缺点,一个是速度慢,一个是只支持对象的部分操作(比如:不支持局部写)。这篇文章 详细介绍了其原理和细节。
Pool 提供如下的能力:
Resilience(弹力):即在确保数据不丢失的情况允许一定的 OSD 失败,这个数目取决于对象的拷贝(copy/replica)份数。对拷贝型 pool 来说,Ceph 中默认的拷贝份数是2,这意味着除了对象自身外,它还有一个另外的备份。你可以自己决定一个 Pool 中的对象的拷贝份数。
Placement Groups(放置组):Ceph 使用 PG 来组织对象,这是因为对象可能成千上万,因此一个一个对象来组织的成本是非常高的。PG 的值会影响 Ceph 集群的行为和数据的持久性。你可以设置 pool 的 PG 数目。推荐的配置是,每个 OSD 大概 100 个 PG。
CRUSH Rules (CRUSH 规则):数据映射的策略。系统默认提供 “replicated_ruleset"。用户可以自定义策略来灵活地设置 object 存放的区域。比如可以指定 pool1中所有objecst放置在机架1上,所有objects的第1个副本放置在机架1上的服务器A上,第2个副本分布在机架1上的服务器B上。 pool2中所有的object分布在机架2、3、4上,所有Object的第1个副本分布在机架2的服务器上,第2个副本分布在机架3的服 器上,第3个副本分布在机架4的服务器上。详细的信息可以参考这些文档 (1)(2)(3)(4)。
Snapshots(快照):你可以对 pool 做快照。
Set Ownership:设置 pool 的 owner 的用户 ID。
Ceph 集群创建后,默认创建了 data,metadata 和 rbd 三个存储池。
2、pg
PG 概念
PG概念非常复杂,主要有如下几点:
PG 也是对象的逻辑集合。同一个PG 中的所有对象在相同的 OSD 上被复制。
PG 聚合一部分对象成为一个组(group),这个组被放在某些OSD上(place),合起来就是 Placemeng Group (放置组)了。
Epoch:PG map 的版本号,它是一个单调递增的序列。
Peering:见下文的状态(8)描述。详细过程请参阅 Ceph:pg peering过程分析。
Acting set:支持一个 PG 的所有 OSD 的有序列表,其中第一个 OSD 是主OSD,其余为次。acting set 是 CRUSH 算法分配的,但是不一定已经生效了。
Up set:某一个 PG map 历史版本的 acting set。在大多数情况下,acting set 和 up set 是一致的,除非出现了 pg_temp。
Current Interval or Past Interval:若干个连续的版本号,这些版本中 acting 和 up set 保持不变。
PG temp:在Ceph 正在往主 OSD 回填数据时,这个主OSD是不能提供数据服务的,这时候,它会向 MON 申请一个临时的 acting set,这就是 PG temp。举个例子,现在 acting set 是[0,1,2],出现了一点事情后,它变为 [3,1,2],此时 osd.3 还是空的因此它无法提供数据服务因此它还需要等待backfilling过程结束,因此,它会向 MON 申请一个临时的 set 比如 [1,2,3],此时将由 osd.1 提供数据服务。回填过程结束后,该临时 set 会被丢弃,重新由 osd.3 提供服务。
主 (primary) OSD:在 acting set 中的首个 OSD,负责接收客户端写入数据;默认情况下,提供数据读服务,但是该行为可以被修改。它还负责 peering 过程,以及在需要的时候申请 PG temp。
次 (replica)OSD:在 acting set 中的除了第一个以外的其余 OSD。
流浪 (stray) OSD:已经不是 acting set 中了,但是还没有被告知去删除数据 的 OSD。
PG 的 acting set 是由 CRUSH 算法根据 CRUSH Rules 动态地计算得出的。

PG特点
其主要特点如下:
基本特点
PG 确定了 pool 中的对象和 OSD 之间的映射关系。一个 object 只会存在于一个 PG 中,但是多个 object 可以在同一个 PG 内。
Pool 的 PG 数目是创建 pool 时候指定的,Ceph 官方有推荐的计算方法。其值与 OSD 的总数的关系密切。当Ceph 集群扩展 OSD 增多时,根据需要,可以增加 pool 的 PG 数目。
对象的副本数目,也就是被拷贝的次数,是在创建 Pool 时指定的。该分数决定了每个 PG 会在几个 OSD 上保存对象。如果一个拷贝型 Pool 的size(拷贝份数)为 2,它会包含指定数目的 PG,每个 PG 使用两个 OSD,其中,第一个为主 OSD (primary),其它的为从 OSD (secondary)。不同的 PG 可能会共享一个 OSD。
Ceph 引入 PG 的目的主要是为了减少直接将对象映射到 OSD 的复杂度。
PG 也是Ceph 集群做清理(scrubbing)的基本单位,也就是说数据清理是一个一个PG来做的。
PG 和 OSD 之间的映射关系由 CRUSH 决定,而它做决定的依据是 CRUSH 规则(rules)。CRUSH 将所有的存储设备(OSD)组织成一个分层结构,该结构能区分故障域(failure domain),该结构中每个节点都是一个 CRUSH bucket。详细情况请阅读 CRUSH 相关的文档。
PG 和 OSD 的关系是动态的:
一开始在 PG 被创建的时候,MON 根据 CRUSH 算法计算出 PG 所在的 OSD。这是它们之间的初始关系。
Ceph 集群中 OSD 的状态是不断变化的,它会在如下状态之间做切换:
up:守护进程运行中,能够提供IO服务;
down:守护进程不在运行,无法提供IO服务;
in:包含数据;
out:不包含数据
部分 PG 和 OSD 的关系会随着 OSD 状态的变化而发生变化。
当新的 OSD 被加入集群后,已有OSD上部分PG将可能被挪到新OSD上;此时PG 和 OSD 的关系会发生改变。
当已有的某 OSD down 了并变为 out 后,其上的 PG 会被挪到其它已有的 OSD 上。
但是大部分的 PG 和 OSD 的关系将会保持不变,在状态变化时,Ceph 尽可能只挪动最少的数据。
客户端根据 Cluster map 以及 CRUSH Ruleset 使用 CRUSH 算法查找出某个 PG 所在的 OSD 列表(其实是 up set)。
PG-Object-OSD 的关系如下图所示:

PG 的创建过程(详细过程请参考 PG 的创建过程):
MON 节点上有PGMonitotor,它发现有 pool 被创建后,判断该 pool 是否有 PG。如果有PG,则一一判断这些 PG 是否已经存在,如果不存在,则开始下面的创建 PG 的过程。
创建过程的开始,设置PG 状态为 Creating,并将它加入待创建PG队列 creating_pgs,等待被处理。
开始处理后,使用 CRUSH 算法根据当前的 OSD map 找出来 up/acting set,加入 PG map 中以这个 set 中 OSD 为索引的队列 creating_pgs_by_osd。(看起来只会加入到主OSD的队列中)。
队列处理函数将该 OSD 上需要创建的 PG 合并,生成消息MOSDPGCreate,通过消息通道发给 OSD。
OSD 收到消息字为 MSG_OSD_PG_CREATE 的消息,得到消息中待创建的 PG 信息,判断类型,并获取该PG的其它OSD,加入队列 creating_pgs (似乎是由主 OSD 负责发起创建次 OSD 上的PG),再创建具体的 PG。
PG 被创建出来以后,开始 Peering 过程。
PG 值的确定:创建 pool 时需要确定其 PG 的数目,在 pool 被创建后也可以调整该数字,该数目会影响到:
数据的持久性:考虑pool 的 size 为 3,表明每个 PG 会将数据存放在 3 个 OSD 上。当一个 OSD down 了后,一定间隔后将开始 recovery 过程,recovery结束前,有部分 PG 的数据将只有两个副本。这时候和需要被恢复的数据的数量有关系,如果该 OSD 上的 PG 过多,则花的时间将越长,风险将越大。如果此时再有一个 OSD down 了,那么将有一部分 PG 的数据只有一个副本,recovery 过程继续。如果再出现第三个 OSD down 了,那么可能会出现部分数据丢失。可见,每个 OSD 上的PG数目不宜过大,否则,会降低数据的持久性。这也就要求在添加 OSD 后,PG 的数目在需要的时候也需要相应增加。
数据的均匀分布性:CRUSH 算法会伪随机地保证 PG 被选中来存放客户端的数据,它还会尽可能地保证所有的 PG 均匀分布在所有的 OSD 上。比方说,有10个OSD,但是只有一个 size 为 3 的 pool,它只有一个 PG,那么10个 OSD 中将只有三个 OSD 被用到。但是 CURSH 算法在计算的时候不会考虑到OSD上已有数据的大小。比方说,100万个4K对象共4G均匀地分布在10个OSD上的1000个PG内,那么每个 OSD 上大概有400M 数据。再加进来一个400M的对象(假设它不会被分割),那么有三块 OSD 上将有 400M + 400M = 800 M 的数据,而其它七块 OSD 上只有 400M 数据。
资源消耗:PG 作为一个逻辑实体,它需要消耗一定的资源,包括内存,CPU 和带宽。太多 PG 的话,则占用资源会过多。
清理时间:Ceph 的清理工作是以 PG 为单位进行的。如果一个 PG 内的数据太多,则其清理时间会很长。
那如何确定一个 Pool 中有多少 PG?Ceph 不会自己计算,而是给出了一些参考原则,让 Ceph 用户自己计算:
少于 5 个 OSD, 建议设为 128
5 到 10 个 OSD,建议设为 512
10 到 50 个 OSD,建议设为 4096
50 个 OSD 以上,就需要有更多的权衡来确定 PG 数目
你可以使用 pgcalc 工具
PG 的状态也是不断变化的,其主要状态包括:
Creating 创建中:PG 正在被创建。
Peering 对等互联:表示一个过程,该过程中一个 PG 的所有 OSD 都需要互相通信来就PG 的对象及其元数据的状态达成一致。处于该状态的PG不能响应IO请求。Peering的过程其实就是pg状态从初始状态然后到active+clean的变化过程。一个 OSD 启动之后,上面的pg开始工作,状态为initial,这时进行比对所有osd上的pglog和pg_info,对pg的所有信息进行同步,选举primary osd和replica osd,peering过程结束,然后把peering的结果交给recovering,由recovering过程进行数据的恢复工作。
Active 活动的:Peering 过程完成后,PG 的状态就是 active 的。此状态下,在主次OSD 上的PG 数据都是可用的。
Clean 洁净的:此状态下,主次 OSD 都已经被 peered 了,每个副本都就绪了。
Down:PG 掉线了,因为存放其某些关键数据(比如 pglog 和 pginfo,它们也是保存在OSD上)的副本 down 了。
Degraded 降级的:某个 OSD 被发现停止服务 (down)了后,Ceph MON 将该 OSD 上的所有 PG 的状态设置为 degraded,此时该 OSD 的 peer OSD 会继续提供数据服务。这时会有两种结果:一是它会重新起来(比如重启机器时),需要再经过 peering 过程再到clean 状态,而且 Ceph 会发起 recovery (恢复)过程,使该 OSD 上过期的数据被恢复到最新状态;二是 OSD 的 down 状态持续 300 秒后其状态被设置为 out,Ceph 会选择其它的 OSD 加入 acting set,并启动回填(backfilling)数据到新 OSD 的过程,使 PG 副本数恢复到规定的数目。详情可以参考 PG 的数据恢复过程。
Recovering 恢复中:一个 OSD down 后,其上面的 PG 的内容的版本会比其它OSD上的 PG 副本的版本落后。在它重启之后(比如重启机器时),Ceph 会启动 recovery 过程来使其数据得到更新。
Backfilling 回填中:一个新 OSD 加入集群后,Ceph 会尝试级将部分其它 OSD 上的 PG 挪到该新 OSD 上,此过程被称为回填。与 recovery 相比,回填(backfill)是在零数据的情况下做全量拷贝,而恢复(recovery)是在已有数据的基础上做增量恢复。
Remapped 重映射:每当 PG 的 acting set 改变后,就会发生从旧 acting set 到新 acting set 的数据迁移。此过程结束前,旧 acting set 中的主 OSD 将继续提供服务。一旦该过程结束,Ceph 将使用新 acting set 中的主 OSD 来提供服务。
Stale 过期的:OSD 每隔 0.5 秒向 MON 报告其状态。如果因为任何原因,主 OSD 报告状态失败了,或者其它OSD已经报告其主 OSD down 了,Ceph MON 将会将它们的 PG 标记为 stale 状态。
PG 的所有的状态是一个类似树形的结构,每个状态可能存在子状态,子状态还可能存在子状态,如下图所示:

(来源)
更多的状态请参考 http://docs.ceph.com/docs/master/rados/operations/pg-states/。实际上 PG 的状态可以是以上这些状态的组合,比如:
[root@ceph-mon ~]# ceph -s
cluster c5476875-2a04-41b7-a4e8-421133c69ac8
health HEALTH_WARN
28 pgs backfill #回填,有新的 OSD 被加入了?
79 pgs degraded #降级,有 OSD down 了?
10 pgs recovering #恢复中
42 pgs recovery_wait #等待恢复
80 pgs stuck unclean #有 80个 PG 一直处于 unclean 状态
27 pgs undersized #GP 的副本数小于pool size
recovery 4814/27835 objects degraded (17.295%)
recovery 2047/27835 objects misplaced (7.354%)
注意,只有当所有的 PG 都是 active + clean 状态时,集群的状态才是 HEALTH_OK 的。
清理 scrubbing:Ceph 以 PG 为单位进行数据清理,以保证数据的完整性,它的作用类似于文件系统的 fsck 工具。
有两种比较方式:(1)light scrubbing:比较对象的size和属性,一般每天进行 (2)deep scrubbing:读取对象的数据,比较检验码,一般每周进行。
Ceph 的 OSD 定期启动 scrub 线程来扫描部分对象,通过与其他副本比对来发现是否一致,如果存在不一致,抛出异常提示用户手动解决。管理员也可以手工发起。
Scrub 以 PG 为单位,对于每一个PG,Ceph 分析该 PG 下所有的对象, 产生一个类似于元数据信息摘要的数据结构,如对象大小,属性等,叫scrubmap, 比较主与副scrubmap,来保证是不是有object 丢失或者不匹配。
Scrub 方式分成两种, classic vs. chunky。Scrub 流程需要提取对象的校验信息然后跟其他副本的校验信息对比,这期间被校验对象的数据是不能被修改的,所以 write 请求会被 block. 由于 PG 可能包含成千上万 objects, chunk 每一次的比较只取其中一部分 objects 来比较,这样只 block一小部分object的write请求。这是在ceph的Bobtail(v0.56 Jan 1 2013)引入的feature,称为chunky scrub。Classic scrub 没有引入chunk, 会block所有的write请求。
该机制对保证数据的完整性非常重要,但是也会消耗大量的集群资源,block 住一部分对象的写入操作,降低集群的性能,特别是当一个OSD服务器上多个OSD同时进行深度清理的时候。这篇文章 Ceph Deep-Scrubbing Impact Study 说当有三个深度清理线程发生时,性能有明显的下降。
3、pgp
PG = Placement Group
PGP = Placement Group for Placement purpose
pg_num = number of placement groups mapped to an OSD
When pg_num is increased for any pool, every PG of this pool splits into half, but they all remain mapped to their parent OSD.
Until this time, Ceph does not start rebalancing. Now, when you increase the pgp_num value for the same pool, PGs start to migrate from the parent to some other OSD, and cluster rebalancing starts. This is how PGP plays an important role.
By Karan Singh

怎么设置PG数目
http://docs.ceph.com/docs/mimic/rados/operations/placement-groups/
副本:OSD100/副本数
纠删码:OSD
100/(K+M)
向上舍成2的幂

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值