问题描述
将MySql中的数据通过Sqoop迁移到Hive中,实现MySql<-->Hive数据流通体系;
执行Sqoop命令后,报错无法找到目标数据库,显示导入失败,但hive中却真实导入了部分数据,属于是半成功
Sqoop命令
root@master:/opt/sqoop-1.4.7.bin__hadoop-2.6.0/bin# sqoop import \ --connect jdbc:mysql://127.0.0.1:3306/bookhub?useSSL=false \ --username debian-sys-maint \ --password 123456 \ --table applications \ --hive-import \ --hive-overwrite \ --hive-table bookhub.applications \ --input-fields-terminated-by '\001'
日志报错(因为第二次遇到这个问题才解决,因此图例有些不对应)
Error: java.lang.RuntimeException: java.lang.RuntimeException: java.sql.SQLSyntaxErrorException: Unknown database 'test1'
日志显示无法在数据库中查找到目标数据库‘test1’
原因
因为搭建的是Hadoop集群模式,执行时会将Sqoop命令发送到集群中的其他主机中去执行,但是其他集群中并没有相应的mysql数据库,也就是找不到"目标数据库‘test1’"这个报错;
重点在于Sqoop命令中的"127.0.0.1"表明要求本机数据库,因此导致报错;
解决
修改"127.0.0.1"为"master"主机,因为mysql数据库储存在master主机上
# Sqoop命令 ./sqoop import \ --connect jdbc:mysql://master:3306/bookhub?useSSL=false \ --username root \ --password 123456\ --table users \ --hive-import \ --hive-table bookhub.users \ --target-dir /user/hive/warehouse/bookhub.db/users \ --fields-terminated-by '\001' # 注意需要先删除hdfs中的相应目录数据 hdfs dfs -rm /user/hive/warehouse/bookhub.db/users/* hdfs dfs -rmdir /user/hive/warehouse/bookhub.db/users # 使用root用户是因为我设置了远程访问数据库的用户就是root,集群中对master数据库的访问是远程访问 --username root \ --password 123456\ # 还可能遇到Public Key Retrieval is not allowed问题,及时更新驱动即可
最后任务完成
但Hive表的数据出现异常
原因
在创建Hive表时设置了表的字符间隔为',',但MySql未定义
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',';
因此,原始MySQL数据的格式不符合Sqoop命令中指定的分隔符,导致Sqoop传输过程中将数据识别成了一个字段,其他值就全为null。
解决
1.创建Hive表时设置字符间隔与MySql默认的字符间隔(空格)相同
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\u0001';
2.Sqoop命令中也要设置相同的字符间隔(空格)
--fields-terminated-by '\001'