解决sqoop从mysql库导入到hadoop个别数据错位的问题(非分隔符原因导致)

起因是应用层的数据出现误差,比正确的数据少了1条,在检查了代码之后发现并无问题,而且考虑到如果真的是代码问题,那么为什么独独差了这么1条。所以我就怀疑是模型层或者贴源层的数据存在问题,于是先检查模型层,果然出现了几条数据错位,顺着往上找,问题根源在于贴源层。

所以我猜想肯定是调度的时候出现了什么故事。

贴下我发生问题的sqoop参数:

#!/bin/sh

/home/master/software/sqoop/bin/sqoop import  \

--connect jdbc:mysql://地址/数据库名  \

--username 用户名 \

--password 密码 \

--table 表名 \

--fields-terminated-by "\t"  \

--hive-delims-replacement "@" \

--lines-terminated-by "\n" \

--hive-import  \

--hive-overwrite  \

--delete-target-dir \

--hive-database  数据库 \

--hive-table 表名 \

-m 1 \

这个脚本说起来是种非常偷懒的调度方式,一不用自己建表,二不用指定hdfs目录,源库的表是什么样子,导入到hadoop后就是什么样子。缺点也很明显,太呆板,不能自由选择字段,也不能对字段进行微处理,而且调度过来的字段数据类型也会发生改变。

一开始我以为是分隔符不合适,毕竟从一开始就在分隔符这里吃过大亏,于是前后更换了十来个分隔符,包括(\u0000\u0001\u0002\u0003\u0004\u0005\u0006\u0007等,具体还有啥请参考大神的文章:Hive分隔符_飞朋的博客-CSDN博客_hive分隔符)试了个遍,重新调度,结果总是这几条数据的某个字段往后错了一位。因此基本上靠更换分隔符的方式没有什么希望了。

我研究了一下异常数据的特征,发现可能是某个字段被一拆为二了,导致后续字段统统错位,所以尝试着换一种方式调度,即加入参数columns,这个参数可以让我们自由选择字段,在去掉了最开始发生错位的那个字段之后重新调度,跟我想的没错,剩下的字段结果正常了,贴下加了参数的脚本:

#!/bin/sh

/home/master/software/sqoop/bin/sqoop import  \

--connect jdbc:mysql://地址/数据库名  \

--username 用户名 \

--password 密码 \

--table 表名 \

--columns 字段1,字段2,字段3 \

--fields-terminated-by "\t"  \

--hive-delims-replacement "@" \

--lines-terminated-by "\n" \

--hive-import  \

--hive-overwrite  \

--delete-target-dir \

--hive-database  数据库 \

--hive-table 表名 \

-m 1 \

然而虽然剩下的字段结果正常,总不能丢下那个出问题的不管,所以我又尝试了另外一种调度方式,query的参与,这个相对于columns参数来说,更麻烦,需要指定target-dir的目录,但更自由,可以用hive语句来对数据进行细微的处理。

#!/bin/sh

/home/master/software/sqoop/bin/sqoop import  \

--connect jdbc:mysql://地址/数据库名  \

--username 用户名 \

--password 密码 \

--query "select 字段1,字段2,字段3 where \$CONDITIONS" \

--delete-target-dir \

--fields-terminated-by "\t" \

--hive-delims-replacement "\001" \

--lines-terminated-by "\n"  \

--hive-import  \

--hive-overwrite  \

--target-dir /user/hive/warehouse/pdd.db/video \

--hive-database  数据库 \

--hive-table 表名 \

-m 1 \

在研究了发生问题数据之后,发现这几条数据的共同特征是字段的值前面有空格,所以首先用了trim函数去掉了这个字段的空格,结果很意外,没有用。

正发愁,突然看到了键盘上的TAB键。没错,伪装成空格的TAB键,用了replace函数把TAB去掉,终于解决了这个困扰大半天的问题。

另外解决问题时有几个小插曲,有的是因为马虎,有的是因为懂得少,也分享一下吧。

首先是报错Unknown column '' in 'field list',这个明面上意思是在源库找不到对应的字段,我检查之后发现在更换query的时候忘记删掉columns这个单词了,它作为字段在源库中当然找不到。

然后是报错ERROR tool.ImportTool: Encountered IOException running import job: java.io.IOException: Query [select 字段1,字段2,字段3from pdd_video] must contain '$CONDITIONS' in WHERE clause.这个错包含信息也很明显,query后面没有加where \$CONDITIONS,我不懂为什么要加这个,但不加就报错。

最后是At minimum, you must specify --connect and –table Arguments to mysqldump and other subprograms may be supplied after a '--' on the command line. ./sqoop_import_video1.sh:行4: --username: 未找到命令。基本上这种问题都是参数后面没有加‘\’这个符号,或者加了符号但符号前面没有加小空格,一定要注意加空格啊。

这个问题总结起来思路如下:发现问题-检查代码-检查上层数据-检查上游数据-检查调度命令-检查异常数据具体的值的特征-找到问题根本-寻找解决方案-解决问题并复盘。

最后仍有个疑问,是不是在调度的过程中,字段的分割全部都是默认用TAB处理的,所以字段的值中存在TAB这个大空格之后,就出现了字段一分为二的情况?希望有大佬能给解答。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值