Ceph基础概述

来源:互联网 发布:阿里云2003申请入口 编辑:程序博客网 时间:2024/06/04 13:36

原文地址:http://docs.ceph.com/docs/master/architecture/

一、存储数据

        ceph存储集群从ceph客户端获取数据,客户端可以是ceph块存储设备,ceph对象存储,ceph文件系统或者你用librados自己实现的一个客户端。文件以对象的形式存储在对象存储设备中。Ceph OSD Daemons处理读写操作。


        Ceph OSD Daemons将数据当成一个个的对象来处理,对象包括一个ID,二进制数据,和元数据,元数据是键值对的形式,其语义完全由Ceph客户端决定,比如说CephFS用元数据存储文件属性,包括文件拥有者,创建日期,最后修改日期等。注意:对象ID在整个集群内是唯一的而不是只在本地文件系统中唯一。


二、扩展性和高可用性

        在传统的体系结构中,客户端和一个统一的集中的部件通信,例如网关,broker,API,facade等),这个集中的部件是这个复杂系统的唯一入口,从而成为了性能和扩展瓶颈,而且会导致单点故障的问题,也就是这个部件坏了,整个系统就玩完了。ceph消灭了这个单点故障点,让客户端直接和Ceph OSD Daemons通信,Ceph OSD Daemons在其他的节点上创建对象的副本从而保证了数据的安全和高可用。Ceph还有一个monitor集群来保证高可用。Ceph使用CRUSH算法来消灭集中化。

1、CRUSH简介

        CRUSH算法运行在Ceph Clients和Ceph OSD上,用于计算对象的位置信息,它代替了传统的查表的思想,把工作分摊到所有Ceph Clients和Ceph OSD上,增强了弹性扩展和高可用性。

2、集群MAP

        集群MAP由以下五部分组成,用于反映集群的拓扑信息:

        (1)The Monitor Map:包括fsid,位置,hostname+IP addr,Monitor端口号。还包括版本号,map何时建立以及上一次改动的时间。map何时建立以及上一次改动的时间,ceph mon dump命令可以查看一个monitor map,如下图所示。


        (2)The OSD Map:包括fsid,map何时建立以及上一次改动的时间,存储池列表,副本大小,PG数,OSD列表和状态。ceph osd dump命令可以查看一个OSD map,如下图所示。


        (3)The PG Map:包含PG的版本号,时间戳,最近的OSD map版本号,使用率,PG的ID,状态,每一个池的使用统计等等。ceph pg dump命令可以查看一个PG map,如下图所示。


        (4)The CRUSH Map:包含存储设备列表,故障域的层次 (e.g., device, host, rack, row, room, etc.),存储数据时遍历的规则。命令 ceph osd getcrushmap -o {filename}可以查看这个map, 命令crushtool -d {comp-crushmap-filename} -o {decomp-crushmap-filename}可以将它编译成文本形式,用cat查看。

       (5)The MDS Map: 包含现在MDS map的版本号,map何时建立以及上一次改动的时间。它还包含一个存储元数据的池,元数据服务器列表,哪些元数据服务器是up&in的。ceph mds dump命令可以查看一个MDS map,如下图所示。


        每一张map都保留它更改的历史记录。Ceph Monitor有集群map的主拷贝,包括集群成员,状态,改动,和集群健康状况。

3、高可用认证

        Cephx是ceph的一套认证系统,用于用户和daemon的认证,防止攻击。

        用户产生密钥,Ceph monitor拥有密钥的拷贝,他们双方都能够向对方证明自己拥有密钥从而完成认证,认证过程中密钥始终不暴露。

        任何一个Ceph monitor都可以认证用户,没有单点故障。从monitor返回的认证数据包含一个session key,这个session key用用户的密钥加密,所以只有该用户可以向ceph monitor发起请求。认证成功后,用户可以访问所有的OSD和MDS。

        使用cephx必须先由管理员建立用户,如下图所示,client.admin用户激活ceph auth get-or-create-key来生成一个用户名和密钥。ceph的认证子系统生成用户名和密码,并在monitor中保留一份副本,再把这个密码传送给用户,这样,用户和Monitor就共享了同一份密钥。


        认证的过程是这样的,用户将用户名传递给Monitor,monitor生成一个session key,将它用密钥和用户名一起加密,然后将加密后的session key返回给用户,用户将其解密,并向monitor请求一个ticket,monitor生成一个加密的ticket,返回用户,用户将其解密并凭借它像集群中的OSD和MDS发起请求。


        在接下来的客户端和ceph服务器的通信过程中,都要用到最先的认证的ticket进行认证,具体过程如下图。这个认证系统只在ceph client和ceph server中间起作用,如果用户用另一台主机和ceph client通信,这个认证不起作用。


