王豪迈
作者王豪迈·2017-02-07 17:50
CTO·星辰天合(XSKY)

解析Ceph: Librbd–块存储库

字数 1794阅读 3355评论 0赞 2

Librbd 是Ceph的块存储库,其利用Rados提供的API实现对卷的管理和操作。就目前而言,在Ceph支持的三种接口Posix(CephFS),块存储(Librbd)和对象存储(RadosGW)接口中,块存储是目前最稳定且达到生产环境要求的接口。

这篇文章主要分析Librbd如何利用Rados API实现块存储管理要求。

使用场景

使用Ceph的块存储有两种路径,一种是利用QEMU走librbd路径,另一种是使用kernel module,走kernel的路径。前种主要为虚拟机提供块存储设备,后者主要为Host提供块设备支持,两种途径的接口实现不完全相同。就目前来说,前者是目前更稳定的途径,也是Ceph所有应用场景中最广泛使用的。(PS: 强烈不推荐使用kernel module)

基本数据结构和概念

下面主要介绍Librbd中一些重要的概念,可能与其他环境下的意义不太相同。

Image: 对应于LVM的Logical Volume,是能被attach/detach到VM的载体。在RBD中,Image的数据有多个Object组成。

Snapshot: Image的某一个特定时刻的状态,只能读不能写但是可以将Image回滚到某一个Snapshot状态。Snapshot必定属于某一个Image。

Clone: 为Image的某一个Snapshot的状态复制变成一个Image。如ImageA有一个Snapshot-1,clone是根据ImageA的Snapshot-1克隆得到ImageB。ImageB此时的状态与Snapshot-1完全一致,区别在于ImageB此时可写,并且拥有Image的相应能力。

主要API实现

创建卷: 使用Rados API创建一个Header Object,将这个卷的元数据如id, size, snaps, name, seq等信息写入。然后将自身(id)注册到一个”RBD_DIRECTORY”的Object里。
创建快照: 发送一个请求到Monitor得到一个snap_seq,然后同时将一个快照的元信息如name,features, size,parent作为一个Snap Context存到之前创建的Image Header Object里。更多的快照实现细节参见解析Ceph: Snapshot

克隆卷: 克隆卷需要指定来源卷和特定快照,首先获取源卷的信息,也就是通过之前创建的Header Object得到。然后同样创建一个新的Header Object,存入与来源卷一样的元信息并且指定parent为来源卷。最后将[source_pool, source_image, source_snap_id]->[c_image_id, c2_image_id, …]存入一个RBD_CHILDREN的对象。这个关系主要用来快速查找和确认父子关系。

快照回滚: 在创建快照之后可以在任意时刻回滚到之前快照状态,首先从该快照所属的Image获取信息,然后对该Image下的所有Object回滚到之前快照的数据。这个回滚object的操作主要是删除最新的object,然后clone之前snapshot object为最新的object。

写入数据: 通常卷被QEMU或者Kernel driver管理,因此卷元信息会被一直持有,在写入数据时得到数据写入卷的offset, length,然后根据卷元信息得到这些数据分别归属的objects,可能会跨越多个。这样,一个op请求会转为多个object op分别发送到对应的OSD。如果该卷存在parent卷,也就是clone得到,那么如果这些数据对应的object为空,就会去parent卷的指定snapshot复制数据,然后将最新的数据覆写发送。

读取数据: 与写入数据的逻辑类似,读取请求也可能跨越多个object,或者存在parent卷。此外,在新的Ceph实现里,针对Snapshot或者父卷的读操作会偏向从最近的(本地)replcation读(当数据存在多个副本时),这类操作在Ceph端会认为是弱一致性读,应用端(librbd)必须保证这类读只发生在只读数据上(如snapshot数据),在lirbd需要打开两个选项才会启用平衡读(随机选择任意replication)和本地读(选择本地osd)。

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

2

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

相关资料

X社区推广