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
作业,其中包含JDBC
到HDFS
的链接
我在日志中遇到以下错误:
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-hadoop200
和Hadoop 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 进行自定义查询的大型导入到单个节点时失败的主要内容,如果未能解决你的问题,请参考以下文章
sqoop 作业 shell 脚本在 oozie 中并行执行
用于验证数据库和 sqoop 之间的网络连接的 shell 脚本