【问题现象】

1、最初的Sqoop语句

sqoop export \
--connect jdbc:mysql://192.168.232.129:3306/test \
--username root \
--password password \
--export-dir /user/hive/warehouse/test_for_exam.db/jobs \
--table jobs \
--input-fields-terminated-by "\t"

【执行结果】数据成功导入但是有乱码

sqoop从mysql导入数据到hive orc表 使用sqoop将数据从hive导入mysql错误_sqoop

2、网上查找原因后的Sqoop语句

sqoop export \
--connect "jdbc:mysql://192.168.232.129:3306/test?useUnicode=true&characterEncoding=utf-8" \
--username root \
--password password \
--export-dir /user/hive/warehouse/test_for_exam.db/jobs \
--table jobs \
--input-fields-terminated-by "\t"

【执行结果】数据导入失败并报错

22/06/24 14:30:05 ERROR mapreduce.ExportJobBase: Export job failed!
22/06/24 14:30:05 ERROR tool.ExportTool: Error during export: 
Export job failed!
	at org.apache.sqoop.mapreduce.ExportJobBase.runExport(ExportJobBase.java:445)
	at org.apache.sqoop.manager.SqlManager.exportTable(SqlManager.java:931)
	at org.apache.sqoop.tool.ExportTool.exportTable(ExportTool.java:80)
	at org.apache.sqoop.tool.ExportTool.run(ExportTool.java:99)
	at org.apache.sqoop.Sqoop.run(Sqoop.java:147)
	at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
	at org.apache.sqoop.Sqoop.runSqoop(Sqoop.java:183)
	at org.apache.sqoop.Sqoop.runTool(Sqoop.java:234)
	at org.apache.sqoop.Sqoop.runTool(Sqoop.java:243)
	at org.apache.sqoop.Sqoop.main(Sqoop.java:252)

3、不断试错后,注意到关键点是编码问题

检查数据库编码和表的编码发现都不是utf-8编码:

数据库的编码:

sqoop从mysql导入数据到hive orc表 使用sqoop将数据从hive导入mysql错误_hive_02

表的编码:

sqoop从mysql导入数据到hive orc表 使用sqoop将数据从hive导入mysql错误_mysql_03


【解决办法】

  1. 方式一:修改数据库和表的编码,再次执行Sqoop语句即可。记得加上?useUnicode=true&characterEncoding=utf-8
  2. 方式二:从根部修改,一次性解决问题。
# 查看一MySQL下字符集
show variables like 'character_set%';

sqoop从mysql导入数据到hive orc表 使用sqoop将数据从hive导入mysql错误_sqoop_04

这里可以很明显的看到,字符集全错了。

MySQL 字符集大体可以分为下面两个方面:

  1. Server 级别字符集
    Server 级别的字符集,即数据存储到数据库时使用的字符集,又可以细化分为库级别、表级别和字段级别;
    一般来说,如果建库建表时没有特别指定,那么就会使用 Server 级别的字符集;
    Server 级别的字符集可以使用 character_set_server 参数指定;
  2. Client 级别字符集
    Client 级别的字符集,即客户端连接进数据库时使用的字符集,分别由下面几个参数控制:
    character_set_client:Server认为Client发送过来的请求是用该参数进行编码的,因此在收到请求后会使用该参数进行解码;
    character_set_connection:Server内部处理请求字符串时,会从character_set_client转为character_set_connection,因此两个参数要一致;
    character_set_results:Server返回查询结果给Client时,会根据character_set_results进行编码,然后再返回,因此也需要和character_set_client保持一致;

开始修改:

# 1、修改MySQL配置文件
vi /etc/my.cnf
# 在[mysqld]后添加
character-set-server=utf8
# 在[mysql]或[cilent]后添加
default-character-set=utf8

# 2、重启MySQL
service mysqld restart

修改成功后:

sqoop从mysql导入数据到hive orc表 使用sqoop将数据从hive导入mysql错误_sqoop_05

【注】第二种方法修改过后,之前创建的数据库和表都需要手动修改一下。之后编写Sqoop语句时就不需要额外写?useUnicode=true&characterEncoding=utf-8了。方便的话Hive也可以重新初始化一下(因为编码还是之前的,不知道如果不修改的话会不会有什么问题)。