Ceph分布式存储系列(一):Ceph工作原理及架构浅析梳理

一、Ceph简介
    众所周知,ceph是一种分布式存储系统,是有着“ceph之父”之称的Sage Weil读博期间的研究课题,项目诞生于2004年,在2006年基于开源协议开源了Ceph的源代码,在经过了数年的发展之后,已经成为了开源社区受关注较高的项目之一。
    Ceph可以将多台服务器组成一个超大集群,把这些机器中的磁盘资源整合到一块儿,形成一个大的资源池(支持PB级别),然后按需分配给客户端应用使用。
ceph官网:https://ceph.com/
ceph官方文档:https://docs.ceph.com/

Ceph特点:
支持三种 对象存储,块存储,文件存储 接口,称之为统一存储
采用CRUSH算法,数据分布均衡,并行度高,不需要维护固定的元数据结构
数据具有强一致性,确保所有副本写入完成后才返回确认,适合读多写少的场景
去中心化,没有固定的中心节点,集群扩展灵活
一些缺点:
去中心化的分布式解决方案,需要提前做好组件和节点部署规划设计
ceph扩容时,由于其数据分布均衡的特性,会导致整个存储系统性能下降
Ceph相较于其他存储方案的优势
CRUSH算法:
    a. CURSH是ceph的两大创新之一(另一大就是去中心化),ceph摒弃了传统的集中式存储元数据寻址的方案,转而使用CRUSH算法计算的方式完成数据的寻址操作;
    b. crush算法有强大的扩展性(即高扩展性),理论上支持上千个存储节点规模。

高可用:
    a. 数据副本数可以灵活调整;
    b. 可以通过crush算法指定副本的物理存放位置以分割故障域,支持数据强一致性;
    c. 支持多种故障场景自动尝试进行修复;
    d. 支持多份强一致性副本,副本能够垮主机、机架、机房、数据中心存放,安全可靠;
    e. 存储节点可以自管理、自动修复。无单点故障,容错性强

高性能:
    a. 因为是多个副本,因此在读写操作时能够做到高度并行化,理论上,节点越多,整个cpeh集群的IOPS和吞吐量就越高;
    b. ceph客户端读写数据可直接与存储设备-OSD交互,在块存储和对象存储中无需元数据-MDS服务

特性丰富
    a. 支持三种存储接口:对象存储,块存储,文件存储,三种方式可一同使用
    b. 支持自定义接口,支持多种语言驱动

二、Ceph架构简介
官方原架构图

简略图


绘制简图原图请看https://www.processon.com/view/link/5f855d831e085307a08807fc
官方原架构图请看https://docs.ceph.com/en/latest/architecture/

由上图所示,自下往上,逻辑上可以分为四个层次:

基础存储系统RADOS(Reliable Autonomic Object Store,可靠、自动、分布式对象存储):
    RADOS是ceph存储集群的基础,这一层本身就是一个完整的对象存储系统。Ceph的高可靠、高可扩展、高性能、高自动化等等特性本质上也都是由这一层所提供的,在ceph中,所有数据都以对象的形式存储,并且无论什么数据类型,RADOS对象存储都将负责保存这些对象,确保了数据一致性和可靠性。RADOS系统主要由两部分组成,分别是OSD和Monitor。

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

上层接口RADOSGW、RBD和CEPHFS
基于LIBRADOS层开发的三个接口,其作用是在librados库的基础上提供抽象层次更高、更便于应用或客户端使用的上层接口。

RADOS GW(简称RGW)提供对象存储服务,是一套基于RESTFUL协议的网关,支持对象存储,兼容S3和Swift
RBD提供分布式的块存储设备接口,主要面向虚拟机提供虚拟磁盘,可以被映射、格式化,像磁盘一样挂载到服务器使用。
CephFS是一个POSIX兼容的分布式文件系统,依赖MDS来跟踪文件层次结构,基于librados封装原生接口,它跟传统的文件系统如 Ext4 是一个类型的,但区别在于分布式存储提供了并行化的能力,像NFS等也是属于文件系统存储。
PS:两个对象的区分,需要说明下,这里提到两个对象的概念:
一个是RGW中的对象存储;一个是Ceph 的后端存储的对象,这两个需要区分:
第一个对象面向用户,是用户接口能访问到的对象;
第二个对象是ceph 服务端操作的对象
eg:使用RGW接口,存放一个1G的文件,在用户接口看到的就是存放了一个对象(1);而后通过RGW 分片成多个对象(2)后最终存储到磁盘上;

