Hadoop 垃圾回收机制原理及其源码分析

一、两个主要的配置参数:

fs.trash.interval

默认值为:0(代表删除的数据不进入垃圾桶,直接删除)

单位:分钟

描述:垃圾数据保存的时间

fs.trash.checkpoint.interval

默认值为:0

单位:分钟

描述:多久进行一次垃圾清理和创建检查点的检测,默认值为0,此时如果设置了 fs.trash.interval,则该值就会和 fs.trash.interval 的值保持一致,另外该值只能小于等于 fs.trash.interval 的值。

二、原理介绍:

NameNode在启动的时候,会创建一个专门用于垃圾回收的守护线程,该线程会根据参数fs.trash.checkpoint.interval 对应的值周期性的从睡眠中苏醒过来,执行两个主要的操作:

1)先执行垃圾清理操作,清理的原理是如下图所示的目录上面的数字代表的是垃圾检查点创建的时间(yyMMddHHmmss),拿当前时间减去该时间,如果大于参数fs.trash.interval 设置的时间,则将该检查点的数据递归的清理掉(其中Current目录会被过滤掉),否者不操作。

2)使用当前的时间将Current目录重命名成日期目录,作为之前一个fs.trash.checkpoint.interval 周期的数据的检查点。

三、源码分析:

1.在NameNode源码中有如下代码,代表着启动垃圾回收机制

    @Override

    public void startActiveServices() throws IOException {

      try {

        namesystem.startActiveServices();

        startTrashEmptier(conf);

      } catch (Throwable t) {

        doImmediateShutdown(t);

      }

    }

2.下面是启动垃圾排空方法的实现,

可以看出其创建了一个守护线程用于垃圾的清理,通过创建Trash对象,可以获取到Emptier对象

3.可以看出Trash类继承与Configured,主要用于保存配置信息和垃圾策略对象。

4.从中可以看到垃圾都被放到了每个用户的目录下。

5.TrashPolicy类中的getInstance方法,

使用反射创建TrashPolicy对象,从源码中也可以看到,我们也可以自己实现自己的垃圾回收策略,并通过在配置文件中使用key:fs.trash.classname指定为自己的实现的类,来使用自己的垃圾回收策略。系统默认实现的垃圾回收策略类是:TrashPolicyDefault

6.之后调用TrashPolicyDefault的初始化方法,

其中最开始处的两个参数就在此时获取其对应的值的,并且会创建一些常量用于回收时进行路径和时间的判断的。

7.创建完TrashPolicyDefault之后,NameNode就会调用getEmptier方法获取一个Emptier对象,用于垃圾的真正的清理。

Emptier类是类TrashPolicyDefault的内部类,因此,该类能访问类TrashPolicyDefault中的很多成员变量,另外类Emptier是Runnable的子类,也是垃圾回收线程真正执行的类,从类Emptier的构造方法中可以看出开头介绍的参数 fs.trash.checkpoint.interval 的值必须要小于等于 fs.trash.interval 的值。

8.之后NameNode会调用this.emptier.start(); (在步骤2中可以看到)方法将线程启动,之后就开始执行类Emptier中的run方法:

从中可以看出,当NameNode程序启动后,其会根据排空间隔时间让线程进行休眠,当线程苏醒之后,就开始执行删除操作和创建检查点操作。

9.垃圾删除操作真正执行的方法,删除策略:

1)Current目录下的垃圾不删除。

2)是日期目录的,将日期目录转换成对应的时间的毫秒值,之后让当前时间减去上面的值,判断是否超过了配置的删除时间,如果超过,就执行递归的删除操作。

10. 创建检查点的方法,

即创建上面删除事需要使用的日期目录方法,该方法将当前时间转换成 yyMMddHHmmss 格式日期,并创建对应的Path对象,之后使用rename方法将Current目录重命名成上面的日期目录,用于下次执行时判断是否需要删除垃圾数据的依据。

你可能感兴趣的:(Hadoop 垃圾回收机制原理及其源码分析)