在OpenStack使用Ceph纠删码存储

张开发
2026/6/9 16:44:24 15 分钟阅读
在OpenStack使用Ceph纠删码存储
背景在当今云原生时代OpenStack 与 Ceph 的组合已成为私有云和混合云场景下的 黄金搭档。Ceph 作为统一的分布式存储平台为 OpenStack 提供了块存储Cinder、镜像存储Glance解决方案。在 OpenStack Ceph 架构中如何在保证高可用的前提下进一步提升存储利用率答案就是RBD 纠删码Erasure Coding, EC。本文结合实际改造经验完整梳理 OpenStack 适配 Ceph 纠删码的设计思路、实现方式与关键改造点。Ceph rbd介绍随着云计算的发展Ceph已经成为目前最为流行的分布式存储系统俨然存储界的Linux操作系统。Ceph集块存储、文件存储和对象存储于一身适用场景广泛用户众多。RBD是 Ceph 分布式存储系统中提供的块存储服务Ceph的块存储通过一个客户端模块实现这个客户端可以直接从数据守护进程读写数据不需要经过一个网关。根据客户端整合生态系统的差异使用Ceph的块设备有两种实现方式librbd (用户态)和krbd (内核态)。使用Ceph的块设备有两种路径内核态与用户态(rbd map就是内核使用ceph块设备调用librbd/librados API访问ceph块设备是用户态)通过Kernel Module(内核态RBD)即创建了RBD设备后把它映射到内核中使用rbd map命令映射到操作系统上成为一个虚拟的块设备这时这个块设备同其他通用块设备一样设备文件一般为/dev/rbd0后续直接使用这个块设备文件就可以了可以把/dev/rbd0格式化后挂载到某目录也可以直接作为裸设备进行使用。krbd是一个内核模块。其在内核中以一个块设备的方式加以实现。这整个Ceph客户端都是以内核模块的方式实现没有与之相关的用户态进程或者守护进程。krbd在内核的源码目录源文件:drivers/block/rbd.c、drivers/block/rbd_types.h、net/ceph/、include/linux/cephhttps://www.likecs.com/show-203739919.htmlhttps://github.com/torvalds/linux/blob/cfb92440ee71adcc2105b0890bb01ac3cddb8507/drivers/block/rbd.chttps://github.com/torvalds/linux/tree/85c7000fda0029ec16569b1eec8fd3a8d026be73/include/linux/ceph通过librbd(用户态RBD)即创建了RBD设备后使用librbd/librados库访问和管理块设备。这种方式直接调用librbd提供的接口实现对RBD设备的访问和管理不会在客户端产生设备文件这种方式主要是为虚拟机提供块存储设备在虚拟机场景中一般会用QEMU/KVM中的RBD驱动部署Ceph块设备宿主机通过librbd向客户端提供块存储服务。应用方案有SPDKlibrbd/libradoshttps://github.com/ceph/ceph/tree/acf835db0376b1b71152949fdfec36e68f4a8474/src/librbdhttps://github.com/spdk/spdk/tree/cff525d336fb2c4c087413d4c53474b9e61cbdbe/module/bdev/rbdRBD 的块设备由于元数据信息少而且访问不频繁故 RBD 在 Ceph 集群中不需要单独的守护进程将元数据加载到内存进行元数据访问加速所有的元数据和数据操作直接与集群中的 Monitor 服务和 OSD 服务进行交互。Ceph数据冗余策略多副本与纠删码多副本策略 是Ceph默认采用的机制。其核心是为同一份数据创建多个完全相同的副本并分散存储于集群的不同节点或硬盘上。例如在常见的3副本配置中一份数据会被复制成三份随机存放于三个独立的物理位置。这种策略的冗余能力直接明了N副本可以容忍N-1个存储单元节点或硬盘同时故障数据依然可用。它的主要优势在于实现简单数据恢复时无需复杂计算直接读取完整副本即可因此性能优异、延迟低。然而其代价是存储空间利用率较低3副本的有效利用率仅为33%即存储1TB用户数据需要消耗3TB的物理空间。纠删码策略 则采用了一种更为复杂的数学保护方法。它将原始数据分割成 k 个数据块并通过算法如矩阵计算生成 m 个校验块。这些数据块和校验块共 km 个随后被分布存储到不同节点。当部分块丢失故障节点数不超过 m时系统可以利用剩余块通过计算重建出丢失的数据。例如一个42的纠删码方案将数据切成4份并生成2份校验数据总计6份存储在6个节点可容忍任意2个节点故障。纠删码的核心优势在于极高的存储空间效率。同样能容忍两个故障42方案的利用率约为66%远高于3副本的33%。配置如104时利用率可达71%以上能容忍4个故障而存储开销仅为40%。但这是以计算开销为代价的数据的写入、重建和恢复过程需要进行大量编解码运算尤其在HDD环境或大规模恢复时性能开销显著延迟通常高于多副本。RBD与纠删码存储方案在 Ceph 环境中RBD块存储使用纠删码EC, Erasure Coding模式本质上是 “元数据放副本池、数据放纠删码池” 的混合方案。这是目前唯一被官方支持、也是生产可用的 RBD EC 方式。Ceph RBD块设备与纠删码结合使用的核心在于采用了一种元数据与数据分离存储的混合架构。这种设计的目的是为了在享受纠删码高存储效率的同时规避其对频繁小IO操作性能不佳的缺点从而兼顾性能与成本。具体而言系统会创建两个不同类型的存储池一个用于存储元数据的副本池和一个用于存储实际块数据的纠删码池。RBD镜像的元数据包括记录镜像大小、特性的 rbd_header 对象、逻辑块到物理对象的映射关系以及快照克隆的父子依赖全部存放在副本池中。这是因为元数据操作如创建快照、更新映射具有低延迟、强一致性和高频小IO的特性副本池的模型能为此提供最佳的性能和可靠性保障同时避免了纠删码带来的“写放大”效应。反之镜像的主体数据块则经过纠删码编码后分片存储于纠删码池中。这主要是看中了纠删码极高的存储空间利用率它能够以远低于多副本的冗余开销例如 42 配置仅需1.5倍空间提供数据保护尤其适合处理块设备典型的大块顺序IO。在这样的架构下I/O路径也相应进行了划分。写入数据时客户端首先访问副本池中的元数据来确定位置然后将数据编码并分片写入纠删码池。读取时则先从副本池获取映射再从纠删码池读取并解码数据分片。特别值得一提的是克隆操作的实现它巧妙利用了这种分离结构。在元数据层副本池仅需记录克隆的引用关系开销极小在数据层纠删码池则执行实际的写时复制COW机制——克隆初始时共享父镜像的数据块仅在首次修改时才触发将父数据块拷贝至子镜像专属空间的操作且拷贝后的数据依然以纠删码形式存储。这种设计使得快速创建克隆成为可能而将较大的数据搬运成本延迟并分散到后续的写入过程中。RBD 纠删码块设备操作命令1、添加块设备 1、rbd pool init poolname //命令用于初始化池供rbd使用poolname是指存储池名称 2、rbd create --size %s --image-feature layering poolname/name --data-pool datapoolname //在存储池上创建一个空的映像 //%s指的是大小poolname为存储池名称name为要创建的映像的名称datapoolname为要创建的影响的存储池的名称 //--image-feature layering作用是创建映像时启用的rbd特性为layering 2、扩容块设备 rbd resize --size %s%s %s/%s //%s分别是大小、单位、存储池名称和块设备名称 3、重命名块设备 rbd mv %s/%s %s/%s //%s分别是存储池名称和旧块设备名称存储池名称和新块设备名称 4、断开关系链 rbd flatten %s/%s //%s分别为存储池名称和clone名称 //作用是使clone独立使其成为一个独立的块设备 5、删除块设备 rados -p %s rm rbd_header.%s //删除块设备信息 //分别是 存储池名称 和 块设备id通过 “rbd info 存储池名称/块设备名称”命令可以读取 rados -p %s rm rbd_id.%s //删除块设备信息 //分别是 存储池名称 和 块设备名称 rbd rm %s/ %s //%s //分别是存储池名称和块设备名称 6、创建快照 rbd snap create %s/%s%s //%s分别为存储池名称、块设备名称和快照名称 7、克隆快照 1、防止快照被删除 rbd snap protect %s //%s为快照名称 2、克隆快照 rbd clone %s %s/%s --data-pool %s //%s分别为快照名称、存储池名称、克隆镜像名称和克隆镜像的数据池名称 8、快照回滚 rbd snap rollback %s/%s%s //%s分别为存储池名称、块设备名称和快照名称 //回滚默认会连容量一起回滚如果需要原先的容量请重新resize 9、删除快照 1、取消保护 rbd snap unprotect %s/%s%s//%s分别为存储池名称、块设备名称和快照名称 2、删除快照 rbd snap rm %s/%s%s//%s分别为存储池名称、块设备名称和快照名称OpenStack使用Ceph纠删码rbd块在openstack中云盘和镜像数据存储在ceph中涉及到nova和cinder组件但原生nova和cinder在设计时主要面向的是传统的副本型RBD池。它们缺乏对纠删码RBD池原生、开箱即用的支持因此需要进行适配。Nova侧配置文件修改nova-compute[libvirt] rbd_user admin rbd_secret_uuid 1647e105-d9d7-49cd-9d1c-84e30e74c088 erasure_ceph_fsid erasure_rbd_meta_pool meta erasure_rbd_data_pool data代码修改nova/virt/libvirt/storage/rbd_utils.pydef clone(self, image_location, dest_name, dest_poolNone): _fsid, pool, image, snapshot self.parse_url(image_location[url]) if _fsid CONF.libvirt.erasure_ceph_fsid and \ dest_pool CONF.libvirt.erasure_rbd_meta_pool: LOG.debug(Using erasure coding features for cloning) features (rbd.RBD_FEATURE_LAYERING | rbd.RBD_FEATURE_DATA_POOL) RbdProxy().clone(src_client.ioctx, image, snapshot, dest_client.ioctx, str(dest_name), featuresfeatures, data_poolCONF.libvirt.erasure_rbd_data_pool) else: RbdProxy().clone(src_client.ioctx, image, snapshot, dest_client.ioctx, str(dest_name), featuressrc_client.features)Cinder侧配置文件修改cinder-volume[ceph] rbd_type erasure erasure_data_pool data代码修改cinder/volume/drivers/rbd.pydef clone(self, image_location, dest_name, dest_poolNone): _fsid, pool, image, snapshot self.parse_url(image_location[url]) if _fsid CONF.libvirt.erasure_ceph_fsid and \ dest_pool CONF.libvirt.erasure_rbd_meta_pool: LOG.debug(Using erasure coding features for cloning) features (rbd.RBD_FEATURE_LAYERING | rbd.RBD_FEATURE_DATA_POOL) RbdProxy().clone(src_client.ioctx, image, snapshot, dest_client.ioctx, str(dest_name), featuresfeatures, data_poolCONF.libvirt.erasure_rbd_data_pool) else: RbdProxy().clone(src_client.ioctx, image, snapshot, dest_client.ioctx, str(dest_name), featuressrc_client.features)总结OpenStack采用Ceph纠删码RBD的混合存储架构实现了性能与效率的卓越平衡。该架构将元数据存储于副本池保障快照、克隆等关键操作的低延迟和高可靠性同时将块数据存储于纠删码池利用其高空间效率特性相比传统3副本可节省50%的存储成本。这种分离设计使云平台能够兼顾高性能操作与大规模数据存储的经济性支持根据数据库、通用计算、冷备份等不同负载类型灵活配置EC策略。通过智能的分级存储管理OpenStack可在统一存储后端上为多样化工作负载提供成本优化且性能可控的块存储服务是兼顾成本与性能的工程化解决方案。

更多文章