Ceph分布式文件系统

时间:2021-01-13 12:35:45

  2003年加州大学Santa Cruz分校的Sage Weil专为博士论文设计的新一代*软件分布式文件系统,并于20124月,Sage Weil成立了Inktank公司

20103月之后的linux内核中,嵌入了ceph

2014430日,RedHat$175million的价格收购了Inktank

 

在目前开源世界里多样的存储项目中,不同的项目都有侧重点,而它们最终都是要为企业的IT基础设施服务。那么企业IT基础设施经理们到底需要怎么样的存储,它们的需求得到满足了吗?

Ceph分布式文件系统 

 

从上图我们可以了解到存储接口需求、扩展、运维和成本构成了企业级存储产品的四大中心。几乎所有的存储产品包括硬件(存储一体机,SAN)和软件都致力于在这个方面强调自己的优势,它们或者考虑成本,或者强调扩展性。那么我们来看Ceph它是如何定位自己的。

Ceph分布式文件系统 

1. 架构

Ceph是统一存储系统,支持三种接口:

Object:有原生的API,而且也兼容SwiftS3API

Block:支持精简配置、快照、克隆

FilePosix接口,支持快照

 

Ceph也是分布式存储系统,它的特点如下:

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

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

高性能:数据分布均衡,并行化高,对于objects storageblock storage,不需要元数据服务器

 

Ceph模块架构图:

 

Ceph分布式文件系统

 

底层是Rados,也是Ceph实现分布式存储的根本,所有存储接口都是基于Rados实现的。Rados本身就是一个对象存储接口,它自身维护了一个集群状态和实现了数据分发的要求,我们通常也讲Rados称为Ceph Cluster,因为其上的存储接口如CephFS都是基于其上的接口实现而已

 

RADOS的组件(A reliable, autonomous, distributed object storage):

OSD: 每一个diskSSD或者RAID group或者其他一个物理存储设备都成为一个OSD,主要负责存储和查找对象,并且负责向该对象的复制节点分发和恢复。

Monitor: 维护集群的成员和状态,维护整个ceph集群的全局状态。提供强一致性的决策(类似于Zookeeper的作用)

 

RADOS具有很强的扩展性和可编程性,Ceph基于RADOS开发了Object StorageBlock StorageFileSystemCeph另外两个组件是:

MDS:用于保存CephFS的元数据。

RADOS Gateway:对外提供REST接口,兼容S3SwiftAPI

 

   在传统架构中,客户谈论到一个集中的组件(如网关,代理,API等),作为单点进入到一个复杂的子系统。这会带来性能和可扩展性的限制,同时引入单点故障(即,如果集中的组件出现故障,整个系统也出现故障)。
      Ceph的消除了集中式网关,使客户能够直接与CephOSD守护进程进行互动。CephOSD守护进程创建对象的副本,在其他Ceph的节点上,以确保数据的安全性和的高可用性。Ceph的还采用了集群监视器,以确保高可用性。为了消除集中Ceph的使用这种算法叫做CRUSH

 

RADOS分发策略�CCRUSH算法:

Ceph的客户端和CephOSD守护进程都使用CRUSH算法来高效地对数据容器的信息需求进行计算,而不必依赖于一个查找表。CRUSH与旧方法相比,提供了更好的数据管理机制,使大规模清晰地将工作分配到集群中的所有客户端和OSD守护。CRUSH使用智能的数据复制,以确保弹性,这样可以更好的适合于超大规模存储。以下各节提供更多的细节CRUSH是如何工作的。

Ceph分布式文件系统

从上图的流程解读RADOS是如何将对象分发到不同的OSD(OSD),首先需要了解Ceph定义的几个存储区域概念。

Pool是一个命名空间,客户端向RADOS上存储对象时需要指定一个PoolPool通过配置文件定义并可以指定Pool的存储OSD节点范围和PG数量。

PGPool内部的概念,是对象和OSD的中间逻辑分层,对象首先会通过简单的Hash算法来得到其存储的PG,这个PG和对象是确定的。然后每一个PG都有一个primary OSD和几个Secondary OSD,对象会被分发都这些OSD上存储,而这个分发策略称为CRUSHCeph的数据均匀分布的核心。

需要注意的是整个CRUSH以上的流程实现都是在客户端计算,因此客户端本身需要保存一份Cluster Map,而这是从Monitor处获得。从这里我们也可以了解到Monitor主要职责就是负责维护这份Cluster Map并保证强一致性。