4、“聪明的”守护进程保证了大规模扩展

        在许多集群集群体系中,客户端和集群通信都是通过一个集中的接口,这个集中的接口在大规模集群中成为了一个巨大的瓶颈。Ceph消除了这个瓶颈: Ceph’s OSD Daemons AND Ceph Clients都是对等的,每一个OSD上的守护进程都知道其他OSD的守护进程干了什么,这使得Ceph clients可以直接和OSD上的守护进程通信。

        这就意味着 Ceph’s OSD Daemons可以使用节点上的CPU和内存轻松地完成任务,如果把这些任务集中在某一台服务器,这台服务器很可能崩溃了,这种均摊计算任务的做法导致如下好处:

        (1)OSDs Service Clients Directly: 在连接数受限的情况下,大规模集群很可能造成网络瓶颈,而不同的客户端和不同节点上的不同OSD直接联系消除了这一瓶颈,还避免了单点故障。

        (2)OSD Membership and Status:OSD Daemon会汇报自己的情况,在底层,如果它的状态是down&in表示它它出故障了。如果它没有运行,比如说它崩溃了,它就无法通知monitor它down了,这时monitor可以周期性Ping一个OSD来确认它是不是运行状态的。而且,OSD Daemon也可以知道它相邻的OSD状态,可以更新集群Map,并将它汇报给Monitor。这意味着monitor可以减少工作量。

        (3)Data Scrubbing: 未保持一致性,OSD Daemon也可以侦查和修复对象,它通过比较一定区域内对象和副本的元数据,修复捕捉到的Bug和文件系统错误(通常以天为单位进行)。它也可以以Bit-by-bit的方式比对对象和副本来做一个深层次的擦除,(通常以周为单位进行),它可以定位坏的扇区并做修复。

        (4)Replication: OSD Daemon使用CRUSH算法计算对象应该被存在什么地方,或者做负载均衡。在一个典型写的场景中,客户端用CRUSH算法计算对象存在什么地方,将对象映射到一个PG和相应的组,用CRUSH算法计算这个组的主OSD是哪一个。

        客户端将数据写入这个主OSD,主OSD利用CRUSH算法计算二级和三级OSD并写入副本,确认写成功后通知客户端。


五、动态集群管理

1、存储池

        存储池是一个逻辑概念,客户端从Monitor获取集群map,将对象写入存储池,存储池设置了如下参数:

        (1)对象的拥有者

        (2)PG数

        (3)CRUSH规则


2、将PG映射到OSD

        每一个存储池都有一定数量的PG,CRUSH算法动态地将PG映射到OSD。它先将对象映射到PG,再将PG映射到OSD,而不是将对象和OSD直接映射,这样的间接映射方式使得集群动态均衡时能够灵活地迁移数据。


3、计算PG的ID

        客户端绑定一个monitor时,它向monitor取得最新的集群Map,通过这个Map,它得知所有集群的拓扑情况,但是,它并不知道对象的位置,这个位置是需要计算的,不能很直接从map中获取。

        要计算这个位置,需要的输入有对象的ID和存储池的信息。例如,存储池的名字叫liverpool,当客户端要存储一个命名的对象(e.g., “john,” “paul,” “george,” “ringo”, etc.),对象名字+hashcode+PG数+pool name就可以计算出PG,PG ID的计算步骤如下:

        (1)客户端输入object id和pool id (e.g., pool = “liverpool” and object-id = “john”)

        (2)计算object id的Hash值

        (3)hash值 mod PG数 (e.g., 58) =PG ID

        (4)从pool name获取一个pool ID (e.g., “liverpool” = 4)

        (5)将pool ID 和PG ID连接起来(e.g., 4.58)

