Ceph中Snapshot的示例分析

65次阅读
没有评论

共计 3687 个字符,预计需要花费 10 分钟才能阅读完成。

丸趣 TV 小编给大家分享一下 Ceph 中 Snapshot 的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

解析 Ceph: Snapshot

Wang, Haomai | 2013.12.27

经常有开发者在邮件列表中会问到 Ceph Snapshot 的实现方式,受限于目前有限的实现文档和复杂的代码结构和代码量,弄清楚 Ceph Snapshot 并不是一件容易的事。正好最近在重构 Ceph 存储引擎层的 DBObjectMap,涉及到处理 Snapshot 间 clone 的问题,重新梳理了一次在 Ceph IO 路径中占了非常大比重的 snapshot 相关代码流程,在这里并不会重点展现里面的代码或者数据结构,而是从高层设计角度展现 Snapshot 的实现。

在阅读下文前务必先了解 Ceph 的基本情况和使用场景。Why Ceph and how to use Ceph?

Ceph Snapshot 使用场景

多数人尝试 Ceph 的 Snapshot 往往从 Ceph 的 RBD 库入手,也就是所谓的块存储。利用 librbd 通过简单的命令可以快速创建卷和 Snapshot。

rbd create image-name –size 1024 -p pool

rbd snap create pool/image-name –snap snap-name

第一条命令创建了一个名为”image-name”的卷,在这个过程中 librbd 库只是创建了一个 metadata 而没有实际向 Ceph 申请空间。关于 librbd 如何利用 Rados 实现块存储和管理更多的细节会在以后的文章中讲到,这里先留个坑。

第二条命令对”image-name”卷创建了一个名为”snap-name”的 Snapshot,创建以后,对”image-name”卷的任意写操作之后都可以在任意时间回滚到创建”snap-name”的 Snapshot 时的数据。如下面这条命令

rbd snap rollback pool/image-name –snap snap-name

在用户实际尝试过程中,会发现 Ceph 对于卷的操作和管理非常轻量,任意时刻,任意卷大小,任意集群大小的卷创建都是相同的操作量级,在其背后实质上也是完全相同的操作。开发者会对如何实现 Snapshot 更敢兴趣,因为 Snapshot 的实现方式决定了如何有效的使用 Snapshot。

Ceph Snapshot 实现

在阐述之前,首先要了解 Ceph 有 Pool 的概念,也就是上面命令上涉及到的 -p pool。一个 Ceph Cluster 可以创建多个 Pool,每个 Pool 是逻辑上的隔离单位,不同的 Pool 可以有完全不同的数据处理方式。如 Replication Size(副本数),Placement Groups(PG),CRUSH Rules,Snapshots,Ownership 都是利用 Pool 进行隔离的。

因此,对 Ceph 的任意操作都需要先指定 Pool 才能进行,上面的 image 操作都是在一个名为”pool”的 Pool 上进行,名为”image-name”的 Image 也是存储在”pool”中。

除了 Pool 概念外,Ceph 实质上有两种 Snapshot 模式,并且两种 Snapshot 是不能同时应用到同一个 Pool 中。

Pool Snapshot: 对整个 Pool 打一个 Snapshot,该 Pool 中所有的对象都会受影响

Self Managed Snapshot: 用户管理的 Snapshot,简单的理解就是这个 Pool 受影响的对象是受用户控制的。这里的用户往往是应用如 librbd。

我们在前面利用 rbd 命令的操作实质上是使用第二种模式,因此我们先首先介绍第二种模式的实现。

在前面提到,Snapshot 也是利用 Pool 隔离的,两种 Snapshot mode 的实现是基本相似的,如何使用是造成两种模式分离的重要原因。每个 Pool 都有一个 snap_seq 字段,该字段可以认为是整个 Pool 的 Global Version。所有存储在 Ceph 的 Object 也都带有 snap_seq,而每个 Object 会有一个 Head 版本的,也可能会存在一组 Snapshot objects,不管是 Head 版本还是 snapshot object 都会带有 snap_seq,那么接下来我们看 librbd 是如何利用该字段创建 Snapshot 的。

用户申请为”pool”中的”image-name”创建一个名为”snap-name”的 Snapshot