CRUSH通过伪随机算法来确保均匀的数据分布,它的输入是PG,Cluster StatePolicy,并且保证CRUSHObject Name一样的情况下,即使后两者参数发生改变也会得到一致的读取(注意是读取)。并且这个CRUSH算法是可配置的,通过PG NumberWeight的指定可以得到不同的分布策略。这个可配置的分布策略让Ceph的能力得到极大加强。

 

RADOS的逻辑结构:

Ceph分布式文件系统

在使用RADOS系统时,大量的客户端程序通过与OSD或者monitor的交互获取cluster map,然后直接在本地进行计算,得出对象的存储位置后,便直接与对应的OSD通信,完成数据的各种操作。可见,在此过程中,只要保证cluster map不频繁更新,则客户端显然可以不依赖于任何元数据服务器,不进行任何查表操作,便完成数据访问流程。在RADOS的运行过程中,cluster map的更新完全取决于系统的状态变化,而导致这一变化的常见事件只有两种:OSD出现故障,或者RADOS规模扩大。而正常应用场景下,这两种事件发生 的频率显然远远低于客户端对数据进行访问的频率。

 

群集映射:

 Ceph的使用取决于Ceph的客户和CephOSD守护集群拓扑知识,包括5类映射

 1.监控映射

包含集群FSID,位置,名称地址和每个监视器的端口。这也表明现在的时期里,当创建映射时,并且它最后一被改变。要查看监控映射,执行如下命令

 #  ceph mon dump

 

2.OSD映射

  包含集群FSID,当创建和最后修改映射时间,池的列表,副本大小,PG数字的OSD的列表,他们的状态(例如,upin)。要查看一个OSD映射,执行如下命令

ceph osd dump

 

3.PG映射

包含PG版本,其时间戳记,最后OSD映射时代,完整的比率,如PG ID,每个配置组集,代理设置,在PG的状态(例如 active + clean)和每个池数据使用统计数据。

 

4.CRUSH映射

包含存储设备,故障域层次结构(例如,设备,主机,机架,行,空间等),并遍历层次结构存储数据时的规则的列表。要查看CRUSH映射,执行命令: getcrushmap �Co {filename},然后通过执行crushtool -D {comp-crushmap-filename} -O {decomp-crushmap-filename}反编译。你可以查看在文本编辑器或反编译的映射或使用命令cat查看。

 

5.MDS映射

包含了现有的MDS映射从它创建至最后一次修改的时期。它还包含池用于存储元数据,元数据服务器的列表,以及元数据服务器中。要查看MDS映射,执行如下命令

# ceph mds dump

 

 每个映射保持一个重复历史关于其运行状态的变化。Ceph的监视器保持集群的主副本映射,包括集群成员的状态,变化,和Ceph的存储集群的整体健康。

 

Ceph分布式文件系统 

 

上图左侧的几个概念说明如下:

1. File ―― 此处的file就是用户需要存储或者访问的文件。对于一个基于Ceph开发的对象存储应用而言,这个file也就对应于应用中的对象,也就是用户直接操作的对象

 

2. Ojbect ―― 此处的objectRADOS所看到的对象Object与上面提到的file的区别是,object的最大sizeRADOS限定(通常为2MB4MB),以便实现底层存储的组织管理。因此,当上层应用向RADOS存入size很大的file时,需要将file切分成统一大小的一系列object(最后一个的大小可以不同)进行存储。为避免混淆,在本文中将尽量避免使用中文的对象这一名词,而直接使用fileobject进行说明。

 

3. PGPlacement Group―― 顾名思义,PG的用途是对object的存储进行组织和位置映射。具体而言,一个PG负责组织若干个object(可以为数千个甚至更多),但一个object只能被映射到一个PG中,即,PGobject之间是一对多映射关系。同时,一个PG会被映射到nOSD上,而每个OSD上都会承载大量的PG,即,PGOSD之间是多对多映射关系。在实践当中,n至少为2,如果用于生产环境,则至少为3。一个OSD上的PG则可达到数百个。事实上,PG数量的设置牵扯到数据分布的均匀性问题。关于这一点,下文还将有所展开。

 

