问题简介
最近业务方反馈依照导入MySQL表导入Hive有部分字段变更乱码,于是乎走上了解决乱码的不归路。
集群信息
服务器系统版本:centos 7.2
cdh 版本:cdh5.9.0
hadoop 版本:2.6.0+cdh5.9.0
hive 版本:1.1.0+cdh5.9.0
sqoop 版本:1.4.6+cdh5.9.0
备注:涉及敏感信息的的变量,使用${xxxx} 代替
问题定位
首先,导入乱码想都不用想,肯定要确定mysql数据库编码是否有问题
于是乎打开导入mysql数据库检查一遍编码
show variables like 'character%'
结果很满意,编码都是utf-8
检查导入用的MySQL链接配置,已经添加了
useUnicode=true&characterEncoding=utf-8
这还乱码!!!这还乱码!!!这还乱码!!! 不科学啊!!!!
同一张表中同样是中文字段有的乱码有的不乱,猜想是否字段类型问问题
查看表字段信息
果然,字段类型不相同,但编码都是utf-8,于是乎确定问题跟数据库编码和链接编码无关,可能跟字段类型有关。初步定位到sqoop导入MySQL字段类型为JSON会乱码。高兴了,开心了,问题貌似找到了,于是乎百度,google关键词:
sqoop 导入 MySQL 字段类型 JSON 乱码
结果惨不忍睹,跟sqoop 相关的 json 乱码没有,好不容易找到一篇文章介绍,升级jdbc版本可以解决JAVA读取MySQL JSON 字段乱码的问题;还有另一篇文档介绍:通过升级jdbc版本解决datax导入MySQL JSON 字段乱码问题。
于是乎尝试升级项目中使用的JDBC版本,但导入JSON乱码还是没解决!
度娘,google没相关文章,可能解决的办法尝试了还不行。我太难啦!!我太难了!!太难了!!
没办法了,只能去看sqoop的原码了,关于sqoop原码解读这两篇文章很良心 文章一 文章二
撸出看源码关心的点
关于导入字段处理的两个点
导入数据库类型到java的映射(org.apache.sqoop.manager.ConnManager)
/**
* Resolve a database-specific type to the Java type that should contain it.
* @param sqlType sql type
* @return the name of a Java type to hold the sql datatype, or null if none.
*/
public String toJavaType(int sqlType) {
// Mappings taken from:
// http://java.sun.com/j2se/1.3/docs/guide/jdbc/getstart/mapping.html