Ceph是根据加州大学Santa Cruz分校的Sage Weil的博士论文所设计开发的新一代自由软件分布式文件系统,其设计目标是良好的可扩展性(PB级别以上)、高性能及高可靠性。Ceph其命名和UCSC(Ceph 的诞生地)的吉祥物有关,这个吉祥物是“Sammy”,一个香蕉色的蛞蝓,就是头足类中无壳的软体动物。这些有多触角的头足类动物,是对一个分布式文件系统高度并行的形象比喻。
其设计遵循了三个原则:数据与元数据的分离,动态的分布式的元数据管理,可靠统一的分布式对象存储机制。本文将从Ceph的架构出发,综合性的介绍Ceph分布式文件系统特点及其实现方式。
Ceph是一个高可用、易于管理、开源的分布式存储系统,可以在一套系统中同时提供对象存储、块存储以及文件存储服务。其主要由Ceph存储系统的核心RADOS以及块存取接口、对象存取接口和文件系统接口组成,如图所示
Ceph的底层是RADOS,它的意思是“A reliable,autonomous, distributed object storage”。 RADOS作为Ceph分布式文件系统的一个子项目,是为了满足Ceph的需求而设计的,但是,其也可以单独作为一种分布式数据存储系统,给其他的有类似需求的分布式文件系统提供数据存储服务。Ceph文件系统, Ceph对象存储和Ceph块设备从RADOS的存储集群中读去和写入数据。
Ceph作为一个分布式存储系统,其对外提供的接口,决定了其通用性以及扩展性。如上图架构图中所示的那样,Ceph对外提供了丰富多样的服务接口,包括多种编程语言接口LIBRADOS(备注,上图来自Ceph中文社区,社区人员在翻译的过程中将字母L遗失掉了)、对象存储接口(RADOSGW)、块存储接口(RBD)以及文件系统接口(Ceph FS)。其中LIBRADOS编程接口是其他各种客户端接口的基础,其他接口都是基于LIBRADOS来进行扩展实现的。
Ceph中RADOS(Reliable Autonomic Distributed Object Store)存储集群是所有其他客户端接口使用和部署的基础。RADOS由两个组件组成:
OSD: Object StorageDevice,提供存储资源。
Monitor:维护整个Ceph集群的全局状态。
典型的RADOS部署架构由少量的Monitor监控器以及大量的OSD存储设备组成,它能够在动态变化的基于异质结构的存储设备集群之上提供一种稳定的、可扩展的、高性能的单一逻辑对象存储接口。
RADOS系统的架构如图所示:
我们看到,RADOS不是某种组件,而是由OSD(Object Storage Device)集群和Monitor集群组成。通常,一个RADOS系统中,OSD集群是由大量的智能化的OSD节点组成;Monitor集群是由少量的Monitor节点组成。OSD集群负责存储所有对象的数据。Monitors集群负责管理Ceph集群中所有成员、关系、属性以及数据分发等信息。
我们将Ceph架构中除了底层基础RADOS之上的LIBRADOS、RADOSGW、RBD以及Ceph FS统一称为Ceph客户端接口。而LIBRADOS又是Ceph其它如RADOSGW、RBD以及Ceph FS的基础。简而言之就是RADOSGW、RBD以及Ceph FS根据LIBRADOS提供的多编程语言接口开发。所以他们之间是一个阶梯级的关系。
RADOSGW(RADOS Gmeway),又叫Ceph对象存储网关,是一个底层基于librados向客户端提供RESTful接口的对象存储接口。目前Ceph支持两种API接口:
(1) S3.compatible:S3兼容的接口,提供与Amazon S3大部分RESTfuI API接口兼容的API接口。
(2) Swift.compatible:提供与OpenStack Swift大部分接口兼容的API接口。Ceph的对象存储使用网关守护进程(radosgw), radosgw结构图如图所示:
在实际的Ceph集群中,radosgw是一个监听RESTfulAPI访问的后台进程,s3 API和Swift APl使用同一个命名空间,即共享同一个命名空间;所以,你可以用其中一个接口写入数据而又用另外一个接口读出数据。
一个数据块是一个字节序列(例如,一个512字节的数据块)。基于数据块存储接口最常见的介质,如硬盘,光盘,软盘,甚至是传统的9磁道的磁带的方式来存储数据。块设备接口的普及使得虚拟块设备成为构建像Ceph海量数据存储系统理想选择。
在一个Ceph的集群中, Ceph的块设备支持自动精简配置,调整大小和存储数据。Ceph的块设备可以充分利用 RADOS功能,实现如快照,复制和数据一致性。Ceph的RADOS块设备(即RBD)通过RADOS协议与内核模块或librbd的库进行交互。。RBD的结构如图所示:
在Ceph中,如果客户端要想使用存储集群服务提供的块存储,必须要先安装相应的Linux内核模块Kernel Module,或者使用librbd编程接口。
Ceph文件系统(CEPH FS)是一个POSIX兼容的文件系统,使用Ceph的存储集群来存储其数据。Ceph的文件系统使用相同的Ceph的存储集群系统比如Ceph的块设备,Ceph的S3和SwiftAPI对象存储,或本机绑定(librados)。CEPH FS的结构图如下所示:
CEPH FS是一个符合POSIX标准的文件系统接口,同时支持用户空间文件系统FUSE。在CEPH FS中,与对象存储接口与块存储接口最大的不同就是在集群中增加了文件系统元数据服务节点MDS(Ceph Metadata Server)。MDS也支持多台机器分布式的部署,以实现系统的高可用性。文件系统客户端需要安装对应的Linux内核模块Ceph FS KernelObject或者Ceph FS FUSE组件。
Ceph存储集群从客户端接收文件,每个文件都会被客户端切分成一个或多个对象,然后将这些对象进行分组,再根据一定的策略存储到集群的OSD节点中,其存储过程如图所示:
图中,对象的分发需要经过两个阶段的计算,才能得到存储该对象的OSD,然后将对象存储到OSD中对应的位置。
(1) 对象到PG的映射。PG(PlaccmentGroup)是对象的逻辑集合。PG是系统向OSD节点分发数据的基本单位,相同PG里的对象将被分发到相同的OSD节点中(一个主OSD节点多个备份OSD节点)。对象的PG是由对象ID号通过Hash算法,结合其他一些修正参数得到的。
(2) PG到相应的OSD的映射,RADOS系统利用相应的哈希算法根据系统当前的状态以及PG的ID号,将各个PG分发到OSD集群中。OSD集群是根据物理节点的容错区域(比如机架、机房等)来进行划分的。
Ceph中的OSD节点将所有的对象存储在一个没有分层和目录的统一的命名空问中。每个对象都包含一个ID号、若干二进制数据以及相应的元数据。
ID号在整个存储集群中是唯一的;元数据标识了所存储数据的属性。一个对象在OSD节点中的存储方式大致如图所示。
而对存储数据的语义解释完全交给相应的客户端来完成,比如,Ceph FS客户端将文件元数据(比如所有者、创建日期、修改日期等)作为对象属性存储在Ceph中。
Ceph作为一个高可用、高性能的对象存储系统,其数据读取及写入方式是保证其高可用性及高性能的重要手段。对于已知的数据对象,Ccph通过使用CRUSH(ControlledReplication Under Scalable Hashing)算法计算出其在Ceph集群中的位置,然后直接与对应的OSD设备进行交互,进行数据读取或者写入。
例如其写入数据的其主要过程如图所示。
首先,客户端获取Ceph存储系统的状态信息Cluster Map,然后根据状态信息以及将要写入的Pool的CRUSH相关信息,获取到数据将要写入的OSD,最后
OSD将数据写入到其中相应的存储位置。其中相关概念的解释如下:
(1) 集群地图(Cluster Map):Ceph依赖于客户端以及OSD进程中保存有整个集群相关的拓扑信息,来实现集群的管理和数据的读写。整个集群相关的拓扑信息就称之为“Cluster Map”。Cluster Map主要保存Monitor集群、OSD集群、MDS集群等相关的拓扑结构信息以及状态信息。
(2) 存储池(P001):是对Ceph集群进行的逻辑划分,主要设置其中存储对象的权限、备份数目、PG数以及CRUSH规则等属性。
在传统的存储系统中,要查找数据通常是依赖于查找系统的的文件索引表找到对应的数据在磁盘中的位置。而在Ceph对象存储系统中,客户端与OSD节点都使用CRUSH算法来高效的计算所存储数据的相关信息。相对于传统的方式,CRUSH提供了一种更好的数据管理机制,它能够将数据管理的大部分工作都分配给客户端和OSD节点,这样为集群的扩大和存储容量的动态扩展带来了很大的方便。CRUSH是一种伪随机数据分布算法,它能够在具有层级结构的存储集群中有效的分发对象副本。
CRUSH算法是根据集群中存储设备的权重来进行数据分发的,数据在各个OSD设备上近似均匀概率分布。CRUSH中,数据在存储设备上的分布是根据一个层次化的集群地图(Cluster Map)来决定的。集群地图是由可用的存储资源以及由这些存储资源构建的集群的逻辑单元组成。比如一个Ceph存储集群的集群地图的结构可能是一排排大型的机柜,每个机柜中包含多个机架,每个机架中放置着存储设备。数据分发策略是依照数据的存放规则(placement rules)进行定义的,存放规则是指数据在备份以及存放时应该遵循的相关约定,比如约定一个对象的三个副本应该存放在三个不同的物理机架上。
给定一个值为x的整数,CRUSH将根据相应的策略进行哈希计算输出一个
有序的包含n个存储目标的序列:
CRUSH(x)=(osd1,osd2,osd3osdn)
CRUSH利用健壮的哈希函数,其得到的结果依赖于集群地图Cluster Map、存放规贝则(placementmles)和输入x。并且CRUSH是一个伪随机算法,两个相似的输入得到的结果是没有明显的相关性的。这样就能确保Ceph中数据分布是随机均匀的。
Ceph中,为了保持数据的一致性,在PG内部通常会进行对象的净化过程(scrubobjects)。数据净化通常每天进行一次(通常在数据I/O量不大,进行系统维护时进行)。OSD设备还能够通过进行数据对象bit-for-bit的对比进行深度的数据净化,用以找到普通数据净化中不易察觉的问题(比如磁盘扇区损坏等)。通过数据维护和净化,为数据的一致性提供了保障。
在传统的分布式系统中,客户端通常与一个中央节点进行交互,这样通常存在着单点故障问题,而且不利于系统的扩展。Ceph中客户端是直接与OSD节点进行交互,而不需要通过中心节点。对同一个对象,Ceph通常会在不同的OSD节点上创建多个备份,这样就保证了数据可靠性和高可用性。Ceph对元数据服务器也采用高可用的集群管理,这样也提高了系统元数据的的高可用性。Ceph的良好的高可用性和扩展性是系统设计的核心,这其中用到了很多精巧的设计和算法,下面就对实现Ceph的一些关键的实现技术进行介绍。
在Ceph的客户端读或者写数据之前,他们必须先通过Ceph Monitor来获取最新的Cluster Map的副本。如果只有一个Monitor节点,Ceph存储集群也可以正常工作,但是这样会有单点的风险(如果这一台Monitor节点宕机了,整个Ceph
集群就无法正常工作)。Ceph中支持多台Monitor节点组成高可用的集群来提高整个Ceph系统的高可用性。Ceph中通过Paxos算法来保持Monitor集群中各个节点的状态一致性。
在通过Ceph FS接口使用Ceph集群时,Ceph集群中需要部署MDS(Metadata Server)进程,通常也是使用集群的方式进行部署。MDS集群的主要作用是将所有的文件系统元数据(目录、文件拥有者、访问权限等)存放在高可用的内存中。这样,客户端简单的文件操作(ls,cd等)将由MDS集群快速的响应,而不用消耗OSD设备的I/O,实现了元数据与数据的分离。为Ceph FS文件系统接口将能提供了性能上的保证。
Ccph FS旨在提供POSIX兼容的文件系统接口,依赖于MDS中运行的ceph-mds进程,该进程不仅能够作为一个单一的进程运行,还可以分布式的运行在多个服务器上,实现了高可用性和扩展性。
(1) 高可用性:通常在Ceph集群中有多个ceph-mds进程在运行。当一个Ceph-mds出现运行故障时,备用的其他的ceph-mds能够立刻接替失效的ceph-mds的工作。这个过程主要依赖于Ceph中的日志机制并且通过高可用的Monitor进程来完成相关的恢复工作。
(2) 扩展性:Ceph集群中可以分布式的部署多个ceph-mds进程实例,他们共同完成Ceph文件系统相关的工作,并且能够动态的实现负载均衡。
在许多传统的集群架构中,往往设立一个中心节点来掌控整个集群的全部元数据信息,这样不仅会因为单点问题对系统的高可用性造成影响,而且中心节点的性能也会成为系统横向扩展的瓶颈。在Ceph就没有这样的瓶颈,在Ceph中,每个Ceph的客户端和OSD节点都保存有整个系统相关的拓扑信息。这样,客户端就能直接和存储数据的OSD节点进行交互,OSD节点相互之间也能直接进行交互。Ceph中去中心节点的架构能够带来以下一些好处:
(1) OSD节点能直接为客户端提供服务:我们知道,任何网络设备都有一个并发连接的上限。中心节点结构的分布式集群中,中心节点往往是整个系统性能的瓶颈。Ceph中客户端能与存放数据的OSD节点直接通信,而不用经过任何的中心节点,这样整个系统不仅没有单点问题,而且性能就得到了很大的提升。
(2) OSD节点参与系统的维护:通常一个OSD节点加入到Ceph存储集群中,要向集群中的Monitor节点汇报自己的状态。如果OSD节点宕机,则需要系统能自动检测出来。这通常是由Monitor节点周期性的对各个OSD节点中的相关服务进行检测来实现。如果Monitor节点检测的周期间隔太短会影响系统的性能;而如果检测周期间隔太长,则会使整个系统有较长的时间处于不一致的状态。Ceph中允许OSD节点对相邻的OSD节点的状态进行检测,如果相邻的节点有状态变化,OSD节点则会主动向整个集群进行汇报,同时集群中相关的Cluster Map得到更新。这样大大减轻了Monitor节点的压力。系统的扩展性和高可用性得到很大的提升。
(3) OSD节点定期的数据清洁:数据清洁是指,一个OSD节点中存储的对象与另外一个存储该对象副本的OSD节点之间进行对象的元数据对比,依此来找出文件系统相关的错误。Ceph中OSD节点能够自动的进行数据清洁(通常是一天一次)。除了普通的数据清洁,Ceph中OSD节点还可以通过对相同对象不同副本中的数据进行按位(bit-for-bit)的深度数据清洁(通常一周一次)。这种数据清洁机制对系统的数据一致性有很大的帮助。
(4) 数据智能备份:和Ceph客户端一样,Ceph OSD节点也使用CRUSH算法。但是和客户端使用CRUSH算法来查找数据不同,Ceph OSD节点使用该算法来计算对象的备份副本应该被存储在哪个位置。数据智能备份的大致流程如图所示:
当在Ceph集群中增加或减少OSD设备时,集群会执行负载再均衡的过程(rebalancing)。首先,集群地图(Cluster Map)会得到更新,PG ID以及OSD集群相关的信息都会得到更新。如下图,简单展示了增加OSD存储设备时数据再均衡的大致过程。其中,一些PG从其原来所处的OSD存储设备迁移到了新的OSD存储设备。在数据再均衡过程中,CRUSH保持稳定,有许多的PG还是依然保留其原有的配置。并且由于进行了数据的迁出,原有OSD设备中的剩余容量也会相应的有所增加。整个数据再均衡过程也是利用的CRUSH算法,数据依然是均衡的分布在新的OSD集群中。
在本文中,我们介绍了Ceph分布式文件系统的基本架构、工作机制及原理。并且从架构和原理的基础上论述了其优良的特性。综合看来,Ceph分布式文件系统有如下的特点:
(1) Ceph的核心RADOS通常是由少量的负责集群管理的Monitor进程和大量的负责数据存储的OSD进程构成,采用无中心节点的分布式架构,对数据进行分块多份存储。具有良好的扩展性和高可用性。
(1) Ceph分布式文件系统提供了多种客户端,包括对象存储接口、块存储接口以及文件系统接口,具有广泛的适用性,并且客户端与存储数据的OSD设备直接进行数据交互,大大提高了数据的存取性能。
(2) Ceph作为分布式文件系统,其能够在维护 POSIX 兼容性的同时加入了复制和容错功能。从2010 年 3 月底,以及可以在Linux 内核(从2.6.34版开始)中找到 Ceph 的身影,作为Linux的文件系统备选之一,Ceph.ko已经集成入Linux内核之中。虽然目前Ceph 可能还不适用于生产环境,但它对测试目的还是非常有用的。Ceph 不仅仅是一个文件系统,还是一个有企业级功能的对象存储生态环境。现在,Ceph已经被集成在主线 Linux 内核中,但只是被标识为实验性的。在这种状态下的文件系统对测试是有用的,但是对生产环境没有做好准备。但是考虑到Ceph 加入到 Linux 内核的行列,不久的将来,它应该就能用于解决海量存储的需要了。
Ceph 中文文档:http://docs.openfans.org/ceph
http://docs.openfans.org/ceph/ceph4e2d658765876863/ceph-1