三、Ceph核心组件简介
OSD(ceph-osd):
object storage daemon,用于集群中所有数据与对象的存储。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节点。

Monitor(ceph-mon):
    维护集群Cluster Map的状态,维护集群的Cluster MAP二进制表,保证集群数据的一致性。Cluster MAP描述了对象块存储的物理位置,以及一个将设备聚合到物理位置的桶列表,map中包含monitor组件信息,manger 组件信息,osd 组件信息,mds 组件信息,crush 算法信息。还负责ceph集群的身份验证功能,client 在连接ceph集群时通过此组件进行验证。

注意事项
1、通常一个节点有多个OSD守护进程和多个磁盘,所以通常来说OSD不是一个节点。
2、Ceph要求必须是奇数个Monitor监控节点,一般建议至少是3个(如果是自己私下测试,可以是1个,但是生产环境绝不建议1个)用于维护和监控整个集群的状态,至少三个mon才能实现冗余和高可用性,每个Monitor都有一个Cluster Map,只要有这个Map,就能够清楚知道每个对象存储在什么位置了。客户端会先tcp连接到Monitor,从中获取Cluster Map,并在客户端进行计算,当知道对象的位置后,再直接与OSD通信(去中心化的思想)。OSD节点平常会向Monitor节点发送简单心跳,只有当添加、删除或者出现异常状况时,才会自动上报信息给Monitor。
3、在Ceph中,如果要写数据,只能向主OSD写,然后再由主OSD向从OSD同步地写,只有当从OSD返回结果给主OSD后,主OSD才会向客户端报告写入完成的消息。如果要读数据,不会使用读写分离,而是也需要先向主OSD发请求,以保证数据的强一致性。
4、在Ceph中,以OSD权重作为主次OSD节点的选择的唯一标准,而权重又以对应硬盘剩余存储容量作为唯一决定因素,所以意味着剩余存储容量是数据分布和读写操作中选择主次OSDd唯一决定因素。

四、RADOS的系统逻辑结构
    RADOS (Reliable, Autonomic Distributed Object Store) 是Ceph的核心之一,作为Ceph分布式文件系统的一个子项目,特别为Ceph的需求设计,能够在动态变化和异质结构的存储设备机群之上提供一种稳定、可扩展、高性能的单一逻辑对象(Object)存储接口和能够实现节点的自适应和自管理的存储系统。 在传统分布式存储架构中,存储节点往往仅作为被动查询对象来使用,随着存储规模的增加,数据一致性的管理会出现很多问题。而新型的存储架构倾向于将基本的块分配决策和安全保证等操作交给存储节点来做,然后通过提倡客户端和存储节点直接交互来简化数据布局并减小io瓶颈。


设计图来源于ceph官方RADOS文档:https://ceph.com/wp-content/uploads/2016/08/weil-rados-pdsw07.pdf

    服务端 RADOS 集群主要由两种节点组成:一种是为数众多的、负责完成数据存储和维护功能的OSD(Object Storage Device);另一种则是若干个负责完成系统状态检测和维护的monitor,monitor是一些独立的进程,以及少量的本地存储,monitor之间通过一致性算法保证数据的一致性。

Cluster Map使用
    集群通过monitor集群操作cluster map来实现集群成员的管理。cluster map 描述了哪些OSD被包含进存储集群以及所有数据在存储集群中的分布。cluster map不仅存储在monitor节点,它被复制到集群中的每一个存储节点,以及和集群交互的client。当因为一些原因,比如设备崩溃、数据迁移等,cluster map的内容需要改变时,cluster map的版本号被增加,map的版本号可以使通信的双方确认自己的map是否是最新的,版本旧的一方会先将map更新成对方的map,然后才会进行后续操作。

    而RADOS也通过 cluster map来实现这些存储半自动化的功能,cluster map会被复制到集群中的所有部分(存储节点、控制节点,甚至是客户端),并且通过怠惰地传播小增量更新而更新。Cluster map中存储了整个集群的数据的分布以及成员。通过在每个存储节点存储完整的Cluster map,存储设备可以表现的半自动化,通过peer-to-peer的方式(比如定义协议)来进行数据备份、更新,错误检测、数据迁移等等操作。这无疑减轻了占少数的monitor cluster(管理节点组成的集群)的负担。

