CEPH分布式存储介绍与原理架构概述

一、Ceph 简介

Ceph 是一个统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。

Ceph 项目最早起源于 Sage 就读博士期间的工作(最早的成果于2004年发表),并随后贡献给开源社区。在经过了数年的发展之后,目前已得到众多云计算厂商的支持并被广泛应用。

RedHat 及 OpenStack 都可与 Ceph 整合以支持虚拟机镜像的后端存储。

二、基础知识:

1  Ceph基础介绍

Ceph是一个可靠地、自动重均衡、自动恢复的分布式存储系统,根据场景划分可以将Ceph分为三大块,分别是对象存储、块设备存储和文件系统服务。在虚拟化领域里,比较常用到的是Ceph的块设备存储,比如在OpenStack项目里,Ceph的块设备存储可以对接OpenStack的cinder后端存储、Glance的镜像存储和虚拟机的数据存储,比较直观的是Ceph集群可以提供一个raw格式的块存储来作为虚拟机实例的硬盘。

Ceph相比其它存储的优势点在于它不单单是存储,同时还充分利用了存储节点上的计算能力,在存储每一个数据时,都会通过计算得出该数据存储的位置,尽量将数据分布均衡,同时由于Ceph的良好设计,采用了CRUSH算法、HASH环等方法,使得它不存在传统的单点故障的问题,且随着规模的扩大性能并不会受到影响。

2  Ceph的核心组件

Ceph的核心组件包括Ceph OSD、Ceph Monitor和Ceph MDS。

Ceph OSD:OSD的英文全称是Object Storage Device,它的主要功能是存储数据、复制数据、平衡数据、恢复数据等,与其它OSD间进行心跳检查等,并将一些变化情况上报给Ceph Monitor。一般情况下一块硬盘对应一个OSD,由OSD来对硬盘存储进行管理,当然一个分区也可以成为一个OSD。

Ceph OSD的架构实现由物理磁盘驱动器、Linux文件系统和Ceph OSD服务组成,对于Ceph OSD Deamon而言,Linux文件系统显性的支持了其拓展性,一般Linux文件系统有好几种,比如有BTRFS、XFS、Ext4等,BTRFS虽然有很多优点特性,但现在还没达到生产环境所需的稳定性,一般比较推荐使用XFS。

伴随OSD的还有一个概念叫做Journal盘,一般写数据到Ceph集群时,都是先将数据写入到Journal盘中,然后每隔一段时间比如5秒再将Journal盘中的数据刷新到文件系统中。一般为了使读写时延更小,Journal盘都是采用SSD,一般分配10G以上,当然分配多点那是更好,Ceph中引入Journal盘的概念是因为Journal允许Ceph OSD功能很快做小的写操作;一个随机写入首先写入在上一个连续类型的journal,然后刷新到文件系统,这给了文件系统足够的时间来合并写入磁盘,一般情况下使用SSD作为OSD的journal可以有效缓冲突发负载。

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特点

高性能
a. 摒弃了传统的集中式存储元数据寻址的方案,采用 CRUSH 算法,数据分布均衡,并行度高。
b. 考虑了容灾域的隔离,能够实现各类负载的副本放置规则,例如跨机房、机架感知等。
c. 能够支持上千个存储节点的规模,支持 TB 到 PB 级的数据。


高可用性
a. 副本数可以灵活控制。
b. 支持故障域分隔,数据强一致性。
c. 多种故障场景自动进行修复自愈。
d. 没有单点故障,自动管理。


高可扩展性
a. 去中心化。
b. 扩展灵活。
c. 随着节点增加而线性增长。

特性丰富
a. 支持三种存储接口:块存储、文件存储、对象存储。
b. 支持自定义接口,支持多种语言驱动。

四、Ceph 架构

Ceph 为普通硬件设计,这可使构建、维护 PB 级数据集群的费用相对低廉。规划集群硬件时,需要均衡几方面的因素,包括区域失效和潜在的性能问题。硬件规划要包含把使用 Ceph 集群的 Ceph 守护进程和其他进程恰当分布。通常,我们推荐在一台机器上只运行一种类型的守护进程。我们推荐把使用数据集群的进程(如 OpenStack 、 CloudStack 等)安装在别的机器上。

       CEPH分布式存储介绍与原理架构概述_第1张图片

建议每台机器最少两个千兆网卡,现在大多数机械硬盘都能达到大概 100MB/s 的吞吐量,网卡应该能处理所有 OSD 硬盘总吞吐量,所以推荐最少两个千兆网卡,分别用于公网(前端)和集群网络(后端)。集群网络(最好别连接到国际互联网)用于处理由数据复制产生的额外负载,而且可防止拒绝服务攻击,拒绝服务攻击会干扰数据归置组,使之在 OSD 数据复制时不能回到 active + clean 状态。请考虑部署万兆网卡。通过 1Gbps 网络复制 1TB 数据耗时 3 小时,而 3TB (典型配置)需要 9 小时,相比之下,如果使用 10Gbps 复制时间可分别缩减到 20 分钟和 1 小时。在一个 PB 级集群中, OSD 磁盘失败是常态,而非异常;在性价比合理的的前提下,系统管理员想让 PG 尽快从 degraded (降级)状态恢复到 active + clean 状态。另外,一些部署工具(如 Dell 的 Crowbar )部署了 5 个不同的网络,但使用了 VLAN 以提高网络和硬件可管理性。 VLAN 使用 802.1q 协议,还需要采用支持 VLAN 功能的网卡和交换机,增加的硬件成本可用节省的运营(网络安装、维护)成本抵消。使用 VLAN 来处理集群和计算栈(如 OpenStack 、 CloudStack 等等)之间的 VM 流量时,采用 10G 网卡仍然值得。每个网络的机架路由器到核心路由器应该有更大的带宽,如 40Gbps 到 100Gbps 。