4、PEERING AND SETS

        同步所有存有同一个PG的OSD有关该PG上所有对象的状态,使得对象在每一个OSD上的状态都是一致的这个步骤叫做peering。peering故障也会报告给monitor。

        Ceph规定副本数最少为2,最好是3副本。OSD分主次,唯一接受客户端请求的OSD为主OSD,它将副本写入其它OSD。正在接收PG请求并活跃的一系列OSD叫Acting Set, Acting Set中的 OSD daemons并不都是up的,其中up的一部分叫UP Set,OSD故障时,Ceph可以将PG重新映射到其它OSD。例如 Acting Set中有三个OSD: osd.25, osd.32 and osd.61,osd.25是主OSD,如果它出现故障, osd.32则变为主OSD,而 osd.25被移出Up Set 。

5、重新负载均衡

        当一个新的OSD被加入集群,集群Map会更新,对象对应的PG也会改变,下图描述了一个重新负载均衡的过程,不是所有的PG都会从当前的OSD迁移到新的OSD,大部分的PG保持原样,每一个OSD的可存储空间增大。


6、数据一致性

        和Data Scrubbing 一节描述一样。

六、纠删码

        每一个对象被划分成K+M个chunk,K个数据chunk,M个校验chunk,存储池的大小为K+M个OSD,每一个chunk存储在Acting Set的OSD中,chunk的信息作为对象的属性。例如存储池有(K+M=5)个OSD,M=2,那么能够坏2个OSD。

1、读写chunk

        一个叫NYAN的对象,它的内容为ABCDEFGHI,它要被写入存储池,纠删码函数将内容分为ABC,DEF,GHI分块,不足K(3)的整数倍将会被补充。生成两个校验chunk:YXY和GOC。每一个chunk存在一个Acting Set的OSD中,他们的名字都叫NYAN,这五个chunk的创建顺序将被保存,并和对象名一起作为对象的属性 (shard_t)。


        对象被读出时,decoding函数读chunk1,3,4,然后重构内容ABCDEFGHI。函数被告知chunk2,5丢失。OSD4故障了,chunk5不能读出,OSD2最慢,它的chunk不算,这样的情况下三个chunk一读出立马重构内容。


2、被中断的FULL WRITES

        up集(up set )的主OSD接受所有写操作请求。它负责分成若干chunk并把它们下发到其它OSD,同样负责维护一个PG的日志。在下图中一个PG有三个相应的OSD,2个是K,1个是M。活跃集(acting set)的OSD有1,2,3。一个对象在这些OSd中是这样的:chunk D1v1 (i.e. Data chunk number 1, version 1) 在OSD1上,D2v2在OSd2上,C1v1在OSD3上,每一个OSD上的PG日志都是唯一的。

      

          OSD1是主OSD,全写意味着D1v2完全覆盖D1v1,D2v2完全覆盖D2v1,C1v2完全覆盖C1v2,而不是只写差异的部分。每个OSD写完后也会更新自己的log。



        如果全部进行顺利,chunks会被通知写完成,日志的last_complete 指针会从1,1移动到1,2。


        然后D1v1,D2v1,C1v1被删除。


        但是,如果有情况发生,例如OSD1在D2v2没有写完的情况下down了,D2v2只被写了一部分,不能通过他和OSD3上的校验数据恢复。纠删码要求至少两个chunk都是完整的这样才能重构第三个。这是OSD4变为主OSD,它找last_complete所指向的日志入口1,1获得新的日志。


       这是OSD3上的日志1,2发现和OSD4上的1,1不一致,那么OSD3上的C1v2被删除,D1v1被重构并存到OSD4上。

 

七、cache分层

        分层包括一个相对较快的存储池,如SSD,作为一个cache层,和一个相对经济一些的包括纠删码的存储池作为存储层。objecter决定对象存到哪,分层代理决定什么时候将对象从cache中flush到存储层中。cache层和存储层完全对用户透明。


八、扩展

        这里说的扩展是说在已有的ceph中加入自己写的新功能,这时你需要创建一个共享的对象类,叫Ceph Classes。Ceph loads .so classes动态存档在osd class dir目录下 (i.e., $libdir/rados-classes by default)。实现一个class后,可以创建一个对象的新方法来调用Ceph Object Store中提供的方法,或者其他你通过libraries创建的方法。




0 0
原创粉丝点击