Ceph 对象存储网关容许你经过 Swift 及 S3 API 访问 Ceph 。它将这些 API 请求转化为 librados
请求。Librados
是一个很是出色的对象存储(库)可是它没法高效的列举对象。对象存储网关维护自有索引来提高列举对象的响应性能并维护了其余的一些元信息。有关对象存储网关索引工做原理的文章不多,因此我写了这篇博文,权当抛砖迎玉。数据库
这个 bucket 的对象列表存储在一个单独的 rados
对象中。这个对象的名字是 .dir. 加上 bucket id
。索引对象存储在一个名为 .rgw.buckets.index 的独立存储池中。因此本例中,mybucket 的索引应该是 .dir.default.14113.1(译者注:原文中是.dir.default.2529250.167, 基于原理和实践,肯定此处有误,特此更正)。性能
# rados -p .rgw.buckets.index ls - | grep "default.14113.1"
.dir.default.14113.1
你能够看到从 .rgw.buckets.index 存储池返回的索引对象。spa
# rados -p rados -p .rgw.buckets.index get .dir.default.14113.1 indexfile
# wc -c indexfile
0 indexfile
对象为 0 字节,怎么回事呢?秘密是:索引信息实际上存储在 Ceph 的键/值数据库中。每一个 OSD 都有一个本地 leveldb 键/值数据库。所以索引对象实际上只是一个占位符,Ceph 经过它找到那个包含索引信息的 OSD 键/值数据库。code
# rados -p .rgw.buckets.index listomapkeys
.dir.default.14113.1myobject
因此索引键就是对象名(情理之中)。对象
如今比较对头了!本例中索引占了 175 字节,从上面的十六进制转储信息能够看到一些信息片断。若是你用上面的转储信息与 radosgw-admin
输出的对象元信息对比,你就会知道索引中存储的是什么。blog
咱们能够肯定索引包含以下信息:索引
name
get
owner
it
owner_display_name
class
etag
tag
须要注意的是 owner 既是键也是值。我认为这样作是在出现数据损坏时能经过扫描索引值来恢复索引键。
owner_display_name 在这里是为了兼容 S3。显然是一个读写妥协。
etag(实体标签)是对象的 MD5 值,也是为了兼容 S3。这有点得不偿失,由于我能够确定若是每次建立一个对象就要计算 MD5 值,这将会损害写性能。
我怀疑 radosgw-admin
显示的其余元信息也包含在索引中(或者为空或者不可见)。
计算出包含索引对象的 OSD
# ceph osd map .rgw.buckets.index .rgw.buckets.index .dir.default.14113.24
osdmap e60 pool '.rgw.buckets.index' (11) object '.dir.default.14113.24/.rgw.buckets.index' -> pg 11.e6c72a3f (11.3f) -> up ([3,5], p3) acting ([3,5], p3)
咱们看到键值数据库在 OSD 3 及 5 上,其中 3 是主 OSD(第一个)。
找到 OSD 3 上的键值数据库
能够看到 osd.3
在主机 ceph-osd1
上
这就是包含索引的键值数据库 leveldb。