我正在尝试将数据从HDFS导出到SQL Server。原始表有超过500列,每次执行Sqoop导出作业时都会卡住,显示mapreduce完成100%。我创建了两个虚拟表,如下所示,以找出确切问题持续存在的位置。 table1和table2之间的唯一区别是后者有一个额外的列[col14 varchar(5)]
首先,我为Table1运行了导出作业,其中包含13列[datatype varchar(5)]。作业成功完成并将所有3条记录导出到SQL Server。
接下来,我使用14列执行Table2的导出作业。当我运行这个工作时,我没有看到任何错误消息/异常,但它在地图完成100%后永远挂起。 SQL Server活动监视器显示正在创建进程,但它没有从Hadoop接收任何数据/预准备语句。
此问题仅存在于SQL Server中吗?导出到SQL Server的列数是否有任何限制?我是否需要调整群集中的任何配置更改?请指教。
配置
Hadoop版本 - Cloudera 2.6.0-CDH-5.5.2 | Sqoop版本 - 1.4.6 | SQL Server版本 - 2008 R2
6节点集群 - 1 NN& 5DN | Map Task - 2 GB / 1vCPU | 减少任务 - 2GB / 1vCPU
表1
CREATE TABLE [dbo].[tbldummy1]
(
[col1] [varchar] (5) NOT NULL,
[col2] [varchar](5) NULL,
[col3] [varchar](5) NULL,
[col4] [varchar](5) NULL,
[col5] [varchar](5) NULL,
[col6] [varchar](5) NULL,
[col7] [varchar](5) NULL,
[col8] [varchar](5) NULL,
[col9] [varchar](5) NULL,
[col10] [varchar](5) NULL,
[col11] [varchar](5) NULL,
[col12] [varchar](5) NULL,
[col13] [varchar](5) NULL,
CONSTRAINT [PK_dummy1] PRIMARY KEY ([col1] ASC))
Table1的Sqoop命令
sqoop export \
--connect “jdbc:sqlserver://x.x.x.x:port;database=xxxxxxx” \
--username xxxxxx --password yyyyyy \
--table tbldummy1 \
--export-dir /user/hue/Out1 \
--input-fields-terminated-by '|' \
-m 1 \
--verbose
表1的输入数据
aa|01|02|03|04|05|06|07|08|09|10|11|12
bb|01|02|03|04|05|06|07|08|09|10|11|12
cc|01|02|03|04|05|06|07|08|09|10|11|12
表2
CREATE TABLE [dbo].[tbldummy2](
[col1] [varchar] (5) NOT NULL,
[col2] [varchar](5) NULL,
[col3] [varchar](5) NULL,
[col4] [varchar](5) NULL,
[col5] [varchar](5) NULL,
[col6] [varchar](5) NULL,
[col7] [varchar](5) NULL,
[col8] [varchar](5) NULL,
[col9] [varchar](5) NULL,
[col10] [varchar](5) NULL,
[col11] [varchar](5) NULL,
[col12] [varchar](5) NULL,
[col13] [varchar](5) NULL,
[col14] [varchar](5) NULL,
CONSTRAINT [PK_dummy2] PRIMARY KEY ([col1] ASC))
表2的Sqoop命令
sqoop export \
--connect "jdbc:sqlserver://x.x.x.x:port;database=xxxxxxx" \
--username xxxxxx --password yyyyyy \
--table tbldummy2 \
--export-dir /user/hue/Out2 \
--input-fields-terminated-by '|' \
-m 1 \
--verbose
表2的输入数据
aa|01|02|03|04|05|06|07|08|09|10|11|12|13
bb|01|02|03|04|05|06|07|08|09|10|11|12|13
cc|01|02|03|04|05|06|07|08|09|10|11|12|13
表2的控制台日志
16/03/16 23:35:01 INFO mapreduce.Job: Running job: job_1458150283440_0028
16/03/16 23:35:07 INFO mapreduce.Job: Job job_1458150283440_0028 running in uber mode : false
16/03/16 23:35:07 INFO mapreduce.Job: map 0% reduce 0%
16/03/16 23:35:18 INFO mapreduce.Job: map 100% reduce 0%
答案 0 :(得分:2)
我们在最后遇到了同样的问题 - sqoop导出到SQL Server中的表达到了100%然后它只是挂起,直到达到10分钟的超时时间,之后作业失败。在我们的调查中,我们发现其原因实际上是SQL Server端的复合主键冲突,我们对hadoop集群端没有任何可见性。解决了这个PK违规问题后,sqoop导出成功完成。
我还想指出访问权限不是问题,我们通过成功运行sqoop eval的insert来测试它,这完成没有问题。
作为您的下一步,我建议您首先通过运行sqoop eval来测试您的写访问权限。确认您可以通过sqoop eval在目标表中插入记录后,继续并列出SQL Server中的目标表所执行的所有约束,然后在数据湖中添加适当的逻辑以防止此类记录被导出到SQL Server。如果您可以确保导出到SQL Server的数据不违反SQL Server端的任何约束,则应解决您的sqoop导出问题。如果这不能解决您所面临的问题,请告诉我们。
答案 1 :(得分:0)
您的 xxxxxxx 数据库中 xxxxxx 用户的权限似乎有问题。在映射阶段之后的导出操作中,作业尝试执行插入更新查询,但如果它没有用户名的nessecary权限,则可能会卡住。尝试将db_writer角色分配给您的用户。另一个选项,如果可能的话,尝试在 sa 帐户下执行操作,以了解是否是这种情况。
答案 2 :(得分:0)
您的错误日志没有显示多少堆栈,以了解我建议检查故障节点的纱线日志的错误。
在检查SQL Server端的问题之前,我已经调整了你的sqoop作业,尝试进行这些更改,我很确定它会解决你所面临的问题。
#Changes Made - #Increase the number of mappers to 8 or 10 for faster process
#columns mapping - You have to give your column names in SQL server table in the sequence to match with your file
sqoop export \
--connect "jdbc:sqlserver://x.x.x.x:port;database=xxxxxxx" \
--username xxxxxx --password yyyyyy \
--table tbldummy2 \
--export-dir /user/hue/Out2 \
--input-fields-terminated-by '|' \
-m <increase to higher number depending on your cluster> \
--columns "col1,col2,col2"
--verbose