Ceph分布式存储
存储根据其类型,可分为块存储,对象存储和文件存储。在主流的分布式存储技术中,HDFS/GPFS/GFS属于文件存储,Swift属于对象存储,而Ceph可支持块存储、对象存储和文件存储,故称为统一存储。
1,Ceph概念
Ceph是一种为优秀的性能、可靠性和可扩展性而设计的统一的、分布式文件系统。ceph 的统一体现在可以提供文件系统、块存储和对象存储,分布式体现在可以动态扩展。
什么是块存储/对象存储/文件系统存储?
1)对象存储:
也就是通常意义的键值存储,其接口就是简单的GET、PUT、DEL 和其他扩展,代表主要有 Swift 、S3 以及 Gluster 等;
2)块存储:
这种接口通常以 QEMU Driver 或者 Kernel Module 的方式存在,这种接口需要实现 Linux 的 Block Device 的接口或者 QEMU 提供的 Block Driver 接口,如 Sheepdog,AWS 的 EBS,青云的云硬盘和阿里云的盘古系统,还有 Ceph 的 RBD(RBD是Ceph面向块存储的接口)。在常见的存储中 DAS、SAN 提供的也是块存储;
3)文件系统存储:
通常意义是支持 POSIX 接口,它跟传统的文件系统如 Ext4 是一个类型的,但区别在于分布式存储提供了并行化的能力,如 Ceph 的 CephFS (CephFS是Ceph面向文件存储的接口),但是有时候又会把 GlusterFS ,HDFS 这种非POSIX接口的类文件存储接口归入此类。当然 NFS、NAS也是属于文件系统存储;
特点:
<1> Ceph支持对象存储、块存储和文件存储服务,故称为统一存储。
<2> 采用CRUSH算法,数据分布均衡,并行度高,不需要维护固定的元数据结构;
<3> 数据具有强一致,确保所有副本写入完成才返回确认,适合读多写少场景;
<4> 去中心化,MDS之间地位相同,无固定的中心节点
Ceph存在一些缺点
<1> 去中心化的分布式解决方案,需要提前做好规划设计,对技术团队的要求能力比较高。
<2> Ceph扩容时,由于其数据分布均衡的特性,会导致整个存储系统性能的下降。
Ceph相比于其他存储方案的优势
(1)高性能:
a. 摒弃了传统的集中式存储元数据寻址的方案,采用CRUSH算法,数据分布均衡,并行度高。
b.考虑了容灾域的隔离,能够实现各类负载的副本放置规则,例如跨机房、机架感知等。
c. 能够支持上千个存储节点的规模,支持TB到PB级的数据。
(2)高可用性:
a. 副本数可以灵活控制。
b. 支持故障域分隔,数据强一致性。
c. 多种故障场景自动进行修复自愈。
d. 没有单点故障,自动管理。
(3)高可扩展性:
a. 去中心化。
b. 扩展灵活。
c. 随着节点增加而线性增长。
(4)特性丰富:
a. 支持三种存储接口:块存储、文件存储、对象存储。
b. 支持自定义接口,支持多种语言驱动。
(5)CRUSH算法:
a. CRUSH在一致性哈希基础上很好的考虑了容灾域的隔离
b.Crush算法有相当强大的扩展性,理论上支持数千个存储节点。
CRUSH算法:
CRUSH算法是根据存储设备的权重来计算数据对象的分布的,权重的设计可以根据该磁盘的容量和读写速度来设置,比如根据容量大小可以将1T的硬盘设备权重设为1,2T的就设为2,在计算过程中,CRUSH是根据Cluster Map、数据分布策略和一个随机数共同决定数组最终的存储位置的。
Cluster Map里的内容信息包括存储集群中可用的存储资源及其相互之间的空间层次关系,比如集群中有多少个支架,每个支架中有多少个服务器,每个服务器有多少块磁盘用以OSD等。
数据分布策略是指可以通过Ceph管理者通过配置信息指定数据分布的一些特点,比如管理者配置的故障域是Host,也就意味着当有一台Host起不来时,数据能够不丢失,CRUSH可以通过将每个pg的主从副本分别存放在不同Host的OSD上即可达到,不单单可以指定Host,还可以指定机架等故障域,除了故障域,还有选择数据冗余的方式,比如副本数或纠删码。
2,Ceph组件
2.1,核心组件
(1)RADOS:Reliable Autonomic Distributed Object Store。RADOS是ceph存储集群的基础
。在ceph中,所有数据都以对象的形式存储,并且无论什么数据类型,RADOS对象存储都将负责保存这些对象。RADOS层可以确保数据始终保持一致。自身是一个完整的分布式对象存储系统
。主要由两部分组成,分别是OSD和Monitor。
(2)Monitors:监视器,维护集群状态的多种映射,同时提供认证和日志记录服务,包括有关monitor 节点端到端的信息,其中包括 Ceph 集群ID,监控主机名和IP以及端口。并且存储当前版本信息以及最新更改信息,通过 "ceph mon dump"查看 monitor map。
(3)MDS(Metadata Server):Ceph 元数据,主要保存的是Ceph文件系统的元数据。注意:ceph的块存储和ceph对象存储都不需要MDS。
(4)OSD:即对象存储守护程序,但是它并非针对对象存储。是物理磁盘驱动器,将数据以对象的形式存储到集群中的每个节点的物理磁盘上。OSD负责存储数据、处理数据复制、恢复、回填(Backfilling)、再平衡。完成存储数据的工作绝大多数是由 OSD daemon 进程实现。在构建 Ceph OSD的时候,建议采用SSD 磁盘以及xfs文件系统来格式化分区。此外OSD还对其它OSD进行心跳检测,检测结果汇报给Monitor。一般情况下一块硬盘对应一个OSD,由OSD来对硬盘存储进行管理,当然一个分区也可以成为一个OSD。
(5)librados:librados库,为应用程度提供访问接口。同时也为块存储、对象存储、文件系统提供原生的接口。
(6)RADOSGW:网关接口,提供对象存储服务。它使用librgw和librados来实现允许应用程序与Ceph对象存储建立连接。并且提供S3 和 Swift(openstack) 兼容的RESTful API接口。
(7)RBD:块设备,它能够自动精简配置并可调整大小,而且将数据分散存储在多个OSD上。
(8)CephFS:Ceph文件系统,与POSIX兼容的文件系统,基于librados封装原生接口。
2.2,Ceph存储系统的逻辑层次结构
2.3,RADOS的系统逻辑结构
通过在每个存储节点存储完整的Cluster map,存储设备可以表现的半自动化,通过peer-to-peer的方式(比如定义协议)来进行数据备份、更新,错误检测、数据迁移等等操作。这无疑减轻了占少数的monitor cluster(管理节点组成的集群)的负担。
一个RADOS系统包含大量的OSDs 和 很少的用于管理OSD集群成员的monitors。OSD存储服务:主要功能是存储数据、复制数据、平衡数据、恢复数据,以及与其它OSD间进行心跳检查等。一般情况下一块硬盘对应一个OSD。而monitor是一些独立的进程,以及少量的本地存储,monitor之间通过一致性算法保证数据的一致性。
Cluster Map
存储节点集群通过monitor集群操作cluster map来实现成员的管理。cluster map 描述了哪些OSD被包含进存储集群以及所有数据在存储集群中的分布。cluster map不仅存储在monitor节点,它被复制到集群中的每一个存储节点,以及和集群交互的client。当因为一些原因,比如设备崩溃、数据迁移等,cluster map的内容需要改变时,cluster map的版本号被增加,map的版本号可以使通信的双方确认自己的map是否是最新的,版本旧的一方会先将map更新成对方的map,然后才会进行后续操作。
Data Placement
下面总体说下RADOS的存储层次,RADOS中基本的存储单位是对象,一般为2MB或4MB,当一个文件要存入RADOS时,首先会被切分成大小固定的对象(最后一个对象大小可能不同),然后将对象分配到一个PG(Placement Group)中,然后PG会复制几份,伪随机地派给不同的存储节点。当新的存储节点被加入集群,会在已有数据中随机抽取一部分数据迁移到新节点。这种概率平衡的分布方式可以保证设备在潜在的高负载下正常工作。更重要的是,数据的分布过程仅需要做几次随机映射,不需要大型的集中式分配表。
3,Ceph数据存储过程
无论使用哪种存储方式(对象、块、文件系统),存储的数据都会被切分成Objects。Objects size大小可以由管理员调整,通常为2M或4M。每个对象都会有一个唯一的OID,由ino与ono生成。
ino:即是文件的File ID,用于在全局唯一标识每一个文件
ono:则是分片的编号
File —— 此处的file就是用户需要存储或者访问的文件。
Ojbect —— 此处的object是RADOS所看到的“对象”。
PG(Placement Group)—— 顾名思义,PG的用途是对object的存储进行组织和位置映射。
OSD —— 即object storage device。
Ceph中的寻址至少要经历以下三次映射:
(1)File -> object映射
(2)Object -> PG映射,hash(oid) & mask -> pgid
(3)PG -> OSD映射,CRUSH算法
pool:是ceph存储数据时的逻辑分区,它起到namespace的作用。每个pool包含一定数量(可配置) 的PG。PG里的对象被映射到不同的Object上。pool是分布到整个集群的。 pool可以做故障隔离域,根据不同的用户场景不统一进行隔离。
(1)PG是指定存储池存储对象的目录有多少个,PGP是存储池PG的OSD分布组合个数
(2)PG的增加会引起PG内的数据进行分裂,分裂相同的OSD上新生成的PG当中
(3)PGP的增加会引起部分PG的分布进行变化,但是不会引起PG内对象的变动
RADOS 分布式存储相较于传统分布式存储的优势在于:
1)将文件映射到object后,利用Cluster Map 通过CRUSH 计算而不是查找表方式定位文件数据存储到存储设备的具体位置。优化了传统文件到块的映射和Block MAp的管理。
2)RADOS充分利用OSD的智能特点,将部分任务授权给OSD,最大程度地实现可扩展。
4,Ceph IO流程
1、正常IO流程
步骤:
1)client 创建cluster handler。
2)client 读取配置文件。
3)client 连接上monitor,获取集群map信息。
4)client 读写io 根据crshmap 算法请求对应的主osd数据节点。
5)主osd数据节点同时写入另外两个副本节点数据。
6)等待主节点以及另外两个副本节点写完数据状态。
7)主节点及副本节点写入状态都成功后,返回给client,io写入完成。
2、新主IO流程
新主IO流程步骤:
1)client连接monitor获取集群map信息。
2)同时新主osd1由于没有pg数据会主动上报monitor告知让osd2临时接替为主。
3)临时主osd2会把数据全量同步给新主osd1。
4)client IO读写直接连接临时主osd2进行读写。
5)osd2收到读写io,同时写入另外两副本节点。
6)等待osd2以及另外两副本写入成功。
7)osd2三份数据都写入成功返回给client, 此时client io读写完毕。
8)如果osd1数据同步完毕,临时主osd2会交出主角色。
9)osd1成为主节点,osd2变成副本。
Ceph Pool和PG分布情况:
pool:是ceph存储数据时的逻辑分区,它起到namespace的作用。每个pool包含一定数量(可配置) 的PG。PG里的对象被映射到不同的Object上。pool是分布到整个集群的。 pool可以做故障隔离域,根据不同的用户场景不统一进行隔离。
5,ceph命令
1、检测ceph集群状态:
ceph -s
2、查看ceph集群配置信息
ceph daemon /var/run/ceph/ceph-mon.$(hostname -s).asok config show
3、在部署节点修改了ceph.conf文件,将新配置推送至全部的ceph节点
ceph-deploy --overwrite-conf config push dlp node1 node2 node3
4、检查仲裁状态,查看mon添加是否成功
ceph quorum_status --format json-pretty
5、查看osd状态:
ceph osd tree
6、列式pool列表
ceph osd lspools
7、创建pool
ceph osd pool create vms 1024
8、删除pool
ceph osd pool delete data #会提示确认信息(增加命令,如下)
ceph osd pool delete data data --yes-i-really-really-mean-it
9、列示pool详细信息
ceph osd dump | grep pool
10、检查pool的副本数
ceph osd dump|grep -i size
11、设置pool副本数
ceph osd pool get data size
ceph osd pool set data size 3
12、设置pool配额
ceph osd pool set-quota data max_objects 100 #最大100个对象
ceph osd pool set-quota data max_bytes $((10 * 1024 * 1024 * 1024)) #容量大小最大为10G
13、重命名pool
ceph osd pool rename data date
14、PG, Placement Groups。CRUSH先将数据分解成一组对象,然后根据对象名称、复制级别和系统中的PG数等信息执行散列操作,再将结果生成PG ID。可以将PG看做一个逻辑容器,这个容器包含多个对 象,同时这个逻辑对象映射之多个OSD上。如果没有PG,在成千上万个OSD上管理和跟踪数百万计的对象的复制和传播是相当困难的。没有PG这一层,管理海量的对象所消耗的计算资源也是不可想象的。建议每个OSD上配置50~100个PG。
ceph集群中的PG总数:
PG总数 = (OSD总数 * 100) / 最大副本数 ##结果必须舍入到最接近的2的N次方幂的值
ceph集群中每个pool中的PG总数:
存储池PG总数 = (OSD总数 * 100 / 最大副本数) / 池数
获取现有的PG数和PGP数值:
ceph osd pool get data pg_num
ceph osd pool get data pgp_num
6,ceph对接openstack环境
1、客户端要有cent用户(ceph的专有用户)
useradd cent && echo "123" | passwd --stdin cent
echo -e 'Defaults:cent !requiretty\ncent ALL = (root) NOPASSWD:ALL' | tee/etc/sudoers.d/ceph
chmod 440 /etc/sudoers.d/ceph
2、openstack部署ceph(安装软件包)
yum install python-rbd
yum install ceph-common
3、在ceph部署节点上为openstack节点安装ceph
ceph-deploy install controller
ceph-deploy admin controller
4、在openstack客户端执行授予权限的命令
sudo chmod 644 /etc/ceph/ceph.client.admin.keyring
5、在一个ceph节点上创建pool
ceph osd pool create images 1024
ceph osd pool create vms 1024
ceph osd pool create volumes 1024
ceph osd lspools
6、在ceph集群中创建glance和cinder用户,只需在一个ceph节点上操作即可
ceph auth get-or-create client.glance mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=images'
ceph auth get-or-create client.cinder mon 'allow r' osd 'allow class-read object_prefix rbd_children, allow rwx pool=volumes, allow rwx pool=vms, allow rx pool=images'
nova使用cinder用户,就不单独创建了
7、拷贝ceph-ring, 只需在一个ceph节点上操作即可:
ceph auth get-or-create client.glance > /etc/ceph/ceph.client.glance.keyring
ceph auth get-or-create client.cinder > /etc/ceph/ceph.client.cinder.keyring
8、更改文件的权限(所有客户端节点均执行)
chown glance:glance /etc/ceph/ceph.client.glance.keyring
chown cinder:cinder /etc/ceph/ceph.client.cinder.keyring
9、更改libvirt权限(只需在nova-compute节点上操作即可,每个计算节点都做)
uuidgen
940f0485-e206-4b49-b878-dcd0cb9c70a4
在/etc/ceph/目录下
cat > secret.xml <<EOF
<secret ephemeral='no' private='no'>
<uuid>940f0485-e206-4b49-b878-dcd0cb9c70a4</uuid>
<usage type='ceph'>
<name>client.cinder secret</name>
</usage>
</secret>
EOF
将 secret.xml 拷贝到所有compute节点,并执行:
virsh secret-define --file secret.xml
ceph auth get-key client.cinder > ./client.cinder.key
virsh secret-set-value --secret 940f0485-e206-4b49-b878-dcd0cb9c70a4 --base64 $(cat ./client.cinder.key)
10、配置Glance, 在所有的controller节点上做如下更改:
vim /etc/glance/glance-api.conf
[DEFAULT]
default_store = rbd
[glance_store]
stores = rbd
default_store = rbd
rbd_store_pool = images
rbd_store_user = glance
rbd_store_ceph_conf = /etc/ceph/ceph.conf
rbd_store_chunk_size = 8
systemctl restart openstack-glance-api.service
创建image验证:
openstack image create "cirros" --file cirros-0.3.3-x86_64-disk.img.img --disk-format qcow2 --container-format bare --public
rbd ls images #有输出镜像说明成功了
11、配置cinder(/etc/cinder/cinder``.conf
)
[DEFAULT]
enabled_backends = lvm,ceph
[ceph]
volume_driver = cinder.volume.drivers.rbd.RBDDriver
rbd_pool = volumes
rbd_ceph_conf = /etc/ceph/ceph.conf
rbd_flatten_volume_from_snapshot = false
rbd_max_clone_depth = 5
rbd_store_chunk_size = 4
rados_connect_timeout = -1
glance_api_version = 2
rbd_user = cinder
rbd_secret_uuid = 940f0485-e206-4b49-b878-dcd0cb9c70a4
volume_backend_name=ceph
systemctl restart openstack-cinder-api.service openstack-cinder-scheduler.service openstack-cinder-volume.service
rbd ls volumes
12、配置nova(/etc/nova/nova``.conf
)
[libvirt]
virt_type=qemu
images_type = rbd
images_rbd_pool = vms
images_rbd_ceph_conf = /etc/ceph/ceph.conf
rbd_user = cinder
rbd_secret_uuid = 940f0485-e206-4b49-b878-dcd0cb9c70a4
systemctl restart openstack-nova-api.service openstack-nova-consoleauth.service openstack-nova-scheduler.service openstack-nova-compute.service openstack-nova-cert.service
七、ceph添加/删除osd
1、添加osd
(1)选择一个osd节点,添加好新的硬盘:
(2)显示osd节点中的硬盘,并重置新的osd硬盘:
列出节点磁盘:ceph-deploy disk list rab1
擦净节点磁盘:ceph-deploy disk zap rab1 /dev/sbd(或者)ceph-deploy disk zap rab1:/dev/vdb1
(3)准备Object Storage Daemon:
ceph-deploy osd prepare rab1:/var/lib/ceph/osd1
(4)激活Object Storage Daemon:
ceph-deploy osd activate rab1:/var/lib/ceph/osd1
2、删除osd
(1)把 OSD 踢出集群
ceph osd out osd.4
(2)在相应的节点,停止ceph-osd服务
systemctl stop ceph-osd@4.service
systemctl disable ceph-osd@4.service
(3)删除 CRUSH 图的对应 OSD 条目,它就不再接收数据了
ceph osd crush remove osd.4
(4)删除 OSD 认证密钥
ceph auth del osd.4
(5)删除osd.4
ceph osd rm osd.4
3、故障硬盘更换
(1)关闭ceph集群数据迁移(osd硬盘故障,状态变为down)
for i in noout nobackfill norecover noscrub nodeep-scrub;do ceph osd set $i;done
(2)定位故障osd
ceph osd tree | grep -i down
(3)进入osd故障的节点,卸载osd挂载目录
umount /var/lib/ceph/osd/ceph-5
(4)从crush map 中移除osd
ceph osd crush remove osd.5
(5)删除故障osd的密钥
ceph auth del osd.5
(6)删除故障osd
ceph osd rm 5
(7)更换完新硬盘后,注意新硬盘的盘符,并创建osd
(8)添加新的osd(cent用户)
ceph-deploy osd create --data /dev/sdd node3
(9)待新osd添加crush map后,重新开启集群禁用标志
for i in noout nobackfill norecover noscrub nodeep-scrub;do ceph osd unset $i;done
ceph集群经过一段时间的数据迁移后,恢复active+clean状态
l
ceph osd tree | grep -i down
(3)进入osd故障的节点,卸载osd挂载目录
```shell
umount /var/lib/ceph/osd/ceph-5
(4)从crush map 中移除osd
ceph osd crush remove osd.5
(5)删除故障osd的密钥
ceph auth del osd.5
(6)删除故障osd
ceph osd rm 5
(7)更换完新硬盘后,注意新硬盘的盘符,并创建osd
(8)添加新的osd(cent用户)
ceph-deploy osd create --data /dev/sdd node3
(9)待新osd添加crush map后,重新开启集群禁用标志
for i in noout nobackfill norecover noscrub nodeep-scrub;do ceph osd unset $i;done
ceph集群经过一段时间的数据迁移后,恢复active+clean状态