概述
ceph 本质上 就是一个 RADOS (
Reliable Automatic Distributed Object Storage
) 可靠的,自动的分布式 对象 存储。
Ceph 内部都是自动的实现 容错机制,基于 CRUSH 算法。当有一块磁盘坏了,会自动的进行 容错机制。
ceph 的特性
- 高效性 ceph 的 Replica 类似于 Raid,速度没有raid 快,但在合理的情况下,速度会无限接近 raid。
- 统一性 (表示支持三种类型的存储
文件存储
、块存储
、对象存储
) - 可扩展性 (数据不存放在库中,而是使用mash
视图
的一个概念,由cluster map
管理整个集群的状态)
其实感觉 Ceph 理念是 使用廉价的设备 部署一套 比较完善的存储集群
Ceph 架构
Ceph 底层是一个 RADOS,在此上层,提供一个 Librados 的库,用于 其他组件想使用下层的 rados,则需要调用 Librados 实现。
而对应的三种类型的存储,实现调用 Librados 的组件也不相同:
- 文件存储 使用的是
CephFS
组件,通过调用 Librados 实现访问 RADOS - 块存储 使用的是
librbd
组件,通过调用 Librados 实现访问 RADOS - 对象存储 使用的是
radosgw
组件,通过调用 Librados 实现访问 RADOS
如下图:
简述实际应用
实际场景中,如 OpenStack 私有云环境中,使用 Ceph (librbd
) 来提供整个集群的块存储。
这里有一个很重要的点,要明白 在 OpenStack 私有云环境中 是谁来使用这个块存储? 谁创建的?
本质上,是由 Nova
通过 libirtd
调用 qemu(硬件仿真,实现对CPU和内存很好的隔离)
驱动来创建一台 云主机(vm
),
之后 Cinder
通过 volume backend
调用 ceph集群的 librbd
驱动实现在 RADOS 中划分一个空间出来,就完成了磁盘创建,
然后把创建的磁盘挂载到 云主机(vm
) 中,此时在vm中对该磁盘存储数据,都是通过 qemu 向ceph集群的 librbd
发送一系列的请求。
那么可以大概行程下面的流程:
首先创建磁盘: cinder --> volumebackend --> librbd --> librados --> RADOS
创建云主机实现挂在动作流程: nova --> libvirtd --> qemu(vm) --> librbd --> librados --> RADOS
简述 Ceph 储存原理
这里大概讲述下ceph 的存储过程以及大致原理,细致的原理后续文章更新
OSD daemon
OSD 守护进程( Ceph OSD )的功能是存储数据,处理数据的
复制
、恢复
、回填
、再均衡
,并通过检查其他OSD 守护进程的心跳来向 Ceph Monitors 提供一些监控信息。
当 Ceph 存储集群设定为有3个副本时,至少需要3个 OSD 守护进程,集群才能达到 active+clean 状态( Ceph 默认有3个副本,可以调整副本数)。
OSD daemon
会监控自己所属的disk
是否正常,并且还会监控 相同组(PG)的其他 的OSD daemon
,并且默认间隔2秒会把状态向Monitor
汇报。
其实 OSD daemon
本质上就是一个管理进程,需要注意:
- 一块磁盘对应一个
OSD daemon
- 可以一块硬盘,分多个分区,每个分区对应一个
OSD daemon
- 也可以建立
Raid
后,这一个Raid
当成一个硬盘,来简历一个OSD daemon
也就是说一个OSD
守护进程只负责管理一块设备,最好的方案是 一块磁盘对应一个OSD daemon
,这样稳定性和性能能发挥到最大。
PG
PG (
Placement Group
) 是组的概念,是一个acting set
有序列表,官方管它叫归置组
,用于管理OSD daemon
,当 Ceph 存储集群设定为有3个副本时,那么每个 PG 组中,会管理三个OSD daemon
。
这里假设的副本数意思表示,一份数据在 Ceph 集群中,会保存三份,这样在一个PG 中,同时坏掉两块磁盘,数据也不会丢失。
在PG 组中,是一个有序列表,队列中的第一个位置,是组长
primary osd
,用于负责本组内的 读写工作,而剩下的两个 OSD 负责备份数据replicated osd
。
注意: PG
跟 OSD
的关系是多对多的关系,如下图:
一个PG
可以对应多个 OSD
,同样一个OSD
也可以对应多个PG
;PG 是通过 CRUSH 算法去发现 OSD
的;
Object
Ceph 存储的数据对象,这个
Object
其实就是数据源中的 Object,只是经过Librbd
这样组件进行处理后,给每个Object
增加了一个Object_id
的标识符。
在如 Ceph 块存储的 Librbd 中,如果有数据要写入时,该数据会被切割,可配置,最小为
4M
的大小。如 要写入一个10M
大小的a.txt
文件,则会被切割为 如 X、Y、Z 三个Object
,分别是 4M 4M 2M 的Object
,然后会被写入到 PG 中,由 PG中的 组长OSD 进行写入数据。至于 X、Y、Z 这三个Object
会被写入到哪一个PG中,则是由 CRUSH 决定,有可能会被写入到 同一个 PG 中,也有可能写入到不同的三个 PG 中。
小总结: 由上面的写入方式可以得出
- Object 与 PG 的关系是 多对一的关系,一个 Object 只能写入一个 PG ,多个 Object 也可以写入同一个 PG 中。
- Ceph 在大文件的支持会更好,而对于单个文件小于4M 的这样的小文件,性能会下降。
下面两个图中,分别表示数据的写入。
Monitor daemon
Ceph Monitor维护着展示集群状态的各种图表,包括监视器图、 OSD 图、归置组( PG )图、和 CRUSH 图。 Ceph 保存着发生在Monitors 、 OSD 和 PG上的每一次状态变更的历史信息(称为 epoch )。
Monitor 进程在每个节点上 只能启动一个,用于监控本节点的所有
Monitor daemon
是基于paxos
算法,是一种基于消息传递且具有高度容错特性的分布式事务一致性算法 来进行选主节点;
也是由于 pexos
算法 ,所以要保证 Monitor daemon
的个数为奇数;
整个集群的状态是由 cluster map
来监控的,也是所有的 Monitor daemon
共同算出来 cluster map
的一个映射关系。
映射关系包含:
Monitor map
:用于监控Monitor
自己的状态;OSD map
: 用于监控OSD daemon
的状态;PG map
: 监控PG
的状态;crush map
如有三个节点运行了 Monitor daemon
,那么就会有一个 leader
,其余两个可以叫 provider
;
两个 provider
的 Monitor
会通过通过 epoch
版本号的方式,来向 leader
同步 cluster map
的信息,并且会产生周期性的落后;
pool
pool
实际上就是一个 池 ,意思就是一个存储池;
这个存储池中,实际上就是一堆PG 的组合,然后给改组合起一个名字,那么就形成了存储池;
一个ceph集群可以有多个pool,每个pool是逻辑上的隔离单位,不同的pool可以有完全不一样的数据处理方式,比如Replica Size(副本数)、Placement Groups、CRUSH Rules、快照、所属者等。
可以大概理解为 LVM
中的 VG
的概念,VG
就是由一堆 PV
组成,然后把 VG
划分为分区提供给系统使用;
image
Image 可以理解为对应于 LVM 的 Logical Volume;
image 只是一个限制,如需要一个 200G 的磁盘,那么创建一个 image 空间要求200G,实际上就是给一个 200G 的边界,当写入数据总和大于200G时,就拒绝写入;
由此可以延伸,当磁盘需要扩展到500G的时候,实际上就是去扩展 image 的边界,允许写入数据达到500G;