五、ceph底层存储过程(Data Placement)
    无论使用哪种存储方式(对象,块,文件),存储的数据当底层保存时,都会被切分成一个个大小固定的对象(Objects),对象大小可以由管理员自定义调整,RADOS中基本的存储单位就是Objects,一般为2MB或4MB(最后一个对象大小有可能不同)。


    如上图,一个个文件(File)被切割成大小固定的Objects后,将这些对象分配到一个PG(Placement Group)中,然后PG会通过多副本的方式复制几份,随机分派给不同的存储节点(也可指定)。

    当新的存储节点(OSD)被加入集群后,会在已有数据中随机抽取一部分数据迁移到新节点,这种概率平衡的分布方式可以保证设备在潜在的高负载下正常工作,更重要的事,数据的分布过程仅需要做几次随机映射,不需要大型的集中式分配表,方便且快速,不会对集群产生大的影响。

逻辑概念说明:
上图两侧逻辑概念词的含义:

File:用户需要存储或者访问的文件
Objects:RADOS的基本存储单元,即对象。 Object与上面提到的file的区别是,object的最大size由RADOS限定(通常为2MB或4MB),以便实现底层存储的组织管理。以便实现底层存储的组织管理。因此,当上层应用向RADOS存入size很大的file时,需要将file切分成统一大小的一系列object进行存储。
PG(Placement Group):英文直译过来即为放置组,所以这里PG作用是对object的存储进行组织和位置映射,它是一个逻辑概念,在Linux系统中可以直接看到对象,但是无法直接看到PG,它在数据寻址中类似于数据库中的索引。用来放置若干个object(可以数千个甚至更多),但一个object只能被映射到一个PG中,即,PG和object之间是“一对多”的映射关系。同时,一个PG会被映射到n个OSD上,而每个OSD上都会承载大量的PG,即,PG和OSD之间是“多对多”映射关系。在实践当中,n至少为2(n代表冗余的份数),如果用于生产环境,则至少为3。一个OSD上的PG则可达到数百个。
OSD(object storage device):前文已详细说明,不再赘述,不过osd数量关系到系统的数据分布均匀性和性能问题,所以也不能太少。
oid 每个object都会有一个唯一的OID,由ino和ono生成。ino即文件的File ID,用于在全局唯一标识每一个文件,ono则是分片编号(对象编号)。例如:一个文件FileID为A,被切割为对象编号是A0,A1的两个对象。
pgid 使用静态hash函数对OID做hash去除特征码,用特征码与PG的数量去模,得到的序号即是PGID,由于这种设计方式,所以PG数量的多少会直接决定了数据分布的均匀性,所以需要合理设置PG的数量可以很好的提升CEPH集群的性能并使数据均匀分布。
存储过程中各层次之间的映射关系:
file -> object
object的最大size是由RADOS配置的,当用户要存储一个file,需要将file切分成若干个object。
object -> PG
每个object都会被映射到一个PG中,然后以PG为单位进行副本备份以及进一步映射到具体的OSD上。
PG -> OSD
通过CRUSH算法来实现,根据用户设置的冗余存储的个数r,PG会最终存储到r个OSD上。
存储过程具体说明:
    用户通过客户端存储一个文件时,在RAODS中,该File(文件)会被分割为多个2MB/4MB大小的 Objects(对象)。而每个文件都会有一个文件ID,例如A,那么这些对象的ID就是A0,A1,A2等等。然而在分布式存储系统中,有成千上万个对象,只是遍历就要花很久时间,所以对象会先通过hash-取模运算,存放到一个PG中。

    PG相当于数据库的索引(PG的数量是固定的,不会随着OSD的增加或者删除而改变),这样只需要首先定位到PG位置,然后在PG中查询对象即可。之后PG中的对象又会根据设置的副本数量进行复制,并根据CRUSH算法存储到OSD节点上。

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

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

