
一:对象存储常用存储池及作用?
.rgw.root(用于存储对象服务元数据信息,包括realm、zonegroup、zone等相关信息;
.data.extra(用于存储对象分片上传的临时数据)。
上述两个池后台创建,用户不用自己设置。
data pool数据池:用于存储对象数据实体内容;
Index pool 索引池:用于存储对象索引信息。注意这里说的不是对象的元数据。创建存储桶时,RGW网关会同步创建一个索引对象(index),用于保存该存储桶下的对象列表。也就是说这个对象里面记录了该桶所有的对象名及相关一些重要属性。
以支持查询存储桶对象列表(List Bucket)功能,因此在存储桶中有新的对象上传或者删除的时候必须更新索引对象。
二:索引对象及其作用?
默认情况下单个bucket的索引对象index全部存储在一个shard文件(shard数量为0,主要以OMAP-keys方式存储在rocksdb中),
随着单个bucket内的Object数量增加,整个shard文件的体积也在不断增长,当shard文件体积过大就会引发各种问题。而且在并发读写的场景,大家都去更新一个shard文件,这个索引对象就会成为新的瓶颈,影响性能。
因此需要做分片,避免该对象随着上传对象的逐渐增多而变得越来越大,引发各种问题。但分片也不能切的太多,分片过多会影响对索引对象的读操作效率,本来list 桶只需要读一个shard文件,现在需要读多个shard分片,并且这些shard分散在多个osd上,读完后还要做结果合并,会降低对象索引查询的性能。
每个存储到rados的Object都需要先计算出对应元数据存储的shard number,之后再将元数据信息更新到shard number对应的Object里面。index shard number的计算方法:
uint32_t sid = ceph_str_hash_linux(obj_key.c_str(), obj_key.size());
uint32_t sid2 = sid ^ ((sid & 0xFF) << 24);
通过对字符串的Hash计算,得到hash值,再取模hash_id%7877%128,得到bucket shard的分片ID
基于上述问题,建议:
1、提前规划好bucket shard分片个数,目前推荐单个shard存储的Object信息条目在10-15W左右。比如你预计单个bucket最多存储100W个Object,那么100W/8=12.5W,设置shard数为8是比较合理的。
2、index pool一定要上SSD
3、性能测试要求高的场景,也可以设置无索引桶,也就是上传对象不去更新索引对象index, 这样就可以少一次写IO,性能提升很明显,但失去了对象索引的功能。
4、可以将对象索引记录在es等第三方服务器上,不去写对象索引,这个也是一个优化的办法。
三:对象的数据和元数据的保存方式?
应用上传的对象包括数据和元数据两部分,数据部分保存在一个或多个RADOS对象的数据部分,元数据保存在其中一个RADOS对象的拓展属性中。都是存放在data pool中。
这里要理解用户上传的对象和rados存放的对象的对应关系。
如上图,rgw_max_chunk_size和rgw_obj_stripe_size默认都是4M。用户上传对象到RGW网关服务后,会先分割成一个4M的首对象,和多个大小为4M的中间对象,以及最后一个尾对象(小于或者等于4M)。首对象就是我们常说的head_obj, 它就是以对象本来的名字命名的。其他中间对象和尾对象的名字都是按 _shadow + . +32bit随机字符串+条带编号,这样的规则进行命名的。
Head_obj存放了该对象的前4M数据,扩展属性保存了上传对象的元数据和manifest信息。元数据是对象的一些属性信息,manifest是用来管理用户上传的对象和经过rgw网关切片后的rados对象的对应关系。所以拿到了manifest就可以知道用户上传的对象和分片后的rados对象的映射关系。
用户下载对象时(读操作),通过对象名找到head_obj, 然后从head_obj中读取manifest信息,计算出用户对象其他的数据保存在哪些rados对象中,然后从这些对象中读出数据,合并后,作为一个完整的对象返回给用户。
四:rgw中用户、桶、对象的对应关系?
用户和用户所属的桶
创建一个用户rgwuser。会在.rgw.root池中创建两个对象rgwuser 和rgwuser.buckets。
rgwuser 对象和我们用户的id名称一致,这个对象就是用来保存用户信息的rados对象。
rgwuser.buckets对象用来保存这个用户拥有的桶,格式就是{uid}.buckets,用户和bucket的对应关系就保存在这个对象的omap里面。表示了用户和bucket的对应关系。
桶和桶中的对象
创建一个桶, 在.rgw.root池中会创建两个rados对象,保存桶的元数据信息,一个叫bucket,另一个是bucket instance。bucket是以bucket名称命名的metadata,而bucket instance是以bucket内部id命名的metadata。bucket对应内部的类型是RGWBucketEntryPoint,其只保存的bucket概要信息。bucket instance对应内部的数据类型是RGWBucketInfo,其保存的是bucket的详细信息。其中数据部分保存RGWBucketinfo定义的信息,扩展属性中保存自定义封装的元数据KV条目。
同时还会在index.pool中创建一个索引对象,用于保存桶中所有对象的索引。(上面已经详细讲过)
五、对象存储中数据的保存方式。
rados保存数据有三种方式:object data、object xattr、object omap。data是保存对象的数据,xattr是保存对象的扩展属性,这要求支持对象存储的本地文件系统(一般是 XFS)。如果要设置的对象的key/value因为操作系统限制,不能存储在文件的扩展属性中,还存在另外一种方式保存omap, omap是 object map 的简称,是将元数据保存在本地文件系统之外的独立 key-value 存储系统中,在使用filestore 时是 leveldb,在使用 bluestore 时是 rocksdb。
有些本地文件系统可能不支持扩展属性,有些虽然支持扩展属性,但对 key 或者 value 占用的空间大小有限制。对于 leveldb 或者 rocksdb 则没有空间上的限制,但它的性能有限制。所以一般情况下,xattrs 保存一些比较小而且经常访问的信息。omap 保存一些大的但不经常访问的数据。




