HDFS数据快速拷贝方案:FastCopy

前言


我们在使用HDFS的时候,往往有的时候需要做一些临时的数据拷贝操作,如果是在同一个集群中的,我们直接用HDFS内部自带的cp这些命令即可;如果是跨集群的时候或者说待拷贝数据量规模非常大的时候,我们还可以使用DistCp工具。但是这是否意味着我们使用这些工具在拷贝数据的时候依然是高效的呢?答案其实并不是这样的。在许多比较早使用Hadoop的公司,估计都或多或少遇到过拷贝大规模数据效率不高的情况。比如说,FaceBook在其内部的Hadoop版本中开发了一种叫做FastCopy的数据快速拷贝工具。目前在JIRA上也有相应的记录:HDFS-2139(Fast copy for HDFS)。本节我们要讲述的主题正是FastCopy工具。

FastCopy的原理介绍


FastCopy与传统的数据拷贝之间的一个主要不同点在于它尽可能地让数据拷贝发生在本地,以此减少跨节点间的数据传输。并且在FastCopy的本地数据拷贝过程中,还能通过对文件创建一个新的硬链接的方式,而无须做真正的数据拷贝操作。HDFS硬链接的相关内容可以阅读本人之前的一篇文章:HDFS符号链接和硬链接。HDFS内部的硬链接在FaceBook内部也已经早已实现。

下面我们来学习FastCopy快速拷贝工具的一个主要原理:

1)查询待拷贝文件的所有block块信息。
2)获取这些源文件块信息所在的位置信息。
3)对于源文件的每个块,在NameNode内部对应创建一个空的目标块,这些目标块的存储位置尽可能与源块最后一致。
4)然后命令DataNode做一个本地的块拷贝操作。
5)然后等待块拷贝完成操作,然后上报到NameNode上。

对于上述过程中的第4步,可以直接利用硬链接来做。OK,这里的过程是一个FastCopy工具拷贝数据内部的过程,那么我们从大一点的角度来观察,FastCopy工具的总流程是怎样的呢,答案如下:

1.首先输入待拷贝的目标路径,这里可以为纯文件或目录。
2.第一步骤中输入的路径会转化为一个个FastCopy的请求。
3.这些请求会提交到一个线程池中去执行。
4.根据拷贝过程中的源块,目标块的所在节点位置,分别执行普通方式的DataCopy或是本地方式的LocalCopy两种拷贝操作。

此过程原理图如图1-1所示。




图 1-1 FastCopy数据拷贝过程

FastCopy原理部分的内容主要在于上面2点。上面的步骤细节大家在后面的关键代码分析中可以进行对应地查找。

FastCopy核心代码分析


在核心代码分析部分,我们将主要关注2个模块的实现:

  • FastCopy工具如何尽可能地让块在本地进行复制。
  • FastCopy在数据拷贝时具体是如何执行的。

首先是第一个点的内容:在FastCopy中,是如何保证块尽量在本地复制呢?要想解答这个问题,我们先回到之前FastCopy的快速拷贝原理,其中有这么一个过程:

对于源文件的每个块,在NameNode内部对应创建一个空的目标块,这些目标块的存储位置尽可能与源块最后一致。

在这步过程的执行时,会将查询到的源块的位置信息优先作为目标创建块的位置信息。这样就保证了目标拷贝块和源快是在同一个节点上了。这里为什么指明说是优先呢,而不是绝对肯定的说法呢?因为这里还要考虑到目标盘上的存储空间够不够用的问题,如果目标存储的盘的可用空间不足,那么这个位置将不可用。然后NameNode将会选择下一个存储位置。

此部分代码如下:

    /**
     * Copy the file.
     * @return result of the operation
     */
    private CopyResult copy() throws Exception {
      // 获取源文件信息,并准备创建空目标文件
      HdfsFileStatus srcFileStatus = srcNamenode.getFileInfo(src);
      if (srcFileStatus == null) {
        throw new FileNotFoundException("File : " + src + " does not exist");
      }
      LOG.info("Start to copy " + src + " to " + destination);
      try {
        ...
        LinkedList<LocatedBlock> blocksList = new LinkedList<LocatedBlock>();
         LocatedBlock previousAdded = null;
         do {
           lastStart = lastEnd;
           // 获取源文件
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值