hive/spark-sql : Cannot find DistCp

最近发现spark-sql执行insert overwrite等操作时 最后move文件是一个一个的操作,效率较低而且还会存在bug(具体bug其余文章讲解)。因此进行了修改,修改后发现如下报错。

Caused by: java.io.IOException: Cannot find DistCp class package: org.apache.hadoop.tools.DistCp
    at org.apache.hadoop.hive.shims.Hadoop23Shims.runDistCp(Hadoop23Shims.java:1158)
    at org.apache.hadoop.hive.common.FileUtils.copy(FileUtils.java:553)
    at org.apache.hadoop.hive.ql.metadata.Hive.moveFile(Hive.java:2625)

网上遇到同样问题的人很多,一般的解决办法都是找到hadoop-distcp-*.jar放到Spark/hive的CLASSPATH里。但这样其实治标不治本,move文件操作在不跨ns的情况下就不应该有distcp操作。否则效率很低。
分析Hive.java源码,发现如下一段, FileUtils.copy操作是产生distcp的原因。而之所以走进这段逻辑是因为destIsSubDir是true。

boolean destIsSubDir = isSubDir(srcf, destf, fs, isSrcLocal);
...
...
if (destIsSubDir) {
            FileStatus[] srcs = fs.listStatus(srcf, FileUtils.HIDDEN_FILES_PATH_FILTER);
            if (srcs.length == 0) {
              success = true; // Nothing to move.
            }
            for (FileStatus status : srcs) {
              success = FileUtils.copy(srcf.getFileSystem(conf), status.getPath(), destf.getFileSystem(conf), destf,
                  true,     // delete source
                  replace,  // overwrite destination
                  conf);

              if (!success) {
                throw new HiveException("Unable to move source " + status.getPath() + " to destination " + destf);
              }
            }
          } else {
            success = fs.rename(srcf, destf);
          }

顺着根往上分析,发现是hive.exec.stagingdir参数惹的祸。如果临时目录在目标表下就会触发,因此如果不想copy hadoop-distcp-*.jar的话,那就修改临时路径吧!

你可能感兴趣的:(错误总结)