为什么hadoop从大量的s3路径开始要花这么长时间?

vu8f3i0k  于 2021-05-30  发布在  Hadoop
关注(0)|答案(3)|浏览(278)

我有一个hadoop作业,它有~60k个s3输入路径。这项工作大约需要45分钟才能开始。同样的工作,只有~3k s3输入路径几乎可以立即启动。
为什么有大量的输入路径会导致作业需要很长时间才能启动?

zd287kbt

zd287kbt1#

答案与怎么做有关 FileInputPath.addInputPath(...) 已实施。如果您查看一下这里的源代码,您会发现它实际上是在执行字符串连接以将所有这些路径保存到一个文件中。打电话 addInputPaths(...) 只是打电话而已 addInputPath ,所以那里没有储蓄。最后我打了电话 FileInputPath.setInputPaths(Job, Path[]) . 这将跳过60k+字符串连接,只需构建一次设置文件的该部分。
作为 climbage 如上所述,需要对s3进行60k+调用才能构建拆分。结果表明,s3调用比字符串串联花费的时间更少。我的工作从45分钟开始到不到20分钟。
对于那些不想梳理源代码的人,下面是 FileInputFormat.addInputPath() 在hadoop 2.5.1中:

public static void addInputPath(Job job, 
                                  Path path) throws IOException {
   Configuration conf = job.getConfiguration();
    path = path.getFileSystem(conf).makeQualified(path);
    String dirStr = StringUtils.escapeString(path.toString());
    String dirs = conf.get(INPUT_DIR);
    conf.set(INPUT_DIR, dirs == null ? dirStr : dirs + "," + dirStr);
}

以及 FileInputFormat.setInputPaths() 在hadoop 2.5.1中:

public static void setInputPaths(Job job, 
                                   Path... inputPaths) throws IOException {
    Configuration conf = job.getConfiguration();
    Path path = inputPaths[0].getFileSystem(conf).makeQualified(inputPaths[0]);
    StringBuffer str = new StringBuffer(StringUtils.escapeString(path.toString()));
    for(int i = 1; i < inputPaths.length;i++) {
      str.append(StringUtils.COMMA_STR);
      path = inputPaths[i].getFileSystem(conf).makeQualified(inputPaths[i]);
      str.append(StringUtils.escapeString(path.toString()));
    }
    conf.set(INPUT_DIR, str.toString());
  }
nsc4cvqm

nsc4cvqm2#

首先 FileInputFormat 在mapreduce初始化期间是否确定输入拆分。这是通过创建每个输入文件及其信息(如文件大小)的列表来实现的。我想60kapi调用s3来获取文件信息并不快。45分钟似乎特别慢-可能也有一些速率限制?

kpbwa7wx

kpbwa7wx3#

很抱歉重新提出一个老问题,但我最近遇到了类似的问题。它的核心是,在你的情况下,hadoop将向aws发出60k个调用
要解决这个问题,可以使用通配符 FileInputFormat.addInputPath("path_to_a_folder/prefix*") 这将只生成一个aws调用来列出目录 path_to_a_folder 然后按前缀过滤
我希望这将有助于谁会发现这个问题

相关问题