ceph version
ceph version 12.2.10
ceph.conf
配置项 |
说明 |
"rgw_dynamic_resharding": "true" |
是否开启自动分片 |
"rgw_reshard_num_logs": "16" |
分片并发数 |
"rgw_bucket_index_max_aio": "8" |
一次下发的op数 |
"rgw_reshard_thread_interval": "600" |
执行reshard间隔 |
"rgw_max_objs_per_shard": "100000" |
每个bucket的索引的最大对象数 |
"rgw_override_bucket_index_max_shards": "0" |
bucket的初始化索引个数,若小于1 则以zone配置项bucket_index_max_shards为准 |
测试reshad命令
执行reshard前,有1个shard,一共5个文件:
查看bucket index 对象,有1个对象,对象omap属性有这5个文件信息:
开始执行reshard命令,结果提示需要手动删除旧的bucket index对象:
执行完成:
执行完成,查看bucket index有3个对象,2个新增的bucket index里分布了共5个文件信息:
手动删除旧的bucket index对象:
再次查看查看bucket index只剩2个对象了
注意:bucket元数据新旧对象同时存在
初始化RGWReshard
ceph配置项rgw_dynamic_resharding=True且为master zone的rgw节点,rgw在初始化阶段会创建RGWReshard对象并启动进程:
rgw_rados.cc : int RGWRados::init_complete()
启动工作进程ReshardWorker
ReshardWorker处理函数
rgw_reshard.cc:
void *RGWReshard::ReshardWorker::entry()
1.检查能否进行reshard,若zg里有多个zone,如配置了multi容灾则不能reshard:
2.一共有rgw_reshard_num_logs(16)个rehsard log,每个reshard log保存在omap里,依次遍历各个reshard log里的分片任务并取出执行,每个rehsard log最多取出1000个任务执行。
do{
for( i =0;i < rgw_reshard_num_logs(16);i ++)
{
for reshard_entires in list(保存在omap里reshard.num的分片任务)
{
处理reshard_entires;执行成功则把reshard_entires从omap里删除
}
}
sleep(600);
}while (!reshard->going_down());
3.具体分片任务执行过程:
RGWBucketReshard::execute(.....)
(1)新生成一个new_bucket_id,更新信息到reshard log对应的reshard任务里(若任务被中断后重新启动,将跳过new_bucket_id != None的reshard 任务,不处理该任务)
(2)构造一个新的bucket index对象名字列表:.dir.${bucket_id}.0 ~ dir.${bucket_id}.n
(3)下发创建初始化新bucket index 对象的命令[create,call rgw.bucket_init_index]创建新bucket index对象的omap header(对应存储池:default.rgw.buckets.index)
(4)构造新bucket meta对象名为.bucket.meta.${bucket_name}:${bucket_id}。(对应存储池:default.rgw.data.root)
(5)下发命令创建初始化bucket meta对象[create,call version.inc,writefull 0~391,setxattr user.rgw.acl (127)],该对象中有2个属性version和acl)
(6)更新omap里reshard log的该bucket 的分片任务的bucket_id
(7)更新bucket index的状态为RESHARD_IN_PROGRESS
(8)更新bucket meta对象状态为RESHARD_IN_PROGRESS
(9)到omap里列出所有bi log里的条目,条目名形如0x0000000000002fbb'.3_kb_file'(在测试里index 对象中看到形如<80>0_00000000012.2134179.5的被过滤掉了),根据条目的idx,即文件名hash并对新shard num总数取模后计算出该文件条目应该记录在哪个bucket index shard下并重新统计桶的已使用量,每达到RESHARD_SHARD_WINDOW(64)个文件则依次下发更新omap命令并更桶的使用量
(10)完成所有shard更新后,更新桶的创建时间为当前时间,更新user_uid_pool存储池里${user name}.buckets对象的omap中的该bucket属性值
(11)更新状态为RESHARD_DONE
(12)把旧的bucket index对象删除(没报错,但测试结果中显示并未删除)
(13)reshard过程中若出错,则会尝试把新建的bucket index对象删除
dynamic reshard
自动动态调整bucket index数量
put/post 命令都会检查是否需要进行自动分片:
rgw_rados.cc : check_bucket_shards :
1.检查conf参数rgw_dynamic_resharding,为false则不需要进行自动分片并return
2.计算当前bucket的总对象数是否大于num_shards * conf.rgw_max_objs_per_shard(即桶索引个数x每个索引的最大对象数)
3.若计算结果为true则需要自动分片,计算新的索引个数=当前bucket的总对象数*2/conf.rgw_max_objs_per_shard ,调整最后结果取min(新的索引个数,65521)
4.把bucket的分片任务加入shard log中等待处理
bucket reshard命令
例:radosgw-admin bucket reshard --bucket=xxx --num-shards=64
rgw_admin.cc
1.校验参数:
要求num_shards <= 65521
要求num_shards > 该bucket 当前的shard num
2.构造分片对象RGWBucketReshard br 并立即执行分片任务br.execute
reshard add命令
例: radosgw-admin reshard add --bucket=xxx --num-shards=64
1.校验参数:
要求num_shards <= 65521
要求num_shards > 该bucket 当前的shard num
2.把【tenant + ":" + bucket_name】hash后去取模计算reshard_id
3把bucket的reshard信息添加到omap里key:val=reshard_id: reshard_of_bucket_info
4.如shard_id=9则把信息加到5:55b0279d:reshard::reshard.0000000009:head 里
reshard list命令
例:radosgw-admin reshard list
遍历列出rgw_reshard_num_logs个reshard log对象:reshard.0000000000 ~ reshard.000000000x里的分片任务
reshard process命令
例:radosgw-admin reshard process
遍历rgw_reshard_num_logs个reshard log对象:reshard.0000000000 ~ reshard.000000000x
逐个启动reshard log对象里的分片任务
reshard cancel命令
例: radosgw-admin reshard cancel --bucket=test-1
先去获取RGWBucketReshard 该bucket的分片对象锁,若分片正在进行则会获取失败不能cancel.否则更新新建的bucket index 对象/bucket meta对象的状态为CLS_RGW_RESHARD_NONE ,把bucket的reshard信息从omap里删除key:val=reshard_id: reshard_of_bucket_info
reshard status命令
ceph versiion >= v12.2.11才有的命令。
例:radosgw-admin reshard status --bucket=test-1
若bucket不处于resharding状态则读出为空,否则列出status/entry/reshard_status/new_bucket_instance_id/num_shards