Ceph 独一无二地用统一的系统提供了对象、块、和文件存储功能,它可靠性高、管理简便、并且是自由软件。 Ceph 的强大足以改变贵公司的 IT 基础架构、和管理海量数据的能力。Ceph 可提供极大的伸缩性——供成千用户访问 PB 乃至 EB 级的数据。 Ceph 节点以普通硬件和智能守护进程作为支撑点, Ceph 存储集群组织起了大量节点,它们之间靠相互通讯来复制数据、并动态地重分布数据。

CEPH分布式存储介绍与原理架构概述_第2张图片

从架构图中可以看到最底层的是RADOS,RADOS自身是一个完整的分布式对象存储系统,它具有可靠、智能、分布式等特性,Ceph的高可靠、高可拓展、高性能、高自动化都是由这一层来提供的,用户数据的存储最终也都是通过这一层来进行存储的,RADOS可以说就是Ceph的核心。

RADOS系统主要由两部分组成,分别是OSD和Monitor。

基于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的文件系统。

  Ceph数据分布算法

在分布式存储系统中比较关注的一点是如何使得数据能够分布得更加均衡,常见的数据分布算法有一致性Hash和Ceph的Crush算法。Crush是一种伪随机的控制数据分布、复制的算法,Ceph是为大规模分布式存储而设计的,数据分布算法必须能够满足在大规模的集群下数据依然能够快速的准确的计算存放位置,同时能够在硬件故障或扩展硬件设备时做到尽可能小的数据迁移,Ceph的CRUSH算法就是精心为这些特性设计的,可以说CRUSH算法也是Ceph的核心之一。

在说明CRUSH算法的基本原理之前,先介绍几个概念和它们之间的关系。

存储数据与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内对象的变动

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

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

CEPH分布式存储介绍与原理架构概述_第3张图片

 本质上CRUSH算法是根据存储设备的权重来计算数据对象的分布的,权重的设计可以根据该磁盘的容量和读写速度来设置,比如根据容量大小可以将1T的硬盘设备权重设为1,2T的就设为2,在计算过程中,CRUSH是根据Cluster Map、数据分布策略和一个随机数共同决定数组最终的存储位置的。

Cluster Map里的内容信息包括存储集群中可用的存储资源及其相互之间的空间层次关系,比如集群中有多少个支架,每个支架中有多少个服务器,每个服务器有多少块磁盘用以OSD等。

数据分布策略是指可以通过Ceph管理者通过配置信息指定数据分布的一些特点,比如管理者配置的故障域是Host,也就意味着当有一台Host起不来时,数据能够不丢失,CRUSH可以通过将每个pg的主从副本分别存放在不同Host的OSD上即可达到,不单单可以指定Host,还可以指定机架等故障域,除了故障域,还有选择数据冗余的方式,比如副本数或纠删码。

下面这个式子简单的表明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 核心组件及概念介绍

    Monitor:一个 Ceph 集群需要多个 Monitor 组成的小集群,它们通过 Paxos 同步数据,用来保存 OSD 的元数据。

    OSD:全称 Object Storage Device,也就是负责响应客户端请求返回具体数据的进程。一个 Ceph 集群一般都有很多个 OSD。

    MDS:全称 Ceph Metadata Server,是 CephFS 服务依赖的元数据服务。

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

    PG:全称 Placement Grouops,是一个逻辑的概念,一个 PG 包含多个 OSD。引入 PG 这一层其实是为了更好的分配数据和定位数据。

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

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

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

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

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

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

六、块存储 

    典型设备:
    磁盘阵列,硬盘
    主要是将裸磁盘空间映射给主机使用的。

    优点:
    a. 通过 Raid 与 LVM 等手段,对数据提供了保护。
    b. 多块廉价的硬盘组合起来,提高容量。
    c. 多块磁盘组合出来的逻辑盘,提升读写效率。

    缺点:
    a. 采用 SAN 架构组网时,光纤交换机,造价成本高。  
    b. 主机之间无法共享数据。

    使用场景:
    a. docker 容器、虚拟机磁盘存储分配。
    b. 日志存储。
    c. 文件存储。
    d. …

七、文件存储

    典型设备:

    FTP、NFS 服务器
    为了克服块存储文件无法共享的问题,所以有了文件存储。
    在服务器上架设 FTP 与 NFS 服务,就是文件存储。

    优点:

    a. 造价低,随便一台机器就可以了。
    b. 方便文件共享。

    缺点:

    a. 读写速率低。
    b. 传输速率慢。

    使用场景:

    a. 日志存储。
    b. 有目录结构的文件存储。
    c. …

八、对象存储

Ceph的存储过程

文件->obj->pool->pg->osd->disk
  • 文件被分片成对象
  • 对象存放于特定的pool
  • pool由多个pg组成
  • pg对应多个osd
  • osd直接对应disk

   

典型设备:
    内置大容量硬盘的分布式服务器(swift, s3)
    多台服务器内置大容量硬盘,安装上对象存储管理软件,对外提供读写访问功能。

    优点:
    a. 具备块存储的读写高速。
    b. 具备文件存储的共享等特性。

    使用场景:
    (适合更新变动较少的数据)

    a. 图片存储。
    b. 视频存储。
    c. …

九、Ceph Pool 和 PG 分布情况

  CEPH分布式存储介绍与原理架构概述_第4张图片

说明:
a. pool 是 ceph 存储数据时的逻辑分区,它起到 namespace 的作用。
b. 每个 pool 包含一定数量(可配置)的 PG。
c. PG 里的对象被映射到不同的 OSD 上。
d. pool 是分布到整个集群的。
e. pool 可以做故障隔离域,根据不同的用户场景不一进行隔离。

十、Ceph 数据扩容 PG 分布

