RGW 的GC深入解析与调优

时间:2022-04-25
本文章向大家介绍RGW 的GC深入解析与调优,主要内容包括什么是GC、GC启动流程、GC 流程概览图、参数调优的几点心得、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。

什么是GC

Garbage Collection缩写GC,简称垃圾回收。在RGW中GC一般都是指一些异步的磁盘空间回收操作,一般下面三种情况会发生GC。 1. 客户端执行删除Object操作,对应的Object所占用的磁盘空间会交由后台GC处理。 2. 客户端执行Object覆盖写入操作,旧Object相关的空间需要释放。 3. 客户端执行上传操作(分块上传),上传过程中会产生一些shadow文件,这些上传过程中产生的临时数据也会纳入GC的回收。

GC启动流程

GC是以thread方式在rgw服务启动时候进行启动,对应的启动调用流程如下。

每个GCworker启动的时候都会有一个数字ID标识,这个ID其实就是对应到gc pool里面的Object的ID名称,GC的任务列表就存储在每个gc pool里面对应的Object的omap中,如果gc队列发生爆炸式增长或是拥塞,那么这个omap体积也会爆炸式增长,在底层做scrub的时候会极大消耗磁盘的性能,同时还可能会引发客户端请求发生阻塞而出现504错误最终影响服务可用性。值得注意的是GCworker启动时的ID是通过一个随机算法选择的,如果已经有相同ID的其他GCworker正在运行,则获取锁失败,要重新运行随机选择算法。GCworekr启动的流程如下

GCworker的随机选择算法如下,其中max_objs表示gc worker总数。

int RGWGC::process()
{
  int max_secs = cct->_conf->rgw_gc_processor_max_time;

  unsigned start;
  int ret = get_random_bytes((char *)&start, sizeof(start));
  if (ret < 0)
    return ret;

  for (int i = 0; i < max_objs; i++) {
    int index = (i + start) % max_objs;
    ret = process(index, max_secs);
    if (ret < 0)
      return ret;
  }

  return 0;
}

需要回收的Object在达到指定条件后会丢进对应的gc队列,进行处理,如下图所示

gc 队列的数据结构如下,每个china通过唯一的的tag名称进行标识。

需要注意的是每个gc的记录会生成两种类型的索引记录,0开头的以名称为标识和1开头以时间戳为标识,最终插入到gc Object所在OSD的omap的LevelDB记录中。

/*
 * We hold the garbage collection chain data under two different indexes: the first 'name' index
 * keeps them under a unique tag that represents the chains, and a second 'time' index keeps
 * them by their expiration timestamp
 */
#define GC_OBJ_NAME_INDEX 0
#define GC_OBJ_TIME_INDEX 1

static string gc_index_prefixes[] = { "0_",
                                      "1_" };

GC 流程概览图

最后一张图来总结整个GC的过程,其中涉及到几个和GC效率有直接关系的几个参数,大家可以根据各自线上情况去调优。

参数调优的几点心得

  • GC worker的数量由rgw_gc_max_objs来控制,设置这个参数的时候要考虑到你线上业务是否会有大量的GC操作,不要盲目调高。
  • rgw_gc_processor_max_time控制每次GC任务最多能够执行的时长,要考虑到你底层存储设备的负载情况,高速存储设备可以适当缩小,但是当底层存储设备比较慢并且负载较高的时候,考虑到GC的额外性能消耗,可能就要调大这个时长了。
  • rgw_gc_obj_min_wait 这个控制删除数据以后多久以后开始真正的底层数据回收,默认是2小时,如果线上对空间资源利用率比较敏感,可以适当缩短。
  • rgw_gc_processor_period 这个控制多久时长以后GCworker开始下一轮的GC操作,如果单次GC需要操作的列表条目数较少,可以适当缩短这个参数。