hadoop fs -get命令源码分析

Created with Raphaël 2.1.2 FsShell::run FsShell::init 初始化FsShell,在工厂 类中注册各种命令对应处理类 op1 调用命令处理类的run方法 实际是调用的Command::run方法 op2 processOptions(args)解析命令行入参进行配置 op3 processRawArguments(args) op4 expandArguments(args)将入参中的路径下的文 件进行解析,转换得到PathData数组 op5 processArguments(pathDatas) op6 pathDatas.hasNext? processArgument(pathData) op7 pathData.exist (传的路径对应的文件 在文件系统是否存在) processPathArgument(item) cond78yes processPaths(items) op8 items.hasNext? processPath(item),如果item对应为目录,且设置了 循环遍历(入参中有-R),循环遍历,处理完成后调 用postProcessPath方法进行后续处理 End processNonexistentPath(item) cond78no yes no yes no yes no

  本人第一次用markdown画流程图,而且还有点小复杂,上图将就着看吧,结合代码理解起来相对简单。。 上图的流程主要体现的是hadoop fs xxx 提交到集群后执行的逻辑,当然这里主要是进入具体代码后的逻辑,进入代码前,以上命令主要是调用的$HADOOP_HOME/bin hadoop 这个脚本,通过这个脚本里面逻辑是:

if [ "$COMMAND" = "fs" ] ; then
CLASS=org.apache.hadoop.fs.FsShell
...
exec "$JAVA" $JAVA_HEAP_MAX $HADOOP_OPTS $CLASS "$@"

  显然通过hadoop fs xxx 调用脚本的时候,后面的fsxxx均是脚本的参数,只是第一个fs是脚本运行判断调用哪块逻辑的参数,而后面的参数xxx中则是用于给具体java执行类(这里是FsShell)的参数。
  上图流程是hadoop fs xxx这一系列命令提交执行的基本流程,这一块中涉及到的处理类主要都是继承自Command.java,主要涉及类的作用如下:

FsShell.java 业务入口
CommandFactory.java 各种不同类型请求的处理类工厂
Command.java FsCommand的父类,是一个抽象类
FsCommand.java 抽象类,代码注释说的很清楚:Base class for all "hadoop fs" commands 所有类型请求均继承自它
PathData.java 文件系统中某个路径对应的逻辑实体类,封装了这个路径所属文件系统信息、路径信息、路径下的文件信息以及文件是否存在等

  以上是一些针对hadoop fs整体处理逻辑设计的基础类,对于具体的请求类型常用的如:getlsputrm等命令,处理类可以在FsCommand.javaregisterCommands方法中查看到往工厂中注册的类:

    factory.registerCommands(AclCommands.class);
    factory.registerCommands(CopyCommands.class);
    factory.registerCommands(Count.class);
    factory.registerCommands(Delete.class);
    factory.registerCommands(Display.class);
    factory.registerCommands(FsShellPermissions.class);
    factory.registerCommands(FsUsage.class);
    factory.registerCommands(Ls.class);
    factory.registerCommands(Mkdir.class);
    factory.registerCommands(MoveCommands.class);
    factory.registerCommands(SetReplication.class);
    factory.registerCommands(Stat.class);
    factory.registerCommands(Tail.class);
    factory.registerCommands(Test.class);
    factory.registerCommands(Touch.class);
    factory.registerCommands(SnapshotCommands.class);
    factory.registerCommands(XAttrCommands.class);
  }

  对于开篇的流程图中,每个不同的业务处理类,主要核心的处理逻辑都在processPath(PathData src)方法中,其它的方法主要是一些流程控制、验证以及异常处理等,这里我们挑选get方法对应的CopyCommands.class进行介绍,这个CopyCommands.class类是对于文件复制类命令的合集,其中有registerCommands,这个方法主要就是注册各类需要处理的类到工厂类中(存在工厂类中的一个HashMap中,后续需要用时直接通过命令行参数如get字符串进行map.get()获取),其调用顺序是FsShell::run->FsShell::init->FsShell::registerCommands->CommandFactory::registerCommands,在工厂类CommandFactory::registerCommands中通过反射调用FsShell::registerCommands中入参FsCommandregisterCommands方法,这个方法也是通过反射的方式调用各个入参类中的registerCommands方法,这就是CopyCommands.classregisterCommands调用的路径,其它处理类调用注册逻辑一样。
  继续来看CopyCommands.class,其中除了registerCommands,主要就是提供了七个静态公共类,我们这里对于get请求,处理类就是Get.class,继承了一个类叫CommandWithDestination,这里查看Get.class的代码,只是实现了processOptions对参数进行设置,核心逻辑在它的父类中,继续进入父类CommandWithDestination中,发现父类果然是继承自FsCommand,这里主要看它的核心处理方法processPath,调用顺序:processPath(PathData src)->processPath(PathData src, PathData dst)->copyFileToTarget(PathData src, PathData target),到了copyFileToTarget方法这里的话,逻辑就十分明了了,贴出该部分代码:

      throws IOException {
    final boolean preserveRawXattrs =
        checkPathsForReservedRaw(src.path, target.path);
    src.fs.setVerifyChecksum(verifyChecksum);
    InputStream in = null;
    try {
      in = src.fs.open(src.path);
      copyStreamToTarget(in, target);
      preserveAttributes(src, target, preserveRawXattrs);
    } finally {
      IOUtils.closeStream(in);
    }
  }

  该部分代码先获取了系统设置目标路径下是否需要保存源文件的元数据信息(例如创建时间、所属用户、所属用户组等),然后获取源文件的输出流,并调用copyStreamToTarget方法将输出流中内容写入到目标路径中,最后再调用preserveAttributes进行基本信息元数据信息的填充。
参考文章:
https://blog.csdn.net/strongyoung88/article/details/68952248

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值