场景数据迁移流程:

a. 现状3个 OSD, 4个 PG

b. 扩容到4个 OSD, 4个 PG

现状:

CEPH分布式存储介绍与原理架构概述_第5张图片

扩容后:

CEPH分布式存储介绍与原理架构概述_第6张图片

    说明:
    1、每个 OSD 上分布很多 PG, 并且每个 PG 会自动散落在不同的 OSD 上。
    2、如果扩容那么相应的 PG 会进行迁移到新的 OSD 上,保证 PG 数量的均衡。

 十、Ceph  分布式存储架构解析与工作原理

Ceph 的架构:分布式服务进程

在这里插入图片描述

Ceph Monitor(MON)

Ceph 监视器服务进程,简称 MON。负责监控集群的监控状态,所有的集群节点都向 MON 节点报告状态以及每个状态变化的信息。MON 通过收集这些信息并维护一个 Cluster Map 来完成它的任务。Cluster Map 下属包含每个组件的 Map,例如:MON Map、OSD Map、PG Map、CRUSH Map 和 MDS Map。一个典型的 Cepb 集群中通常存在多个 MON 节点,它们之间启用了仲 裁(Quorum)这种分布式决策机制,应用 Paxos 算法保持各节点 Cluster Map 的一致性。所以集群中 MON 节点数应该是一个奇数,开始仲裁操作时至少要保证有一半以上的 MON 处于可用状态,这样才可以防止传统存储系统中常见的脑裂问题。OSD 只有在一些特殊情况(e.g. 添加新的 OSD、OSD 发现自身或他人存在异常)才会上报自己的信息,平常只会简单的发送心跳。MON 在收到这些上报信息时,则会更新 Cluster Map 并加以扩散。

  • MON Map:维护着 MON 节点间端到端的信息。包括 Ceph Cluster ID、MON hostname、IP:Port 以及当前 MON Map 的创建版本和最后一次修改信息,帮助确定集群应该遵循哪个版本。
  • OSD Map:维护着 Ceph Cluster ID、OSD 数目、状态、权重、主机、以及 Pool 相关的信息(e.g. Pool name、Pool ID、Pool Type、副本数、PG ID),以及存储了 OSD map 创建版本和最后一次修改信息。
  • PG Map :维护着 PG 的版本、时间戳、容量比例、最新的 OSD Map 版本、PG ID、对象数、OSD 的 Up Set、OSD 的 Acting Set、Clean 状态等信息。
  • CRUSH Map:维护着集群的存储设备信息、故障域层次结构以及在故障域中如何存储数据的规则定义。
  • MDS Map:维护着元数据池 ID、MDS 数量、状态、创建时间和当前的 MDS Map 版本等信息。

Ceph Object Storage Device Daemon(OSD)

Ceph 对象存储设备服务进程,简称 OSD。一个 OSD 守护进程与集群中的一个物理磁盘绑定,OSD 负责将数据以 Object 的形式存储在这些物理磁盘中,并在客户端发起数据请求时提供相同的数据。一般来说,物理磁盘的 总数与 Ceph 集群中负责存储用户数据到每个物理磁盘的 OSD 守护进程数是相等的。OSD 同时还负责处理数据复制、数据恢复、数据再平衡以及通过心跳机制监测其它 OSD 状况并报告给 MON。对于任何 R/W 操作,客户端首先向 MON 请求集群的 Map,然后客户端就可以直接与 OSD 进行 I/O 操作。正是因为客户端能够直接与 OSD 进行操作而不需要额外的数据处理层,才使得 Ceph 的数据事务处理速度如此的快。

Ceph Metadata Server(MDS)[可选]

Ceph 元数据服务器服务进程,简称 MDS。只有在启用了 Ceph 文件存储(CephFS)的集群中才需要启用 MDS,它负责跟踪文件层次结构,存储和管理 CephFS 的元数据。MDS 的元数据也是以 Obejct 的形式存储在 OSD 上。除此之外,MDS 提供了一个带智能缓存层的共享型连续文件系统,可以大大减少 OSD 读写操作频率。

Ceph 的架构:核心组件

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Ceph RADOS(Reliable, Autonomic, Distributed Object Store)

可靠、自动、分布式对象存储系统,简称 Ceph 存储集群。Ceph 的所有优秀特性都是由 RADOS 提供的,包括分布式对象存储的数据一致性、高可用性、高可靠性、没有单点故障、向我修复以及自我管理等,Ceph 的数据访问方式(e.g. RBD, CephFS, RADOSGW 和 librados)都建立在 RADOS 之上。Cepb 中的一切都以对象的形式存储,而 RADOS 就负责存储这些对象。对于分布式存储的数据一致性,RADOS 通过执行数据复制、故障检测与恢复,还包括数据在集群节点间的迁移与再平衡来实现。

LIBRADOS

是一个 C 语言库,简称 Ceph 基础库。对 RADOS 的功能进行了抽象和封装,并提供北向 API。通过 librados,应用程序可以直接访问 RADOS 原生功能,以此来提高了应用程序的性能、可靠性和效率。因为 RADOS 本质是一个对象存储系统,所以 librados 提供的 API 都是面向对象存储的。librados 原生接口的优点是它直接与应用代码集成,操作非常方便,但也不会主动对上传的数据进行分片。

librados 支持具有异步通信能力的对象存储接口:

  • 存储池操作
  • 快照
  • 读、写对象
    • 创建/删除
    • 整个 Object 范围或字节范围
    • 追加或截断
  • 创建/设置/获取/删除 XATTRs
  • 创建/设置/获取/删除 K/V 对
  • 复合操作和双重 ACK 语义

Ceph Reliable Block Storage(RBD)

