Sqoop-2 在使用 sqoop shell 进行自定义查询的大型导入到单个节点时失败

Posted

技术标签:

【中文标题】Sqoop-2 在使用 sqoop shell 进行自定义查询的大型导入到单个节点时失败【英文标题】:Sqoop-2 fails on large import to single node with custom query using sqoop shell 【发布时间】:2016-02-12 17:39:19 【问题描述】:

我正在对由计算量大的自定义查询生成的大型记录集进行原型迁移。此查询大约需要 1-2 小时才能在 SQL Developer 中返回结果集

我正在尝试将此查询传递给一个简单的Sqoop 作业,其中包含JDBCHDFS 的链接

我在日志中遇到以下错误:

2016-02-12 10:15:50,690 错误 mr.SqoopOutputFormatLoadExecutor [org.apache.sqoop.job.mr.SqoopOutputFormatLoadExecutor$ConsumerThread.run(SqoopOutputFormatLoadExecutor.java:257)] 从 MR 作业中加载数据时出错。 org.apache.sqoop.common.SqoopException:GENERIC_HDFS_CONNECTOR_0005:加载程序运行期间发生错误 在 org.apache.sqoop.connector.hdfs.HdfsLoader.load(HdfsLoader.java:110) 在 org.apache.sqoop.connector.hdfs.HdfsLoader.load(HdfsLoader.java:41) 在 org.apache.sqoop.job.mr.SqoopOutputFormatLoadExecutor$ConsumerThread.run(SqoopOutputFormatLoadExecutor.java:250) 在 java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) 在 java.util.concurrent.FutureTask.run(FutureTask.java:266) 在 java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 在 java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 在 java.lang.Thread.run(Thread.java:745) 原因:org.apache.hadoop.ipc.RemoteException(org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException):/user/username/schema/recordset/.72dee005-3f75-4a95-bbc0-30c6b565d193 上没有租约/f5aeeecc-097e-49ab-99cc-b5032ae18a84.txt(inode 16415):文件不存在。 [租。持有者:DFSClient_NONMAPREDUCE_-1820866823_31,pendingcreates:1]

当我尝试检查 hdfs 中生成的 .txt 文件时,它们是空的。

有没有人遇到并解决过这个问题?另外,我注意到Sqoop shell 的额外错误。例如,我无法检查作业状态,因为它总是返回 UNKNOWN。

我正在使用sqoop-1.99.6-bin-hadoop200Hadoop 2.7.2 (Homebrew install)。我正在使用Generic JDBC Connector 查询远程Oracle 11 数据库。

我已经使用create job 中的schema/table 参数执行了一个较小的导入工作

我很想逐表迁移整个模式表,然后只需使用 Hive 生成​​和存储我想要的记录集。这会是一个更好/更简单的解决方案吗?

【问题讨论】:

对于大多数人来说,“Sqoop”是指最初的、久经考验的实用程序,也就是“Sqoop 1”(当前版本是 1.4.6)——我不确定有多少人会信任他们的“Sqoop 2”上的生产系统,又名“总有一天我们会填补功能空白并修复问题,实际上达到 2.0 标记,然后弃用 V1,再给我们几年时间”。 @SamsonScharfrichter 感谢您的建议。我更改了问题以反映其 Sqoop2。我应该回归到 1.4.6 吗?它适用于我的 Hadoop 安装吗? 实际上,我不确定这是否会有所作为,这是 1 小时的延迟让您丧命。 Sqoop1 就像 Pig,它是一个胖客户端,使用核心 Hadoop 服务(HDFS + YARN + 可选的 Hive MetaStore),但按照自己的节奏发展;顺便说一句,如果默认情况下它没有捆绑在您的发行版中,我会感到惊讶。 【参考方案1】:

org.apache.hadoop.hdfs.server.namenode.LeaseExpiredException

此查询大约需要 1-2 小时才能在 SQL 中返回结果集 开发者

我敢打赌 Sqoop 1.99 会创建一个空的 HDFS 文件 (即 NameNode 收到请求,创建文件但尚未为其他客户端实现它,为 Sqoop 授予独占写入租约,并分配责任将 block#1 写入随机 DataNode) 然后等待 JDBC ResultSet 生成一些数据……同时不进行任何保持活动。

但是,60 分钟后,NameNode 只是看到租约已过期,而没有任何 Sqoop 客户端处于活动状态的迹象,因此它关闭了文件——或者更确切地说,好像它从未创建(从未发生过刷新)。

您是否有机会通过 Oracle 方面的 /*+ FIRST_ROWS */ 提示来减少时间流逝?

【讨论】:

如果您愿意接受以 Oracle 为中心的解决方案,您可以尝试贿赂 Oracle DBA 以设置 DataPump 文件导出,您可以使用 EXEC 触发该文件导出,以及某种文件传输从 Oracle 机器到 HDFS(例如使用 WebHDFS REST 接口)。总的来说,它可能更高效、更可靠。但它涉及开发和运营中的 Oracle 人员。 警告 - AFAIK WebHDFS no 进行任何类型的完整性检查,因此您最好仅对压缩文件使用它(CRC32 = 可怜人的完整性检查)。 不幸的是,我几乎无法控制 Oracle 服务器。但是,当可以控制整个堆栈时,这似乎是一个有效的解决方案。

以上是关于Sqoop-2 在使用 sqoop shell 进行自定义查询的大型导入到单个节点时失败的主要内容,如果未能解决你的问题,请参考以下文章

使用 Hue sqoop 2 从 vertica 获取数据

sqoop 作业 shell 脚本在 oozie 中并行执行

用于验证数据库和 sqoop 之间的网络连接的 shell 脚本

为啥我在 Azkaban 中的 Sqoop 任务在选择列后卡住了?

与 Sqoop 不一致的结果

Sqoop2使用方法简介