librbd 向 Ceph Monitor 申请得到一个”pool”的 snap sequence,Ceph Monitor 会递增该 Pool 的 snap_seq,然后返回该值给 librbd。

librbd 将新的 snap_seq 替换原来 image 的 snap_seq 中,并且将原来的 snap_seq 设置为用户创建的名为”snap-name”的 Snapshot 的 snap_seq

从上面的操作中,对于版本控制实现熟悉的同学们可能就大致猜测出 Ceph 对于 Snapshot 的实现了。每个 Snapshot 都掌握者一个 snap_seq,Image 可以看成一个 Head Version 的 Snapshot,每次 IO 操作对会带上 snap_seq 发送给 Ceph OSD,Ceph OSD 会查询该 IO 操作涉及的 object 的 snap_seq 情况。如”object-1″是”image-name”中的一个数据对象,那么初始的 snap_seq 就”image-name”的 snap_seq,当创建一个 Snapshot 以后,再次对”object-1″进行写操作时会带上新的 snap_seq,Ceph 接到请求后会先检查”object-1″的 Head Version,会发现该写操作所带有的 snap_seq 大于”object-1″的 snap_seq,那么就会对原来的”object-1″克隆一个新的 Object Head Version,原来的”object-1″会作为 Snapshot,新的 Object Head 会带上新的 snap_seq,也就是 librbd 之前申请到的。

Ceph 的实现当然比上面提到的要复杂很多,要考虑更多的异常情况还有管理 Object Snaps 上。

上述提到的是第二种 Snapshot Mode,那么第一种模式实际上更简单。既然第二种方式是应用 (librbd) 自己申请 snap_seq,然后进行管理,那么第一种是的场景可以是命令如”rados mksnap snap-name -p pool”进行全局 pool 的 Snapshot,应用是不需要知道 snap_seq 的。这条命令会递增”pool”的 snap_seq,然后接下来所有”pool”下的 objects 对会受影响,因为所有的接下来的 IO 操作都会自动继承”pool”的 snap_seq,对 object 进行 clone。在 CephFS 里用到这个模式管理全局的 Snapshot。

所以,更简单的讲,这两者 mode 的区别就在于应用进行 IO 请求时是否附带 snap_seq。

Object Snapshot 的存储管理

上面提到的都是如何利用 snap_seq 向底层存储查找相应的对象然后返回,那么底层的存储引擎是如何管理一个 Object 的不同版本的呢。

首先,任一个 Object 都是通过 ObjectStore 接口进行访问,目前 Ceph Master 分支支持 MemStore 和 FileStore 两种,FileStore 是默认的存储接口实现。以后的文章也会介绍具体的 FileStore 实现。

在 Ceph 中,每一个 Object 都有三种类型的存储接口,分别是最主要的 Object 存储,xattr 存储和 omap 存储。Object 存储就是用户实际数据的存放,xattr 主要用来给 CephFS 提供 XATTR 数据存放,omap 存储可以理解成一个 k / v 存储并且与某一个 object 相关联。而一个 Object 的元数据 (pool,PG,name 等等) 都有一个 object_info_t 的结构进行管理,有一个 SnapSetContext 结构管理 Snapshots,两者都作为一个 object 的 k / v 存储持久化。默认的 FileStore 是利用 LevelDB 作为键值存储,然后通过 DBObjectMap 类对 LevelDB 进行映射管理。

在 Snapshot 的实现上,最重要的其实就是 Clone 操作,那么在 FileStore 层面,Object 数据存储是实际上就是一个文件,Object 间克隆依赖 OSD 数据目录的文件系统,如 Ext4 或者 XFS 会直接完全拷贝数据,使用 Btrfs 会利用 ioctl 的 BTRFS_IOC_CLONE_RANGE 命令,kv 数据克隆通过一个巧妙的 KeyMapping 实现 COW 策略(略微复杂,后面文章解读),而 xattr 则完全 copy 实现(xattr 在 Ceph 中较少用到)。

以上是“Ceph 中 Snapshot 的示例分析”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注丸趣 TV 行业资讯频道!

正文完
 
丸趣
版权声明:本站原创文章,由 丸趣 2023-08-16发表,共计3687字。
转载说明:除特殊说明外本站除技术相关以外文章皆由网络搜集发布,转载请注明出处。
评论(没有评论)