Ceph 块存储,简称 RBD,是基于 librados 之上的块存储服务接口。RBD 的驱动程序已经被集成到 Linux 内核(2.6.39 或更高版本)中,也已经被 QEMU/KVM Hypervisor 支持,它们都能够无缝地访问 Ceph 块设备。Linux 内核 RBD(KRBD)通过 librados 映射 Ceph 块设备,然后 RADOS 将 Ceph 块设备的数据对象以分布式的方式存储在集群节点中。

Ceph RADOS Gateway(RGW)

Ceph 对象网关,简称 RGW,是基于 librados 之上的对象存储服务接口。本质是一个代理,可以将 HTTP 请求转交给 RADOS,同时也可以把 RADOS 请求转换为 HTTP 请求,以此来提供 RESTful 对象存储服务接口,并兼容 S3 和 Swift。

在这里插入图片描述

Ceph File System(CephFS)

Ceph 文件系统,简称 CephFS。在 RADOS 层之上提供了一个任意大小且兼容 POSIX 的分布式文件系统。CephFS 依赖 MDS 来管理其元数据(文件层次结果),以此将元数据与原始数据分离,MDS 不直接向客户端提供数据,因此可以避免单点故障,有助于降低软件复杂性并提高可靠性。

在这里插入图片描述

Ceph 的架构:内部构件

在这里插入图片描述

Ceph Client

Ceph 的客户端是指使用 Ceph 存储服务的一切实体对象。可能是一个 Client 软件、一台主机/虚拟机或者是一个 App。客户端会根据 Ceph 提供的不同接口类型(服务接口、原生接口、C 库)来连接并 Ceph 存储服务器并使用相应的 Ceph 存储服务。
在这里插入图片描述

客户端的数据条带化(分片)

当用户使用 RBD、RGW、CephFS 类型客户端接口来储存数据时,会经历一个透明的、将数据转化为 RADOS 统一处理对象的过程,这个过程就称之为数据条带化或分片处理。

熟悉存储系统的你不会对条带化感到陌生,它是一种提升存储性能和吞吐能力的手段,通过将有序的数据分割成多个区段并分别储存到多个存储设备上,最常见的条带化就是 RAID0。而 Ceph 的条带化处理就类似于 RAID0,如果想发挥 Ceph 的并行 I/O 处理能力,就应该充分利用客户端的条带化功能。需要注意的是,librados 原生接口并不具有条带化功能,比如:使用 librados 接口上传 1G 的文件,那么落到存储磁盘上的就是 1G 大小的文件。存储集群中的 Objects 也同样不具备条带化功能,实际上是由上述三种类型的客户端将数据条带化之后再储存到集群 Objects 之中的。

条带化处理过程

  1. 将数据切分为条带单元块。
  2. 将条带单元块写入到 Object 中,直到 Object 达到最大容量(默认为 4 M)。
  3. 再为额外的条带单元块创建新的 Object 并继续写入数据。
  4. 循环上述步骤知道数据完全写入。

假设 Object 存储上限为 4M,每一个条带单元块占 1M。此时我们储存一个 8M 大小的文件,那么前 4M 就储存在 Object0 中,后 4M 就创建 Object1 来继续储存。
在这里插入图片描述
随着储存文件 Size 的增加,可以通过将客户端数据条带化分割储存到多个 Objects 中,同时由于 Object 映射到不同的 PG 上进而会映射到不同的 OSD 上,这样就能够充分利用每个 OSD 对应的物理磁盘设备的 IO 性能,以此实现每个并行的写操作都以最大化的速率进行。随着条带数的增加对写性能的提升也是相当可观的。如下图,数据被分割储存到两个 Object Set 中,条带单元块储存的顺序为 stripe unit 0~31。
在这里插入图片描述
Ceph 有 3 个重要参数会对条带化产生影响

  • order:表示 Object Size。例如:order=22 即为 2**22,即 4M 大小。Object 的大小应该足够大以便与条带单元块相匹配,而且 Object 的大小应该是条带单元块大小的倍数。RedHat 建议的 Object 大小是 16MB。
  • stripe_unit:表示条带单元块宽度。客户端将写入 Object 的数据切分为宽度相同的条带单元块(最后走一块的宽度未必一致)。条带宽度应该是 Object 大小的一个分数,比如:Object Size 为 4M,单元块为 1M,那么一个 Object 就能包含 4 个单元块。以便充分利用 Object 的空间。
  • stripe_count:表示条带数量。根据条带数量,客户端将一批条带单元块写入到 Object Set 中。

NOTE:由于客户端会指定单个 Pool 进行写入,所以条带化到 Objects 中的所有数据都会被映射在同一个 Pool 包含的 PGs 内。

客户端对 Object 的监视和通知

客户端可以向 Object 注册持久的监听,并保持与 Primary OSD 的会话,这就是客户端对 Object 的监视与通知性。该特性使得监听同一个 Object 的客户端之间可以使用 Object 来作为通信的渠道。

在这里插入图片描述

客户端的独占锁(exclusive-lock)

客户端的独占锁特性提供一种可以对 RBD 块设备进行 “排它性的” 锁定,这有助于解决多个客户端对同一个 RBD 块设备进行操作时,多个客户端尝试同时向同一个 Object 写入数据导致的冲突。独占锁特性需要依赖客户端对 Object 的监视与通知特性,在数据写入时,如果一个客户端首先在 Object 上放置了独占锁,则能够被其它客户端在写入数据前检查到,并放弃数据写入。设置了这一特性的话,同一时刻只有一个客户端能够对 RBD 块设备进行修改,常被应用到快照创建、快照删除这种改变块设备内部结构的操作。强制的独占锁功能特性默认是不开启的,需要在创建镜象时显式的通过选项 --image-features 启用。

rbd -p mypool create myimage --size 102400 --image-features 5
# 5 = 4 +1 
#   1:启用分层特性
#   4:启用独占锁特性