4. OSD ―― object storage device,前文已经详细介绍,此处不再展开。唯一需要说明的是,OSD的数量事实上也关系到系统的数据分布均匀性,因此其数量不应太少。在实践当中,至少也应该是数十上百个的量级才有助于Ceph系统的设计发挥其应有的优势。

 

基于上述定义,便可以对寻址流程进行解释了。具体而言, Ceph中的寻址至少要经历以下三次映射:

 

File -> Object映射:

inoFile的元数据,File的唯一id

onoFile切分产生的某个object的序号)

oidobject id: ino + ono

 

这次映射的目的是,将用户要操作的file,映射为RADOS能够处理的object。其映射十分简单,本质上就是按照object的最大sizefile进行切分,相当于RAID中的条带化过程。这种切分的好处有二:一是让大小不限的file变成最大size一致、可以被RADOS高效管理的object;二是让对单一file实施的串行处理变为对多个object实施的并行化处理。

每一个切分后产生的object将获得唯一的oid,即object id。其产生方式也是线性映射,极其简单。图中,ino是待操作file的元数据,可以简单理解为该file的唯一idono则是由该file切分产生的某个object的序号。而oid就是将这个序号简单连缀在该file id之后得到的。举例而言,如果一个idfilenamefile被切分成了三个object,则其object序号依次为012,而最终得到的oid就依次为filename0filename1filename2

这里隐含的问题是,ino的唯一性必须得到保证,否则后续映射无法正确进行。

 

Object -> PG映射:

hashoid&mask -> pgid

mask = PG总数mm2的整数幂)- 1

Ceph指定一个静态hash函数计算oid的值,将oid映射成一个近似均匀分布的伪随机值,然后和mask按位相与,得到pgid

 

首先是使用Ceph系统指定的一个静态哈希函数计算oid的哈希值,将oid映射成为一个近似均匀分布的伪随机值。然后,将这个伪随机值和mask按位相与,得到最终的PG序号(pgid)。根据RADOS的设计,给定PG的总数为mm应该为2的整数幂),则mask的值为m-1。因此,哈希值计算和按位与操作的整体结果事实上是从所有mPG中近似均匀地随机选择一个。基于这一机制,当有大量object和大量PG时,RADOS能够保证objectPG之间的近似均匀映射。又因为object是由file切分而来,大部分objectsize相同,因而,这一映射最终保证了,各个PG中存储的object的总数据量近似均匀。

从介绍不难看出,这里反复强调了“大量”。只有当objectPG的数量较多时,这种伪随机关系的近似均匀性才能成立,Ceph的数据存储均匀性才有保证。为保证“大量”的成立,一方面,object的最大size应该被合理配置,以使得同样数量的file能够被切分成更多的object;另一方面,Ceph也推荐PG总数应该为OSD总数的数百倍,以保证有足够数量的PG可供映射。

 

PG -> OSD映射:

采用CRUSH算法,将pgid代入其中,然后得到一组共nOSDn由部署配置文件决定,一般3个)

 

第三次映射就是将作为object的逻辑组织单元的PG映射到数据的实际存储单元OSD。如图所示,RADOS采用一个名为CRUSH的算法,将pgid代入其中,然后得到一组共nOSD。这nOSD即共同负责存储和维护一个PG中的所有object。前已述及,n的数值可以根据实际应用中对于可靠性的需求而配置,在生产环境下通常为3。具体到每个OSD,则由其上运行的OSD deamon负责执行映射到本地的object在本地文件系统中的存储、访问、元数据维护等操作。

和“object -> PG”映射中采用的哈希算法不同,这个CRUSH算法的结果不是绝对不变的,而是受到其他因素的影响。其影响因素主要有二:

一、是当前系统状态,也就是上文逻辑结构中曾经提及的cluster map。当系统中的OSD状态、数量发生变化时,cluster map可能发生变化,而这种变化将会影响到PGOSD之间的映射。

二、是存储策略配置。这里的策略主要与安全相关。利用策略配置,系统管理员可以指定承载同一个PG3OSD分别位于数据中心的不同服务器乃至机架上,从而进一步改善存储的可靠性。