PG数量设置多少才合适?
    根据以上所述,我们知道了pg数量的多少,会影响到集群的存储分布,以及集群存储的性能,那到底该如何规划pg数呢?我们首先来简单了解下PG-Pool的概念

Pool: 是ceph存储数据时的逻辑分区,它起到namespace的作用。每个pool包含一定数量(可配置) 的PG。PG里的对象被映射到不同的Object上。pool是分布到整个集群的。 pool可以做故障隔离域,根据不同的用户场景不统一进行隔离。
支持两种类型:副本(replicated)和 纠删码( Erasure Code)

副本(replicated):即复制,例如三副本,即为该Pool内的PG会复制三份
纠删码(Erasure Code):是一种编码容错技术,其基本原理就是把传输的信号分段,加入一定的校验再让各段间发生相互关联,即使在传输过程中丢失部分信号,接收端仍然能通过算法将完整的信息计算出来。在数据存储中,纠删码将数据分割成片段,把冗余数据块扩展和编码,并将其存储在不同的位置,比如磁盘、存储节点或者其他地理位置。用更少的空间实现存储,即节约空间
pg 跟 pool 关联,一个pool有多少个pg,跟osd数相关
Ceph官方给的计算方式为:https://ceph.com/pgcalc/
根据以下的官方介绍,结合自身集群的规模大小(OSD多少)去计算合理的PG数

例如,上图,
    使用3副本模式;OSD编号为5,即集群中5个OSD(硬盘);数据存储使用量为80%;在可以预见的未来,集群OSD数量不会增加
根据官方计算出:
5 个 osd时,设置128个pg
10个 osd 时,设置256个pg。
100个 osd 时,设置2048个pg。

注: 一旦设置pg和pgp数量,最好就不需要再调整,否则会引发数据的大量迁移。如果一定要调整,请确保调整前,集群是ok状态;
严格意义上来说,我们无论为池分配多少个 pg 都没有问题。但有时候 pg_num 配置小了集群状态会报错,配置大了也会报错。这不是因为这么配置不对,是因为有其它的参数在限制我们随意配置 pg_num。

和PG密切相关的PGP是什么?
    这里需要特别说明的是和PG相关的一个概念为PGP,我理解来PGP是用来放置PG使用的,PGP中包含了PG,Pool池中有多少个PG,就又多少个PGP,所以集群设置PG数量时,PGP也是同样的大小。
应该可以简单粗暴的如下图去理解
详细点来说:
pg_num(pg的数量): pg_num增加时,会导致原来各PG中的对象均匀的分布到新建PG中,但是原PG的实际物理存储位置不会发生变化,只是会影响这些PG所在的同一个Pool池中的object分布

pgp_num(pgp的数量): pgp_num增加时,因为PG是存在于PGP中,所以会导致PG的分布方式发生变化,但是PG内的对象并不会变动,只是会导致一些PG的实际物理存储位置发生变化。

六、Ceph日常操作命令:
#查看状态命令:

查看ceph集群整体状态:ceph -s

查看ceph集群健康状态:ceph health detail

查看mon状态:ceph mon stat

查看mds状态:ceph mds stat

查看pg状态:ceph pg stat

查看osd状态:ceph osd stat

查看osd目录树(可以查看到每个osd挂载在哪个服务器上,up或者down状态):ceph osd tree

#启动ceph进程命令:
(在运行对应组件服务的节点上操作)

启动mon进程:systemctl start ceph-mon.target

启动mds进程:systemctl start ceph-mds.target

启动mgr进程:systemctl start ceph-mgr.target

启动osd进程:systemctl start ceph-osd.target

启动单个osd节点:systemctl start [email protected](第263个osd)

查看ceph的实时运行状态:ceph -w

查看ceph集群的存储空间:ceph df

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
End……
————————————————
版权声明:本文为CSDN博主「Echo&.」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_43860781/article/details/109053152

你可能感兴趣的:(存储,分布式,架构,java)