客户端的 Object 映射索引

客户端可以在数据写入到 RBD Image 时会跟踪这些 Object(建立映射索引),从而让客户端可以在数据读写时就能知道相应的 Objects 是否存在,省去了遍历 OSD 以确定 Objects 是否存在的开销。Object 的映射索引保存在 librbd 客户端的内存中。该特性对一些 RBD Image 操作比较有利:

  • 缩容:仅删除存在的尾部 Objects。
  • 导出操作:仅导出存在的 Objects。
  • 复制操作:仅存在的 Objects。
  • 扁平化:仅将存在的 Parent Objects 拷贝到 Clone Image。
  • 删除:仅删除存在的 Objects。
  • 读取:仅读取存在的 Objects。

Object 映射索引特性默认也是不开启的,同样需要在创建镜象时显式的通过选项 --image-features 启用。

rbd -p mypool create myimage –size 102400 –image-features 13
# 13 = 1 + 4 + 8
#   1:启用分层特性
#   4:启用独占锁特性
#   8:启用 Object 映射索引

CRUSH(Controlled Replication Under Scalable Hashing)

可控的、可扩展的、分布式的副本数据放置算法。本质是一种伪随机数据分布算法,类似一致性哈希,是 Ceph 的智能数据分发机制,管理着 PG 在整个 OSD 集群的分布。CRUSH 的目的很明确, 就是一个 PG 如何与 OSD 建立关系,它是 Ceph 皇冠上的宝石。

动态计算元数据

传统物理存储设备的存储机制都涉及存储原始数据及其元数据,元数据存储了原始数据存储在存储节点和磁盘阵列的地址信息。每一次有新数据写入存储系统时,元数据最先更新,更新的内容就是原始数据将会存放的物理地址,在此之后才是原始数据的写入。Ceph 则抛弃了这种存储机制,使用 CRUSH 算法动态计算用于存储 Object 的 PG,同时也用于计算出 PG 的 OSD Acting Set(Acting Set 即为活跃的 OSD 集合,集合中首编号的 OSD 即为 Primary OSD)。CRUSH 按需计算元数据,而不是存储元数据,所以 Ceph 消除了传统的元数据存储方法中的所有限制,具有更好的容量、高可用性和可扩展性。

基于 CRUSH bucke 的故障域/性能域划分

除此之外,CRUSH 还具有独特的基础设施感知能力,可以识别整个基础设施中的物理组件拓扑(故障域和性能域),包括磁盘、节点、机架(Rack)、行(Row)、开关 、电源电路、房间、数据中心以及存储介质类型等多种 CRUSH bucke 类型,bucket 表明了设备的具体物理位置。这种感知能力使得 CRUSH 可以让客户端进行跨故障域写入数据,以此来保证数据的安全性。CRUSH bucke 包含在 CRUSH Map 中,CRUSH Map 还保存了一系列可定义的规则(CRUSH Rules),告诉 CRUSH 如何为不同的 Pool 复制数据。CRUSH 使得 Ceph 能够自我管理和自我疗愈。当故障区域中的组件故障时,CRUSH 能够感知哪个组件故障了,并自动执行相应的数据迁移、恢复等动作。使用 CRUSH,我们能够设计一个没有单点故障的高度可靠的存储基础设施。CRUSH 也可使客户端能够将数据写入特定类型的存储介质中,例如:SSD、SATA。CRUSH Rules 决定了故障域以及性能域的范围。
在这里插入图片描述

Object

对象。是 Ceph 的最小存储单元,每个 Object 都包含了在集群范围内唯一的标识、二进制数据、以及由一组键值对组成的元数据。绑定在一起的原始数据与元数据,并且具有 RADOS 全局唯一的标识符 OID。无论上层应用的是 RBD、CephFS 还是 RADOSGW,最终都会以 Object 的方式存储在 OSD 上。当 RADOS 接收到来向客户端的数据写请求时,它将接收到的数据转换为 Object,然后 OSD 守护进程将数据写入 OSD 文件系统上的一个文件中。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Placement Group(PG)

归置组,简称 PG。PG 是一组 Objects 的逻辑集合。一个 Ceph 存储池可能会存储数百万或更多的数据对象。因为 Ceph 必须处理数据持久化(副本或纠删码数据块)、清理校验、复制、再平衡以及数据恢复,因此以 Object 作为管理对象就会出现扩展性和性能上的瓶颈。Ceph 通过引入 PG 层来解决这个问题。CRUSH 分配每个 Object 到指定的 PG 中,每个 PG 再映射到一组 OSD 中。PG 是保障 Ceph 可伸缩性和性能必不可少的部分。当数据要写入 Ceph 时,首先会将将数据分解成一组 Objects,然后根据 Object 名称、复制级别和系统中的总 PG 数等信息执行散列操作并生成 PG ID,最后依据 PG ID 将 Objects 数据分散到各个 PG 中。没有 PG,在成千上万个 OSD 上管理和跟踪数以百万计的 Objects 的复制和传播是相当困难的。将包含大量 Objects 的 PG 作为管理和复制的对象,可以有效缩减计算资源的损耗。每个 PG 都会消耗一定的计算资源(CPU、RAM),所以存储管理员应该精心计算集群中的 PG 数量。

计算 PG 数

上文中我们提到过,PG 数会在一定程度上影响存储性能,一个 OSD 的 PG 数可以被动态修改,但建议在部署规划时期就能够对 PG 数有一定的把握。常见的,有以下几种 PG 数计算方式:

  • 计算集群 PG 总数
PG 总数 = (OSD 总数 x 100) / 最大副本数
  • 1

