Ceph 是一个统一的分布式存储系统,设计初衷是提供较好的性能、可靠性和可扩展性。
Ceph 项目最早起源于 Sage 就读博士期间的工作(最早的成果于 2004 年发表),并随后贡献给开源社区。在经过了数年的发展之后,目前已得到众多云计算厂商的支持并被广泛应用。RedHat 及 OpenStack 都可与 Ceph 整合以支持虚拟机镜像的后端存储。
支持三种接口:
Monitor
一个 Ceph 集群需要多个 Monitor 组成的小集群,它们通过 Paxos 同步数据,用来保存 OSD 的元数据。
OSD
OSD 全称 Object Storage Device,也就是负责响应客户端请求返回具体数据的进程。一个 Ceph 集群一般都有很多个 OSD。
MDS
MDS 全称 Ceph Metadata Server,是 CephFS 服务依赖的元数据服务。
Object
Ceph 最底层的存储单元是 Object 对象,每个 Object 包含元数据和原始数据。
PG
PG 全称 Placement Grouops,是一个逻辑的概念,一个 PG 包含多个 OSD。引入 PG 这一层其实是为了更好的分配数据和定位数据。
RADOS
RADOS 全称 Reliable Autonomic Distributed Object Store,是 Ceph 集群的精华,用户实现数据分配、Failover 等集群操作。
Libradio
Librados 是 Rados 提供库,因为 RADOS 是协议很难直接访问,因此上层的 RBD、RGW 和 CephFS 都是通过 librados 访问的,目前提供 PHP、Ruby、Java、Python、C 和 C++ 支持。
CRUSH
CRUSH 是 Ceph 使用的数据分布算法,类似一致性哈希,让数据分配到预期的地方。
RBD
RBD 全称 RADOS block device,是 Ceph 对外提供的块设备服务。
RGW
RGW 全称 RADOS gateway,是 Ceph 对外提供的对象存储服务,接口与 S3 和 Swift 兼容。
CephFS
CephFS 全称 Ceph File System,是 Ceph 对外提供的文件系统服务。
主要是将裸磁盘空间映射给主机使用的。
优点:
缺点:
使用场景:
典型设备: FTP、NFS 服务器
为了克服块存储文件无法共享的问题,所以有了文件存储。
在服务器上架设 FTP 与 NFS 服务,就是文件存储。
优点:
缺点:
使用场景:
典型设备: 内置大容量硬盘的分布式服务器 (swift, s3)
多台服务器内置大容量硬盘,安装上对象存储管理软件,对外提供读写访问功能。
优点:
使用场景: (适合更新变动较少的数据)
说明:
如果新加入的 OSD1 取代了原有的 OSD4 成为 Primary OSD, 由于 OSD1 上未创建 PG , 不存在数据,那么 PG 上的 I/O 无法进行,怎样工作的呢?
File 用户需要读写的文件。File->Object 映射:
Object 是 RADOS 需要的对象。Ceph 指定一个静态 hash 函数计算 oid 的值,将 oid 映射成一个近似均匀分布的伪随机值,然后和 mask 按位相与,得到 pgid。Object->PG 映射:
PG (Placement Group), 用途是对 object 的存储进行组织和位置映射,(类似于 redis cluster 里面的 slot 的概念) 一个 PG 里面会有很多 object。采用 CRUSH 算法,将 pgid 代入其中,然后得到一组 OSD。PG->OSD 映射:
locator = object_name
obj_hash = hash(locator)
pg = obj_hash % num_pg
osds_for_pg = crush(pg) # returns a list of osds
primary = osds_for_pg[0]
replicas = osds_for_pg[1:]
场景数据迁移流程:
现状:
ceph_io_recry2.png
说明
每个 OSD 上分布很多 PG, 并且每个 PG 会自动散落在不同的 OSD 上。如果扩容那么相应的 PG 会进行迁移到新的 OSD 上,保证 PG 数量的均衡。
心跳是用于节点间检测对方是否故障的,以便及时发现故障节点进入相应的故障处理流程。
问题:
故障检测策略应该能够做到:
OSD 节点会监听 public、cluster、front 和 back 四个端口
Ceph 通过伙伴 OSD 汇报失效节点和 Monitor 统计来自 OSD 的心跳两种方式判定 OSD 节点失效。
网络通信框架三种不同的实现方式:
设计模式 (Subscribe/Publish)
订阅发布模式又名观察者模式,它意图是 “定义对象间的一种一对多的依赖关系,
当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新”。
ceph_message_3.png
通信协议格式需要双方约定数据格式。
消息的内容主要分为三部分:
class Message : public RefCountedObject {
protected:
ceph_msg_header header; // 消息头
ceph_msg_footer footer; // 消息尾
bufferlist payload; // "front" unaligned blob
bufferlist middle; // "middle" unaligned blob
bufferlist data; // data payload (page-alignment will be preserved where possible)
/* recv_stamp is set when the Messenger starts reading the
* Message off the wire */
utime_t recv_stamp; //开始接收数据的时间戳
/* dispatch_stamp is set when the Messenger starts calling dispatch() on
* its endpoints */
utime_t dispatch_stamp; //dispatch 的时间戳
/* throttle_stamp is the point at which we got throttle */
utime_t throttle_stamp; //获取throttle 的slot的时间戳
/* time at which message was fully read */
utime_t recv_complete_stamp; //接收完成的时间戳
ConnectionRef connection; //网络连接
uint32_t magic = 0; //消息的魔术字
bi::list_member_hook<> dispatch_q; //boost::intrusive 成员字段
};
struct ceph_msg_header {
__le64 seq; // 当前session内 消息的唯一 序号
__le64 tid; // 消息的全局唯一的 id
__le16 type; // 消息类型
__le16 priority; // 优先级
__le16 version; // 版本号
__le32 front_len; // payload 的长度
__le32 middle_len;// middle 的长度
__le32 data_len; // data 的 长度
__le16 data_off; // 对象的数据偏移量
struct ceph_entity_name src; //消息源
/* oldest code we think can decode this. unknown if zero. */
__le16 compat_version;
__le16 reserved;
__le32 crc; /* header crc32c */
} __attribute__ ((packed));
struct ceph_msg_footer {
__le32 front_crc, middle_crc, data_crc; //crc校验码
__le64 sig; //消息的64位signature
__u8 flags; //结束标志
} __attribute__ ((packed));
CRUSH 算法的全称为:Controlled Scalable Decentralized Placement of Replicated Data,可控的、可扩展的、分布式的副本数据放置算法。
PG 到 OSD 的映射的过程算法叫做 CRUSH 算法。(一个 Object 需要保存三个副本,也就是需要保存在三个 osd 上)。
CRUSH 算法是一个伪随机的过程,他可以从所有的 OSD 中,随机性选择一个 OSD 集合,但是同一个 PG 每次随机选择的结果是不变的,也就是映射的 OSD 集合是固定的。
CRUSH 算法因子:
层次化的 Cluster Map
反映了存储系统层级的物理拓扑结构。定义了 OSD 集群具有层级关系的 静态拓扑结构。OSD 层级使得 CRUSH 算法在选择 OSD 时实现了机架感知能力,也就是通过规则定义, 使得副本可以分布在不同的机 架、不同的机房中、提供数据的安全性 。
Placement Rules
决定了一个 PG 的对象副本如何选择的规则,通过这些可以自己设定规则,用户可以自定义设置副本在集群中的分布。
CRUSH Map 是一个树形结构,OSDMap 更多记录的是 OSDMap 的属性 (epoch/fsid/pool 信息以及 osd 的 ip 等等)。
叶子节点是 device(也就是 osd),其他的节点称为 bucket 节点,这些 bucket 都是虚构的节点,可以根据物理结构进行抽象,当然树形结构只有一个最终的根节点称之为 root 节点,中间虚拟的 bucket 节点可以是数据中心抽象、机房抽象、机架抽象、主机抽象等。
数据分布策略 Placement Rules 主要有特点:
rule replicated_ruleset #规则集的命名,创建pool时可以指定rule集
{
ruleset 0 #rules集的编号,顺序编即可
type replicated #定义pool类型为replicated(还有erasure模式)
min_size 1 #pool中最小指定的副本数量不能小1
max_size 10 #pool中最大指定的副本数量不能大于10
step take default #查找bucket入口点,一般是root类型的bucket
step chooseleaf firstn 0 type host #选择一个host,并递归选择叶子节点osd
step emit #结束
}
一般的 buckets:适合所有子节点权重相同,而且很少添加删除 item。
list buckets:适用于集群扩展类型。增加 item,产生最优的数据移动,查找 item,时间复杂度 O (n)。
tree buckets:查找负责度是 O (log n), 添加删除叶子节点时,其他节点 node_id 不变。
straw buckets:允许所有项通过类似抽签的方式来与其他项公平 “竞争”。定位副本时,bucket 中的每一项都对应一个随机长度的 straw,且拥有最长长度的 straw 会获得胜利(被选中),添加或者重新计算,子树之间的数据移动提供最优的解决方案。
说明:
集群中有部分 sas 和 ssd 磁盘,现在有个业务线性能及可用性优先级高于其他业务线,能否让这个高优业务线的数据都存放在 ssd 磁盘上。
普通用户:
高优用户:
配置规则:
QoS (Quality of Service,服务质量)起源于网络技术,它用来解决网络延迟和阻塞等问题,能够为指定的网络通信提供更好的服务能力。
问题:
我们总的 Ceph 集群的 iIO 能力是有限的,比如带宽,IOPS。如何避免用户争取资源,如果保证集群所有用户资源的高可用性,以及如何保证高优用户资源的可用性。所以我们需要把有限的 IO 能力合理分配。
ClientOp:来自客户端的读写 I/O 请求。
SubOp:osd 之间的 I/O 请求。主要包括由客户端 I/O 产生的副本间数据读写请求,以及由数据同步、数据扫描、负载均衡等引起的 I/O 请求。
SnapTrim:快照数据删除。从客户端发送快照删除命令后,删除相关元数据便直接返回,之后由后台线程删除真实的快照数据。通过控制 snaptrim 的速率间接控制删除速率。
Scrub:用于发现对象的静默数据错误,扫描元数据的 Scrub 和对象整体扫描的 deep Scrub。
Recovery:数据恢复和迁移。集群扩 / 缩容、osd 失效 / 从新加入等过程。
mClock 是一种基于时间标签的 I/O 调度算法,最先被 Vmware 提出来的用于集中式管理的存储系统。(目前官方 QOS 模块属于半成品)。
基本思想:
基于令牌桶算法 (TokenBucket) 实现了一套简单有效的 qos 功能,满足了云平台用户的核心需求。
基本思想:
步骤:
现有框架图:
令牌图算法框架图:
转自:https://www.jianshu.com/p/cc3ece850433