使用 sqoop 导入 Hive 时获取文件存在错误

Getting an file exists error while import into Hive using sqoop

我正在尝试将 retail_db 数据库表复制到我已经创建的配置单元数据库中。当我执行下面的代码时

sqoop import-all-tables \
--num-mappers 1 \
--connect "jdbc:mysql://quickstart.cloudera:3306/retail_db" \
--username=retail_dba \
--password=cloudera \
--hive-import \
--hive-overwrite \
--create-hive-table \
--outdir java_files \
--hive-database retail_stage

我的 Map-reduce 作业因以下错误而停止:

ERROR tool.ImportAllTablesTool: Encountered IOException running import job: org.apache.hadoop.mapred.FileAlreadyExistsException: Output directory hdfs://quickstart.cloudera:8020/user/cloudera/categories already exists

我正在尝试将表复制到配置单元数据库,那么为什么 cloudera 中的现有文件导致了问题。有没有办法忽略此错误或覆盖现有文件。

Sqoop 导入 Hive 只需 3 个步骤:

  • 将数据放入HDFS
  • 创建 Hive table 如果不存在
  • 将数据加载到 Hive Table

你没有提到 --target-dir--warehouse-dir,所以它会将数据放在 HDFS 主目录中,我相信你的情况是 /user/cloudera/

现在对于 MySQL table categories 您可能之前已经导入了它。因此,/user/cloudera/categories 目录存在并且您收到此异常。

添加 --taget-dir 中任何不存在的目录,如 --taget-dir /user/cloudera/mysqldata。然后sqoop会把上面命令导入的所有Mysql Table都放在这个位置

这就是 sqoop 导入作业的工作方式:

  • sqoop creates/imports tmp dir(HDFS) 中的数据,这是用户的主目录(在你的例子中是 /user/cloudera).

  • 然后将数据复制到其实际的配置单元位置(即/user/hive/wearhouse.

  • 这个 categories 目录应该在您 运行 import 语句之前存在。所以删除该目录或重命名它(如果它很重要)。

hadoop fs -rmr /user/cloudera/categories

hadoop fs -mv /user/cloudera/categories /user/cloudera/categories_1

并重新运行 sqoop 命令!

所以简而言之,导入到 Hive 将使用 hdfs 作为暂存位置,sqoop 在复制(成功)到实际 hdfs 位置后删除暂存目录 /user/cloudera/categories - 这是 sqoop 作业的最后阶段清理 staging/tmp 个文件 - 因此如果您尝试列出 tmp 暂存目录,您将找不到它。

成功导入后:hadoop fs -ls /user/cloudera/categories - 目录将不存在。

您不能同时使用 hive-importhive-overwrite

我确认这个问题的版本是;

$ sqoop help import

--hive-overwrite Overwrite existing data in the Hive table

$ sqoop version

Sqoop 1.4.6-cdh5.13.0

参考。

根据上面的答案 #1,我找到了 this。我试过了,效果很好。

所以,只需添加 --delete-target-dir