结果取最接近 2 的 N 次幂,比如:集群有 160 个 OSD 且副本数为 3,那么根据公式计算得到的 PG 总数是 5333.3,再舍入这个值到最接近的 2 的 N 次幕,最终结果为 8192 个 PG。

  • 计算 Pool 下属的 PG 总数
PG 总数= ((OSD 总数 x 100) / 最大副本数) / 池数
  • 1

结果同样取最接近 2 的 N 次幂。

PG 与 PGP

PG - Placement Group
PGP - Placement Group for Placement purpose
pg_num - number of placement groups mapped to an OSD
When pgnum 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 pgpnum 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.

顾名思义,PGP 是为了实现定位而设置的 PG。PGP 的数量应该与 PG 总数保持一致。对于一个 Pool 而言,当你增加了 PG 的数量,这个 Pool 的 PG 同时还应该修改 PGP 的数量,让两者保持一致,这样集群才能够触发再平衡动作。

  • pg_num 的增加会使旧 PGs 中的 Objects 再平衡到新建 PG 中,旧 PGs 之间不会发现 Object 迁移并且依旧保存原有的 OSD 映射关系。
  • pgp_num 的增加会使新 PGs 在平衡到 OSDs 中,而旧 PGs 依旧保存原有的 OSD 映射关系。
  • PGP 决定了 PG 的分布。

PG Peering 操作、Acting Set 与 Up Set

OSD 守护进程会为每个 PG 的副本执行 Peering 操作,确保 PG 对应的主从 OSDs 之间的 PG 副本是一致的。这些主从 OSDs 以 Acting Set 的形式组织起来,Acting Set 的第一个元素就是 Primary OSD,保存着 PG 的主副本。其余为 Replica OSDs 中保存的是 PG 的第二/第三副本(假设副本数为 3)。Primary OSD 负责 Replica OSDs 之间的 PG 的 Peering 操作。当 Primary OSD 状态为 down 时,首先会从 Up Set 中移除,然后由第二 OSD 晋升为 Primary OSD,故障 OSD 中的 PG 会以同步到其他 OSD 的方式还原,并将新的 OSD 加入到 Actin Set 和 Up Set 中,以确保整个集群的高可用性。
在这里插入图片描述

Pool

存储池。是一个面向管理员的、用来隔离 PGs 和 Objects 的逻辑分区。简单来说,Pool 就是一个管理员自定义的命名空间,不同的 Pool 可以具有完全不同的数据处理方式,例如:Replica Szie(副本数)、PG Num、CRUSH Rules、快照、所属者及其授权等。可以为特定类型的数据创建存储池,比如:块设备、对象网关,亦或仅仅是为了多用户隔离而创建 Pool。

管理员可以为 Pool 设置所有者和访问权限,还支持快照功能。当用户通过 API 来存储数据时,需要指定 Objects 要存储到哪一个 Pool 中。管理员可以对不同的 Pool 设置相关的优化策略,比如 PG 副本数、数据清洗次数、数据块及 Object 的 Size 等等。Pool 提供了一个有组织的存储管理方式。每个 Pool 都会交叉分布在集群节点的 OSDs 上,这样能够提供足够的弹性。除了 PG 副本数,也可以通过指定纠删码的规则集来提供与副本数同等级别的可靠性,而且只消耗更少的空间。

当把数据写人到一个 Pool 时,首先会在 CRUSH Map 找到与 Pool 对应的规则集,这个规则集描述了 Pool 的副本数信息。在部署 Ceph 集群时会创建一些默认的存储池(e.g. data、metadata、rbd)。

Pool 也存在容量的概念,但 Pool Size 只在限制最大容量或者 QoS 的场景中有用,并不是真实的容量,因为 Pools 与 OSDs 之间的隐射是交叉的,Pools 的总容量大于 Ceph Cluster GLOBAL Size。所以 Pools 的总容量是没有意义的。

在这里插入图片描述

Ceph 的设计思想

在这里插入图片描述
在这里插入图片描述
此处不妨小结一下 Ceph 每个内部构件的设计含义及其存在的意义。以 Object 作为 Ceph 的最小存储单元充分地展示了 Ceph 宏大的野心 —— 要成为新一代(或者成为云时代)的存储架构。众所周知,元数据是关于原始数据的信息,它决定了原始数据将往哪里存储,从哪里读取。传统的存储系统通过维护一张集中式的查找表来跟踪它们的元数据,这直接导致了传统存储系统查找性能低(容量有限)、单点故障(可靠性低)、数据一致性(可扩展性低)等问题。为了实现这一目标,Ceph 就必须打破传统存储系统的桎梏,采用更加智能的元数据管理方法,以离散的方式来存储原始数据及其元数据,再以动态计算的方式来定位数据的所在,这就是 Object + CRUSH。在此基础之上,RADOS 的引入就是为了解决分布式运行环境中的数据一致性、高可用性和自我管理等问题;PG 的引入就是为了缩小 RADOS 的管理对象以及 Objects 的遍历寻址空间,进一步提升性能和降低内部实现复杂度,在进行数据迁移时,也是以 PG 作为迁移单位。有了 PG 之后 Ceph 会尽量避免直接操作 Objects;Pool 的引入就是为了抽象出更加友好的资源管理与操作模型,例如:PG 的数量以及 PG 的副本数都是以 Pool 为单位设定的,提供了良好的用户操作体验。在如此可靠、自动、分布式的对象存储系统之上再构建 librados、RBD、RGW、CephFS 等多种更便于应用或客户端使用的上层接口类型,真正实现了下层抽象统一、上层异构兼容的统一存储解决方案。回头再看,Ceph 成功的原因很简单,其 SDS(软件定义存储)基因所带来的 “可编程性” 不正是云时代所渴望的吗?

Ceph 的数据读写原理

数据储存的三个映射过程

在这里插入图片描述
Ceph 存储系统中,数据存储分三个映射过程:

