ceph集群和数据库到底是储存数据_Ceph剖析1- RDB 块存储原理

简介

​ 块设备是i/o设备中的一类,是将信息存储在固定大小的块中,每个块都有自己的地址,还可以在设备的任意位置读取一定长度的数据,例如硬盘,U盘,SD卡等。狭义的块设备专指硬盘。

​ 块设备(Block device)是Ceph最重要的用途之一。早期Ceph开发的时候,是作为纯粹的文件系统向外提供的;随着云计算的兴起,基于Ceph的后端存储组件RBD的产生逐渐使ceph作为弹性计算最重要的后端之一,逐步得到了开发者的重视。

​ 在当前,Iaas和弹性计算流行的今天,部分厂商将Ceph选为块存储的存储系统。在LinuxIO协议栈中,块设备位于VFS层之下,提供了基于块的读写能力。

Ceph RADOS语义:

​ Ceph的底层是RADOS集群,RADOS包含了Monitor集群,OSD集群以及客户端,对外提供一致和统一的服务。

​ Ceph支持块存储、对象存储和文件存储的场景,不同的存储场景对于存储的性能要求不同:大数据场景更加注重吞吐量和集群规模,块存储注重延迟和稳定性,对象存储更加关注成本和数据可靠性,数据库和实时计算关注低延迟以及一致性。

​ 为了满足不同的存储场景的需要,作为存储底座的RADOS的对外提供的接口需要足够简单,尽量满足不同存储场景的需求。Ceph的RADOS客户端提供了以下几种语义:

  • 向一个存储池内创建一个对象,并可以对对象随机读写以及追加读写;对象使用对象id标志,比如“object1”,对象内容是无意义的二进制流;
  • 向一个存储池内创建一个omap或者attr,omap类似于字典,并可以向omap中新增或者删除key value。如果存储池是基于纠删码的存储,则不支持omap。

Ceph提供了以对象为基础的接口,上层业务需要在额外封装块存储或者对象存储的接口。RADOS内部实现了高可用、数据高可靠性、统一化存储。

RBD接口

​ RBD(RADOS Block Device)是Ceph对外的三大组件之一,也是Ceph最稳定的接口。应用访问rados应用有两种途径(如下图):

  • librbd 用户态接口,librados.so动态链接库充当客户端接入RADOS集群;可以在用户态访问RBD接口;
  • krbd 内核态,通过rbd命令,可以将rbd设备映射为本地的块设备,可以在/mnt下挂载。

1abfea897b249a760ef7ea3f8e87c2ef.png

用户可以使用rbd命令通过存储池的名字和image名字设置挂载的image。

sudo rbd map {pool-name}/{image-name} --id {user-name}

​ RDB提供的接口定义在中,RBD提供的接口不同于块设备的bio接口,在RBD使用名字或者id唯一标志一个RBD。rbd.ko作用在块设备驱动层。提供了以下接口:

  • 打开、关闭、clone、快照一个块设备;
  • 同步io接口,以及异步io接口,参数 偏移+长度;
  • 获取image元数据信息的能力。

image存储组织(基于RADOS)

​ RBD块设备在Ceph中被称为image(本文仅仅讨论image V2)。类似于其他存储,image由元数据和数据组成,元数据和数据都以对象的方式在RADOS维护:

  • 对于块设备的各种IO请求,RBD驱动会转化为对于RADOS集群中相应对象的操作。
  • image元数据中需要维护信息,支持快照、克隆等操作,也需要记录文件大小、条带等信息;
  • image数据被分为一个个大小相等的数据片(默认为4MB,比如1GB的image分为256个),每个数据片都以RADOS对象的形式存储在RADOS集群中。

对于一个块存储设备,RBD在RADOS上维护了四种对象:

9f4cb940d8894a1de43f22994bb5b6b5.png

rbd_id.<:name>

​ RBD向上提供了通过name接口访问image的能力,同时也提供了为image重命名的接口。image内部使用id标志,这样即使名字改变id也不会变化。

​ 比如RADOS对象, rbd_id.foo1 值为 “1234567890”,表示名字为foo1的image的id为1234567890。

rbd_header.<:id>

​ rbd_header.<:id>表示image的元数据信息,比如rbd_header.1234567890表示id为1234567890的image元数据信息。superblock中的大部分信息都维护在rbd_header.<:id>中,

​ rbd_header.<:id>的类型为omap,可以容纳很多键值对。

46fe53130d76de376d3d150a437f694d.png

rbd_object_map.<:id>

​ 早期的RBD设备没有这个对象,对于数据快照的场景,RBD会逐次拷贝每一个数据片对象,会占用集群大量的性能。对于数据快照的场景,理想的方式应该是采用写时复制技术,类似于Linux fork,只有修改了才会复制。为了支持写时复制,rbd_object_map对象被加入新版的image元数据中。

​ 每一个数据片在rbd_object_map都有2bits的标识,可以表示四种状态:

  • b00 表示数据片不存在,即内容全部为0;
  • b10 表示数据片存在,可以被随意修改;
  • b10 数据片存在等待删除,即内容全部为0;
  • b11 数据片从上一次快照没有被修改过。

​ 在RADOS中,这个对象的值为二进制流。对于1TB的磁盘,4MB的分片,RBD共维护了262144个数据片对象,相应的每个数据片对象占有2bits,那么总共占有64KB,所以rbd_object_map对象的大小为64KB。第i个字节,表示第4i ~4i+3 个分片的状态。

rbd_data.<:obj_prefix>.<:obj_no>

​ 这一类对象表示块存储的数据分片,obj_no为16位长度的16进制数表示一个64位整形。obj_prefix存在Header里面。比如某个image的prefix为1017238e1f29,那么rbd_data.1017238e1f29.0000000000000000 表示第一个分片,依次类推。由于image的特性,创建的块设备的时候只在头尾创建了部分数据,大部分数据片为空,即标志位为00。

​ 为了节省存储空间,如果一个数据片全部为0则不会实际在RADOS集群中存储;如果一个数据片的后半部分全部为0,则只会存储到非0部分,比如在4MB的全0数据片中,3084KB-3085KB写入了1KB的数据,则RBD会创建一个对象长度为3085KB,前面3084KB全部为空。

数据条带化:

​ 启动条带化会使用RAID0的方式存储。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值