因此,只有在系统状态(cluster map)和存储策略都不发生变化的时候,PGOSD之间的映射关系才是固定不变的。在实际使用当中,策略一经配置通常不会改变。而系统状态的改变或者是由于设备损坏,或者是因为存储集群规模扩大。好在Ceph本身提供了对于这种变化的自动化支持,因而,即便PGOSD之间的映射关系发生了变化,也并不会对应用造成困扰。事实上,Ceph正是需要有目的的利用这种动态映射关系。正是利用了CRUSH的动态特性,Ceph可以将一个PG根据需要动态迁移到不同的OSD组合上,从而自动化地实现高可靠性、数据分布re-blancing等特性。

之所以在此次映射中使用CRUSH算法,而不是其他哈希算法,原因之一正是CRUSH具有上述可配置特性,可以根据管理员的配置参数决定OSD的物理位置映射策略;另一方面是因为CRUSH具有特殊的“稳定性”,也即,当系统中加入新的OSD,导致系统规模增大时,大部分PGOSD之间的映射关系不会发生改变,只有少部分PG的映射关系会发生变化并引发数据迁移。这种可配置性和稳定性都不是普通哈希算法所能提供的。因此,CRUSH算法的设计也是Ceph的核心内容之一。

Ceph通过三次映射,完成了从fileobjectPGOSD整个映射过程。通观整个过程,可以看到,这里没有任何的全局性查表操作需求。至于唯一的全局性数据结构cluster map,在后文中将加以介绍。可以在这里指明的是,cluster map的维护和操作都是轻量级的,不会对系统的可扩展性、性能等因素造成不良影响。

 

集群的维护

若干个mintor共同负责ceph集群中所有osd状态的发现与记录,并共同形成cluster mapmaster版本,然后扩散至全体osdclientOsd使用cluster map进行数据维护,而client使用cluster map进行数据寻址。

在集群中,各个monitor的功能总体上是一样的,其相互间的关系可以被简单理解为主从备份关系。因此,在下面的讨论中不对各个monitor加以区分。

monitor并不主动轮询各个OSD的当前状态。正相反,OSD需要向monitor上报状态信息。常见的上报有两种情况:一是新的OSD被加入集群,二是某个OSD发现自身或者其他OSD发生异常。在收到这些上报信息后,monitor将更新cluster map信息并加以扩散。

 

Cluster map实际内容:

1、Epoch版本号。Cluster mapepoch是一个单调递增序列。Epoch越大,则cluster map版本越新。因此,持有不同版本cluster mapOSDclient可以简单地通过比较epoch决定应该遵从谁手中的版本。而monitor手中必定有epoch最大、版本最新的cluster map。当任意两方在通信时发现彼此epoch值不同时,将默认先将cluster map同步至高版本一方的状态,再进行后续操作。

2、各个OSD的网络地址。

3、各个OSD的状态。OSD状态的描述分为两个维度:up或者down(表明OSD是否正常工作),in或者out(表明OSD是否在至少一个PG中)。因此,对于任意一个OSD,共有四种可能的状态:

―― Upin:说明该OSD正常运行,且已经承载至少一个PG的数据。这是一个OSD的标准工作状态;

―― Upout:说明该OSD正常运行,但并未承载任何PG,其中也没有数据。一个新的OSD刚刚被加入Ceph集群后,便会处于这一状态。而一个出现故障的OSD被修复后,重新加入Ceph集群时,也是处于这一状态;

―― Downin:说明该OSD发生异常,但仍然承载着至少一个PG,其中仍然存储着数据。这种状态下的OSD刚刚被发现存在异常,可能仍能恢复正常,也可能会彻底无法工作;

―― Downout:说明该OSD已经彻底发生故障,且已经不再承载任何PG

4、CRUSH算法配置参数。表明了Ceph集群的物理层级关系(cluster hierarchy),位置映射规则(placement rules)。

 

 

ClientMonitors中得到CRUSH MAPOSD MAPCRUSH Ruleset,然后使用CRUSH算法计算出Object所在的OSD set。所以Ceph不需要Name服务器,Client直接和OSD进行通信。伪代码如下所示:

  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:]

这种数据映射的优点是:

Object分成组,这降低了需要追踪和处理metadata的数量(在全局的层面上,我们不需要追踪和处理每个objectmetadataplacement,只需要管理PGmetadata就可以了。PG的数量级远远低于object的数量级)

增加PG的数量可以均衡每个OSD的负载,提高并行度。

分隔故障域,提高数据的可靠性。

 

数据操作流程,强一致性:

Ceph分布式文件系统 