Step 1. 将要存储的 File 数据映射(切分)为 RADOS 可以处理的 Objects(1:N)(ino, ono) -> oid

  • ino:File 的元数据,File 的唯一标识
  • ono:File 切分产生的某个 Object 时的分片编号,默认以 4M 大小切分
  • oid:Object 唯一标识,存储了 Obejcts 与 File 的从属关系

Step 2. 将 Objects 映射到 PG(N:1)hash(oid) & mask -> pgid,Ceph 指定一个静态 HASH 函数将 oid 映射成一个近似均匀分布的伪随机值,然后将这个值与 mask 按位相与,得到 PG ID。

  • mask:PG 总数 m - 1,m 为 2 的整数幂

Step 3. 将 PG 隐射到 OSDs(N:M)CRUSH(pgid) -> (osd1,osd2,osd3),传入 pgid 到 CRUSH 算法计算得到一组 OSD 数组(长度与 PG 副本数相同)。

File 数据最终分散保存在这些 OSDs 中。

调度算法的伪代码

locator = object_name
obj_hash =  hash(locator)
pg = obj_hash % num_pg
osds_for_pg = crush(pg)    # returns a list of osds
primary = osds_for_pg[0]
replicas = osds_for_pg[1:]
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

客户端的 I/O 定位

当客户端读写数据时,首先需要与 MON 节点建立连接并下载最新的 Cluster Map。客户端读取 Cluster Map 中的 CRUSH Map(包含 CRUSH Rules、CRUSH bucke)和 OSD Map(包含所有 Pool 的状态和所有 OSDs 的状态),Crush Rules 就是数据映射的策略,决定了每个 Object 有多少个副本,这些副本应该如何存储,当把数据写入一个 Pool 时,可以通过 Pool name 匹配到一个 CRUSH Rules。客户端通过这些信息在本地执行 CRUSH 算法获得数据读写的 Primary OSD 的 IP:Port,然后就可以与 OSD 节点直接建立连接来传输数据了。CRUSH 动态计算的动作发生在客户端,不需要有集中式的主节点用于寻址。客户端分摊了这部分工作,进一步减轻了服务端的工作负载。
在这里插入图片描述
在这里插入图片描述

  1. 客户端输入 Pool name 以及 Object ID(例如:Pool=“pool1”, Object=”obj1”)。
  2. CRUSH 获取 Object ID 后对其进行 HASH 编码。
  3. CRUSH 根据上一步的 HASH 编码与 PG 总数求模后得到 PG ID。(e.g. HASH 编码后为 186,而 PG 总数为 128,则求模得 58,所以这个 Object 会存储在 PG_58 中)。
  4. CRUSH 计算对应 PG ID 的主 OSD。
  5. 客户端根据 Pool name 称得到 Pool ID(e.g. pool1=4)。
  6. 客户端将 PG ID 与 Pool ID拼接(e.g. 4.58)
  7. 客户端直接与 Activtin Set 集合中的主 OSD 通信,来执行对象的 IO 操作。

主从 OSD 的副本 I/O

首先我们需要了解到 Ceph 的读写操作采用了主从模型,当客户端读写数据时,都只能向 Object 对应的 Primary OSD 发起请求。同时 Ceph 还是一个 强一致性 分布式存储,也就是说保证分布式数据的一致性同步过程并非异步操作。只有当所有的主从 OSD 都写入数据之后才算是一次成功的写入。客户端使用 CRUSH 算法计算 Object 映射的 PG ID 以及 Acting Set 列表。Acting Set 的首元素就是 Primary OSD,剩下的为 Replica OSD。
在这里插入图片描述

提升性能的日志 I/O

强一致性的数据同步方式在带来了高度的数据一致性的同时也存在一些缺点,比如:写性能低。为了提高写性能,Ceph 采用了一种普遍的应对方式 —— 日志缓存的机制。

当有突发的写入峰值时,Ceph 会先把一些零散的、随机的 IO 请求保存到缓存中进行合并,然后再统一向内核发起 IO 请求。这种方式有效提升了执行效率,但一旦 OSD 节点崩溃,缓存中的数据也会随之丢失。所以,Ceph OSD 包含两个不同的部分:OSD 日志部分(journal 文件)和 OSD 数据部分。每一个写操作都包含两个步骤:首先将 Object 写入日志部分,然后再将同一个 Object 从日志部分写人数据部分。当 OSD 崩溃后重新启动时,会自动尝试从 journal 恢复因崩溃而丢失的缓存数据。因此,journal 的 IO 是非常密集的,而且由于一个数据要 IO 两次,很大程度上也损耗了硬件的性能。从性能的角度来看,在生产环节中建以使用 SSD 存储来日志。使用 SSD 可以通过减少访问时间和读取延迟实现吞吐量的显著提升。

如果使用 SSD 来存储日志,我们可以在每一个物理 SSD 磁盘上创建一个逻辑分区来作为日志分区,这样每个 SSD 的日志分区就可以映射到一个 OSD 的数据分区,journal 文件的大小默认为 5G。在这种部署方案中,切记不要在同一个 SSD 上存储过多的日志以避免超出它的上限而影响到整体性能。建议在每一个 SSD 磁盘上不应该存储超过 4 个 OSD 的日志。但需要注意的是,使用单一 SSD 磁盘来存储多个日志的另一个坏处是容易发生单点故障,所以也建议使用 RAID1 来避免这种情况。

数据写入 OSD 的 UML 流程

