ceph基础知识
一、基础概念
ceph官方文档 http://docs.ceph.org.cn/
ceph中文开源社区 http://ceph.org.cn/
1、概述
Ceph是可靠的、可扩展的、统一的、开源分布式的存储系统。
Ceph是一个统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。
Ceph项目最早起源于Sage就读博士期间的工作(最早的成果于2004年发表),并随后贡献给开源社区。在经过了数年的发展之后,目前已得到众多云计算厂商的支持并被广泛应用。RedHat及OpenStack都可与Ceph整合以支持虚拟机镜像的后端存储。
不管你是想为云平台提供Ceph 对象存储和/或 Ceph 块设备,还是想部署一个 Ceph 文件系统或者把 Ceph 作为他用,所有 Ceph 存储集群的部署都始于部署一个个 Ceph 节点、网络和 Ceph 存储集群。
Ceph 存储集群至少需要一个 Ceph Monitor 和两个 OSD 守护进程。运行Ceph文件系统客户端时,则必须要有元数据服务器( MDS )。
Ceph可提供以下三种功能:
• 对象存储RADOSGW(Reliable、Autonomic、Distributed、Object Storage Gateway)
• 块存储RBD(Rados Block Device)
• 文件系统存储Ceph FS(Ceph Filesystem)
2、Ceph优点
• 统一存储 - 虽然ceph底层是一个分布式文件系统,但由于在上层开发了支持对象和块的接口。所以在开源存储软件中,能够一统江湖。
• 高扩展性 - 扩容方便、容量大。能够管理上千台服务器、EB级的容量。
• 可靠性强 - 支持多份强一致性副本。副本能够垮主机、机架、机房、数据中心存放, 安全可靠。
存储节点可以自管理、自动修复。无单点故障,容错性强。
• 性能高 - 因为是多个副本,因此在读写操作时候能够做到高度并行化。理论上,节点越多,整个集群的IOPS和吞吐量越高。
ceph客户端读写数据直接与存储设备(osd) 交互。
3、Ceph应用场景
Ceph可以提供对象存储、块设备存储和文件系统服务,其对象存储可以对接网盘(owncloud)应用业务等;其块设备存储可以对接(IaaS),当前主流的IaaS运平台软件,如:OpenStack、CloudStack、Zstack、Eucalyptus等以及kvm等。
4、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。
当 Ceph 存储集群设定为有2个副本时,至少需要2个OSD守护进程,集群才能达到 active+clean 状态(Ceph 默认有3个副本,但你可以调整副本数)
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,主要保存的文件系统服务的元数据,但对象存储和块存储设备是不需要使用该服务的。Ceph 元数据服务器( MDS )为 Ceph 文件系统存储元数据(也就是说,Ceph 块设备和 Ceph 对象存储不使用MDS )。元数据服务器使得 POSIX 文件系统的用户们,可以在不对 Ceph 存储集群造成负担的前提下,执行诸如 ls、find 等基本命令。
Pool, PG(placement group)
Pool - 存储池, 存储对象的逻辑分区,它规定了数据冗余的类型和对应的副本分布策略支持两种类型:副本(replicated)和 纠删码( Erasure Code)
PG - 归置组, 是一个放置策略组,它是对象的集合,该集合里的所有对象都具有相同的放置策略;
相同PG内的对象都会放到相同的硬盘上; PG是 ceph的核心概念, 服务端数据均衡和恢复的最小粒度就是PG。
面这张图形象的描绘了它们之间的关系:
• 一个Pool里有很多PG,
• 一个PG里包含一堆对象;一个对象只能属于一个PG;
• PG有主从之分,一个PG分布在不同的OSD上
● pool是ceph存储数据时的逻辑分区,它起到namespace的作用;
● 每个pool包含一定数量(可配置)的PG;
● PG里面的对象被映射到不同的object上;
● pool是分布到整个集群的;
● pool可以做故障隔离域,根据不同的用户场景不一进行隔离。
无论使用哪种存储方式(对象、块、挂载),存储的数据都会被切分成对象(Objects)。Objects size大小可以由管理员调整,通常为2M或4M。每个对象都会有一个唯一的OID,由ino与ono生成,虽然这些名词看上去很复杂,其实相当简单:
ino即是文件的File ID,用于在全局唯一标示每一个文件,而ono则是分片的编号。
比如:一个文件FileID为A,它被切成了两个对象,一个对象编号0,另一个编号1,那么这两个文件的oid则为A0与A1。Oid的好处是可以唯一标示每个不同的对象,并且存储了对象与文件的从属关系。由于ceph的所有数据都虚拟成了整齐划一的对象,所以在读写时效率都会比较高。
但是对象并不会直接存储进OSD中,因为对象的size很小,在一个大规模的集群中可能有几百到几千万个对象。这么多对象光是遍历寻址,速度都是很缓慢的。如果将对象直接通过某种固定映射的哈希算法映射到osd上,当这个osd损坏时,对象无法自动迁移至其他osd上面(因为映射函数不允许)。
为了解决这些问题,ceph引入了归置组的概念,即PG。PG是一个逻辑概念,我们linux系统中可以直接看到对象,但是无法直接看到PG。每个对象都会固定映射进一个PG中(相当于把图书馆中的书归类到某一个区域),所以当我们要寻找一个对象时,只需要先找到对象所属的PG,然后遍历这个PG就可以了,无需遍历所有对象。而且在数据迁移时,也是以PG作为基本单位进行迁移,ceph不会直接操作对象。
对象时如何映射进PG的?还记得OID么?首先使用静态hash函数对OID做hash取出特征码,用特征码与PG的数量取模,得到的序号则是PGID。
由于这种设计方式,PG的数量多寡直接决定了数据分布的均匀性,所以合理设置的PG数量可以很好的提升CEPH集群的性能并使数据均匀分布。
PG会根据管理员设置的副本数量进行复制,然后通过crush算法存储到不同的OSD节点上(其实是把PG中的所有对象存储到节点上),第一个osd节点即为主节点,其余均为从节点。
二、块存储
什么是块设备?块设备是i/o设备中的一类,是将信息存储在固定大小的块中,每个块都有自己的地址,还可以在设备的任意位置读取一定长度的数据。可以认为块设备就是硬盘或虚拟硬盘。
查看下Linux环境中的设备:
[root@ceph ~] ls /dev/
/dev/sda /dev/sda1 /dev/sda2 /dev/sdb /dev/sdb1 /dev/hda
/dev/rbd1 /dev/rbd2 …
上面的/dev/sda、/dev/sdb和/dev/hda都是块设备文件,这些文件是怎么出现的呢?当给计算机连接块设备(硬盘)后,系统检测的有新的块设备,该类型块设备的驱动程序就在/dev/下创建个对应的块设备设备文件用户可以通过设备文件使用该块设备。
它们怎么有的叫 sda?有的叫 sdb?有的叫 hda?以sd开头的块设备文件对应的是SATA接口(或者是scsi,usb)的硬盘,而以hd开头的块设备文件对应的是IDE接口的硬盘。
那SATA接口的硬盘跟IDE接口的硬盘有啥区别?你只需要知道,IDE接口硬盘已经很少见到了,逐渐被淘汰中,而SATA接口的硬盘是目前的主流。
sda和sdb的区别呢?当系统检测到多个SATA硬盘时,会根据检测到的顺序对硬盘设备进行字母顺序的命名。PS:系统按检测顺序命名硬盘会导致了盘符漂移的问题。(所以挂载磁盘时一般使用UUID的方式进行挂载)
怎么还有的叫 rbd1 和 rbd2 呢?rbd就是我们压轴主角了。rbd就是由Ceph集群提供出来的块设备。可以这样理解,sda和hda都是通过数据线连接到了真实的硬盘,而rbd是通过网络连接到了Ceph集群中的一块存储区域,往rbd设备文件写入数据,最终会被存储到Ceph集群的这块区域中。
针对多种多样的使用场景,衍生出了很多的文件系统。有的文件系统能够提供更好的读性能,有的文件系统能提供更好的写性能。我们平时常用的文件系统如xfs、ext4是读写性能等各方面比较均衡的通用文件系统。然而,很多应用往往并不需要这种均衡,而需要突出某一方面的性能,如小文件的存储性能。此时,xfs、ext4等通用文件系统如果不能满足应用的需求,应用往往会在裸设备上实现自己的数据组织和管理方式。简单的说,就是应用为了强化某种存储特性而实现自己定制的数据组织和管理方式,而不使用通用的文件系统。
Ceph块设备接口怎么使用?在Ceph集群中创建块设备:rbd create -s 1G myrbd # 保证/etc/ceph目录下有Ceph集群的配置文件ceph.conf和ceph.client.admin.keyring
在用户机上挂载该Ceph块设备,可以理解为往用户机上插入硬盘:rbdmap myrbd # 输出: /dev/rbd1
将Ceph块设备格式化成文件系统并挂载:
mkfs.xfs /dev/rbd1
mkdir -p /mnt/ceph_rbd
mount /dev/rbd1 /mnt/ceph_rbd
通过/mnt/ceph_rbd读写数据,都是在读写Ceph集群中该块设备对应的存储区域。总结一下,块设备可理解成一块硬盘,用户可以将其格式化成特定的文件系统,由文件系统来组织管理存储空间,从而为用户提供丰富而友好的数据操作支持。
三、文件系统存储
用户可以在块设备上创建xfs文件系统,也可以创建ext4等其他文件系统。Ceph集群实现了自己的文件系统来组织管理集群的存储空间,用户可以直接将Ceph集群的文件系统挂载到用户机上使用。下图为ceph三种存储的对比:
Ceph有了块设备接口,在块设备上完全可以构建一个文件系统,那么Ceph为什么还需要文件系统接口呢?主要是因为应用场景的不同,Ceph的块设备具有优异的读写性能,但不能多处挂载同时读写,目前主要用在OpenStack上作为虚拟磁盘Ceph的文件系统接口读写性能较块设备接口差,但具有优异的共享性。
为什么Ceph的块设备接口不具有共享性,而Ceph的文件系统接口具有呢?对于Ceph的块设备接口,如下图, 文件系统的结构状态是维护在各用户机内存中的。假设Ceph块设备同时挂载到了用户机1和用户机2,当在用户机1上写入数据后,更新了用户机1的内存中文件系统状态,最终数据存储到了Ceph集群中。但此时用户机2内存中的文件系统并不能得知底层Ceph集群数据已经变化而维持数据结构不变,因此用户无法从用户机2上读取用户机1上新写入的数据。
对于Ceph的文件系统接口,如下图,文件系统的结构状态是维护在远端Ceph集群中的Ceph文件系统同时挂载到了用户机1和用户机2,当往用户机1的挂载点写入数据后,远端Ceph集群中的文件系统状态结构随之更新,当从用户机2的挂载点访问数据时会去远端Ceph集群取数据,由于远端Ceph集群已更新,所有用户机2能够获取最新的数据。
总结一下,Ceph的文件系统接口弥补了Ceph的块设备接口在共享性方面的不足,Ceph的文件系统接口符合POSIX标准,用户可以像使用本地存储目录一样使用Ceph的文件系统的挂载目录。
四、对象存储
首先,通过下图来看下对象存储接口是怎么用的,简单了说,使用方式就是通过http协议上传下载删除对象(文件即对象)。
有了块设备接口存储和文件系统接口存储,为什么还整个对象存储呢?往简单了说,Ceph的块设备存储具有优异的存储性能但不具有共享性,而Ceph的文件系统具有共享性然而性能较块设备存储差
为什么不权衡一下存储性能和共享性,整个具有共享性而存储性能好于文件系统存储的存储呢? 对象存储就这样出现了。
对象存储为什么性能会比文件系统好?原因是多方面的,主要原因是对象存储组织数据的方式相对简单,只有bucket和对象两个层次(对象存储在bucket中),对对象的操作也相对简单。而文件系统存储具有复杂的数据组织方式,目录和文件层次可具有无限深度,对目录和文件的操作也复杂的多,因此文件系统存储在维护文件系统的结构数据时会更加繁杂,从而导致文件系统的存储性能偏低。
存储空间(Bucket)所谓的桶存储空间是用于存储对象(Object)的容器,所有的对象都必须隶属于某个存储空间。可以设置和修改存储空间属性用来控制地域、访问权限、生命周期等,这些属性设置直接作用于该存储空间内所有对象可以通过灵活创建不同的存储空间来完成不同的管理功能。
同一个存储空间的内部是扁平的,没有文件系统的目录等概念,所有的对象都直接隶属于其对应的存储空间。每个用户可以拥有多个存储空间,存储空间的名称在 OSS 范围内必须是全局唯一的,一旦创建之后无法修改名称。存储空间内部的对象数目没有限制。
存储空间的命名规范如下:
只能包括小写字母、数字和短横线(-)。
必须以小写字母或者数字开头和结尾。
长度必须在3-63字节之间
Ceph的对象存储接口怎么用呢?Ceph的对象接口符合亚马逊S3接口标准和OpenStack的Swift接口标准,可以自行学习这两种接口。
总结一下,文件系统存储具有复杂的数据组织结构,能够提供给用户更加丰富的数据操作接口,而对象存储精简了数据组织结构,提供给用户有限的数据操作接口,以换取更好的存储性能。对象接口提供了REST API,非常适用于作为web应用的存储。