针对功能,对照代码,理解radosgw的lc机制
写在前面
松鼠哥的ceph专业课程上线啦!
面向新手同学,从0实战,全面入门ceph安装部署与运维,有需要的同学赶紧扫码订购吧:
在radosgw中,可以针对bucket设置其对象的生命周期,当对象存活时间超出这个时间后,rgw会对其进行删除回收,这里设置的粒度目前是在bucket,也就是不能针对object设置其失效时间
bucket的lc机制弊端是很明显的,在lc打开的情况下,进行lc的做法是遍历整个bucket的对象,找出超过存活时间的对象进行回收,这就意味着,如果单个bucket对象数量十分庞大,这个遍历就会极其消耗性能
首先,与lc相关的参数有
1 | "rgw_enable_lc_threads": "true", |
默认情况下,bucket的属性标识中对象是永不过期的,对于某个bucket,手动设置其过期时间的接口,使用boto3的做法是
1 | #pip install boto3 -i https://pypi.tuna.tsinghua.edu.cn/simple boto |
设置完成后,可以通过命令radosgw-admin lc list
查看到当前lc的队列
1 | [store@server227 build]$ ./bin/radosgw-admin -k keyring -c ./ceph.conf lc list |
代码跟读
lc处理流程的入口是rgw/rgw_lc.cc
的*RGWLC::LCWorker::entry
函数
1 | void *RGWLC::LCWorker::entry() { |
如果使能了lc的功能,lc的线程会在进行一次lc作业后,等待一段时间,再唤醒起来进行下一次的作业,这里函数的第三行,使用should_work
函数判断本次的lc是否进行,默认rgw_lc_debug_interval
为-1,表示不进行lc的作业,此时会进一步判断是否在设定的回收时间内,如果不在,也不进行lc作业
1 | if (cct->_conf->rgw_lc_debug_interval > 0) { |
跟着lc->process()
看下
1 | int RGWLC::process() |
函数比较简短,限制每次作业的时间为rgw_lc_lock_max_time
,默认是60s,结合实际测试看,这个时间并不准确,继续看
1 | int RGWLC::process(int index, int max_lock_secs) |
lock的对象是lc_process
,这个函数中会多次请求osd进行lc的前期操作,包括查询head、set一些配置等,最重要的是检查bucket是否配置了lc,开始lifecycle到调用bucket_lc_process
前,花费时间为68ms
,接下来
1 | int RGWLC::bucket_lc_process(string& shard_id) |
在这个函数中,首先设定运行时间,线程通过bucket list的方式拿到1000个obj,获取使用按顺序的方式,遍历这1000个对象,如果该对象超过了过期时间,则删掉,关于循环的停止条件,is_truncated: if number of objects in the bucket is bigger than max, then truncated
,即要求遍历完整个bucket
这部分耗时主要依赖于bucket内对象的数量,对象越多,则耗时肯定会越多
最后,针对对象中分片情况,进行了处理,在RGWLC::bucket_lc_process
的最后
1 | ret = handle_multipart_expiration(&target, prefix_map); |
其中prefix_map
表明了对象分片的相关信息
看下对于分片的处理逻辑
1 | for (auto prefix_iter = prefix_map.begin(); prefix_iter != prefix_map.end(); ++prefix_iter) { |
可以看到,与对象删除一样,分片删除也是一次性取出1000个分片对象进行删除
逻辑总结
首先,在默认情况下,lc线程启动后,根据rgw_lc_debug_interval
及设定的rgw_lifecycle_work_time
来判断要不要做本次的process,默认rgw_lc_debug_interval
为-1,表示不做本次lc,另外,在rgw_lc_debug_interval <=0
时,这个时间间隔单位将放大为天,原注释说的是We're in debug mode; Treat each rgw_lc_debug_interval seconds as a day
在决定要做本次lc后,根据rgw_lc_lock_max_time
来判断每次lc的周期时间长度,然后每次从rgw_lc_max_objs
中选取一个进行运行,增大这个值不会加快回收速度
关于rgw_lc_max_objs
,它表示的是lc的处理线程的最大数量,它并不是并发的线程,因而增大这个值并不能加快回收速度,它类似于一个分组,bucket被设置lc规则后将被分配到某个lc中,例如,这个值设置为3,它启动回收的时候会随机启动lc.0、lc.1、lc.2中的其中一个,测试发现,多个bucket都设置过期的情况下,单个rgw同一时间仅运行一个lc线程,因而设置自动回收速度其实是很慢的
接下来,请求并设定一些基本的元数据信息,最重要的是判断bucket是否需要做lc,它检测bucket是否进行了lc的设置,如果设置才做,没有设置,默认是不做
然后,从指定的bucket中每次取出最多1000个有序对象,遍历这些对象并检查他们是否到达过期时间,过期则删除,直到bucket中所有的对象都遍历完成.
针对分片做了特殊处理,删除掉第一个片后,其余分片有专门的逻辑进行进一步的删除
环境中起2个rgw进行测试,发现2个rgw可以同时进行不同bucket的回收,因而,要加快回收速度,只能通过增加rgw的数量实现,单个rgw明显只能串行单线程进行单bucket的回收,不过,因为回收bucket涉及到bucket list,过快的回收速度也可能引发性能问题,需要权衡
- 本文作者: 奋斗的松鼠
- 本文链接: http://www.strugglesquirrel.com/2019/07/07/bucket对象回收lifecycle机制/
- 版权声明: 本博客所有文章除特别声明外,创作版权均为作者个人所有,未经允许禁止转载!