在这里插入图片描述

  1. Client 创建 Cluster Handler。
  2. Client 读取配置文件。
  3. Client 连接上 MON,获取 Cluster Map 的副本。
  4. 根据 CRUSH Map 记录的故障域以及数据分发规则信息,找到 Client 读写 I/O 的目的 Primary OSD(主 OSD)。
  5. 根据 OSD Map 记录的 Pool 副本数(这里假设副本数为 3),首先将数据写入 Primary OSD。Primary OSD 再复制相同的数据到两个 Replica OSD 中,并等待它们确认写入完成。
  6. Replica OSD 完成数据写人,它们就会发送一个应答信号给 Primary OSD。
  7. 最后,Primary OSD 再返问一个应答信号给客户端,以确认完成整个写人操作 。

数据写入新 Primary OSD 的 UML 流程

在这里插入图片描述

  1. Client 连接 MON,获取 Cluster Map 的副本。
  2. 新 Primary OSD 由于不存在任何 PG,所以主动上报 MON 暂时由 Primary OSD 2 升级为临时 Primary OSD。
  3. 临时 Primary OSD 把 PG 全量同步给新 Primary OSD。
  4. Client I/O 直接连接临时 Primary OSD。
  5. 临时 Primary OSD 接收到数据后同时复制另外两个 OSD,并等待它们确认写入完成。
  6. 三个 OSD 都同步写入数据后返问一个应答信号给客户端,以确认完成整个写人操作 。
  7. 如果临时 Primary OSD 与新 Primary OSD 的全量数据完成,则临时 Primary OSD 再次降级为 Replica OSD。

Ceph 的自管理

OSD 的心跳机制

心跳机制是最常见的故障检测机制,Ceph 使用心跳机制来检测 OSD 是否正常运行,以便及时发现故障节点并进入相应的故障处理流程。OSD 的状态(Up/Down)反映了其健康与否,OSD 加入到集群后会定期的上报心跳到 MON,但假如 OSD 已然故障的话就不会在继续上报自己为 Down 的状态了,所以具有关联关系的 OSDs 之间也会互相评判对方的状态,如果发现对方 Down 掉了,则会协助上报到 MON。当然了,MON 也会定期的 Ping 这些 OSD 以此来确定它们的运行情况。Ceph 通过伙伴 OSD 汇报失效节点以及 MON 统计来自 OSD 的心跳检测两种方式判定 OSD 节点是否失效。

OSD 服务进程会监听 Public、Cluster、Front 和 Back 四个端口

  • Public 端口:监听来自 MON 和 Client 的连接。
  • Cluster 端口:监听来自 OSD Peer 的连接。
  • Front 端口:监听供客户端连接到集群所使用的网卡。
  • Back 端口:监听供集群内部使用的网卡。

在这里插入图片描述

OSD 心跳机制的特征

  • 及时:伙伴 OSD 可以在秒级发现失效节点汇报至 MON,并在几分钟内由 MON 将失效 OSD 下线。
  • 适当的压力:由于有伙伴 OSD 协同汇报,MON 与 OSD 之间的心跳检测更像是一种保险措施,因此 OSD 向 MON 发送心跳的间隔可以长达 600 秒,MON 的检测阈值也可以长达 900 秒。Ceph 将故障检测过程中中心节点的压力分散到所有的 OSD 上,以此提高了中心节点 MON 的可靠性,进而提高整个集群的可扩展性。
  • 容忍网络抖动:MON 收到 OSD 对其伙伴 OSD 的汇报后,并没有马上将目标 OSD 下线,而是周期性的等待一下几个条件:
    • 目标 OSD 的失效时间大于通过固定量 osd_heartbeat_grace 和历史网络条件动态确定的阈值。
    • 来自不同主机的汇报达到 mon_osd_min_down_reporters。
    • 满足前两个条件前失效汇报没有被源 OSD 取消。
  • 扩散:作为中心节点的 MON 并没有在更新 OSD Map 后尝试广播通知所有的 OSD 和 Client,而是惰性的等待 OSD 和 Client 来获取。以此来减少 MON 的压力并简化交互逻辑。

OSD 之间相互的心跳检测

在这里插入图片描述

  • 同一个 PG 内 OSDs 之间互相发送 PING/PONG 信息。
  • 每隔 6s 检测一次。
  • 20s 没有检测到心跳回复,将对方加入 Failure 队列。

OSD 与 MON 间的心跳机制

在这里插入图片描述

OSD 扩容时的 PG 迁移与再平衡

将一个新的 OSD 添加到 Ceph 集群时,Cluster Map 也会更新,这一变化会改变 CRUSH 计算时输入的参数,也就间接的改变了 Object 放置的位置。CRUSH 算法是伪随机的,但会均匀的放置数据,所以 CRUSH 会开始执行再平衡操作,并且会让尽量少的数据发生迁移。一般迁移的数据量是集群总数据量与 OSD 数量的比值,例如:在有 50 个 OSD 的集群中,当新增加一个 OSD 时,就只会有 1/50(2%)的数据会被迁移。并且所有旧 OSD 会并行地移动数据,使其能够迅速的完成。在生产环境中对于利用率高(刷写量大速快)的 Ceph 集群,建议先将新的 OSD 权重设为 0,再逐渐增加权重。通过这种方式,能够减少再平衡操作对 Ceph 集群性能有较大的影响。再平衡机制保证了所有磁盘能能够被均匀的使用,以此提升集群性能和保持集群健康。

扩容前
在这里插入图片描述
扩容后
在这里插入图片描述
上图可见,虚线的 PGs 会自动迁移到新的 OSD 上。

数据擦除(Clean)

数据擦除是 Ceph 维护数据一致性以及整洁性的手段。OSD 守护进程会完成 PG 内的 Object 清理工作,它会比较副本间 PGs 内的 Object 元数据信息,捕获异常或文件系统的一些错误,这类 Clean 是 Day 级别的调度策略。OSD 还只会更深层次的比较,对数据本身进行按位比较,这种深层次的比较可以发现驱动盘上坏的扇区,一般是 Week 级别的调度策略。

 

 

你可能感兴趣的:(ceph)