当某个client需要向Ceph集群写入一个file时,首先需要在本地完成5.1节中所叙述的寻址流程,将file变为一个object,然后找出存储该object的一组三个OSD。这三个OSD具有各自不同的序号,序号最靠前的那个OSD就是这一组中的Primary OSD,而后两个则依次是Secondary OSDTertiary OSD

找出三个OSD后,client将直接和Primary OSD通信,发起写入操作(步骤1)。Primary OSD收到请求后,分别向Secondary OSDTertiary OSD发起写入操作(步骤23)。当Secondary OSDTertiary OSD各自完成写入操作后,将分别向Primary OSD发送确认信息(步骤45)。当Primary OSD确信其他两个OSD的写入完成后,则自己也完成数据写入,并向client确认object写入操作完成(步骤6)。

之所以采用这样的写入流程,本质上是为了保证写入过程中的可靠性,尽可能避免造成数据丢失。同时,由于client只需要向Primary OSD发送数据,因此,在Internet使用场景下的外网带宽和整体访问延迟又得到了一定程度的优化。

 

高新能:

ClientServer直接通信,不需要代理和转发

多个OSD带来的高并发度。objects是分布在所有OSD上。

负载均衡。每个OSD都有权重值(现在以容量为权重)

client不需要负责副本的复制(primary负责),这降低了client的网络消耗。

 

高可靠性:

数据多副本。可配置的per-pool副本策略和故障域布局,支持强一致性。

没有单点故障。可以忍受许多种故障场景;防止脑裂;单个组件可以滚动升级并在线替换。

所有故障的检测和自动恢复。恢复不需要人工介入,在恢复期间,可以保持正常的数据访问。

并行恢复。并行的恢复机制极大的降低了数据恢复时间,提高数据的可靠性。

 

Ceph分布式文件系统


主机角色分配

192.168.31.80      admin(ceph-deploy,ntp服务器)

192.168.31.84      osd1(mon*1,osd*3)

192.168.31.85      osd2(mon*1,osd*3)

192.168.31.86      osd3(mon*1,osd*3)


安装配置前准备工作,在admin主机生成密钥和公钥并认证其他节点服务器

~]# ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''~]# ssh-copy-id -i /root/.ssh/id_rsa.pub osd1
~]# ssh-copy-id -i /root/.ssh/id_rsa.pub osd2
~]# ssh-copy-id -i /root/.ssh/id_rsa.pub osd3


admin服务器安装配置:

#安装配置ntp服务器~]# cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime  #修改时区~]# yum install ntp~]# vim /etc/ntp.conf server 127.127.1.0fudge 127.127.1.0 stratum 8restrict default nomodify~]# systemctl start ntpd#默认的源比较慢,这里使用阿里的源~]# wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo(下载阿里云的base源)~]# wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repo(下载阿里云的epel源)~]# sed -i 's/$releasever/7.2.1511/g' /etc/yum.repos.d/CentOS-Base.repo~]# vim /etc/yum.repos.d/ceph.repo[ceph]name=cephbaseurl=http://download.ceph.com/rpm-hammer/el7/x86_64/gpgcheck=0[ceph-noarch]name=cephnoarchbaseurl=http://download.ceph.com/rpm-hammer/el7/noarch/gpgcheck=0~]# yum makecache#在admin安装ceph-deploy~]# yum install ceph-deploy#在osd1,osd2,osd3等上安装ceph包~]# yum install ceph#在远程主机上部署一个集群,并生成配置文件和集群内部认证密钥文件~]# ceph-deploy mon create-initial#在远程主机上部署一个ceph监控(mon)~]# ceph-deploy mon add node3#添加一个节点到现有的集群中,添加完成后需要在ceph.conf中添加上对应的节点,并同步~]# ceph-deploy --overwrite-conf config push node1 node2 node3#强行将修改的配置文件同步到其他节点上~]# ceph-deploy disk list node1 #查看节点的磁盘情况~]# ceph-deploy osd prepare osd1:/dev/sdc1:/dev/sdb1 osd1:/dev/sdd1:/dev/sdb2 osd1:/dev/sde1:/dev/sdb3#创建三个osdrbd create block-csdn --size=100rbd map rbd/block-csdnrbd unmap /dev/rbd0




本文出自 “马尔高” 博客,请务必保留此出处http://kgdbfmwfn.blog.51cto.com/5062471/1717970