Hive 使用 load inpath 导入数据时出现 NULL 原因解析

最近给测试造一些 hive 的测试数据,先是使用 sqoop 从 mysql 导出数据到 hdfs,然后从 hdfs 导入数据到 hive。这是背景。

问题

在把 hdfs 上数据导入到 hive 表的时候,显示导入成功。

[root@hd-node1 ~]# hdfs dfs -ls /data/sqoop/test1_text
18/10/19 00:36:11 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 1 items
-rw-r--r--   1 root supergroup          0 2018-09-23 15:52 /data/sqoop/test1_text/_SUCCESS

并且统计记录行数也是正确的。

hive> select count(*) from test_data_100w.test1_text;
Query ID = root_20181019005050_5d16fe1b-1964-4831-ba0b-371ea3b20d44
Total jobs = 1
Launching Job 1 out of 1
Number of reduce tasks determined at compile time: 1
In order to change the average load for a reducer (in bytes):
  set hive.exec.reducers.bytes.per.reducer=<number>
In order to limit the maximum number of reducers:
  set hive.exec.reducers.max=<number>
In order to set a constant number of reducers:
  set mapreduce.job.reduces=<number>
Starting Job = job_1539108956909_0025, Tracking URL = http://hd-node1:8088/proxy/application_1539108956909_0025/
Kill Command = /opt/hadoop-2.6.0-cdh5.10.0/bin/hadoop job  -kill job_1539108956909_0025
Hadoop job information for Stage-1: number of mappers: 2; number of reducers: 1
2018-10-19 00:50:26,009 Stage-1 map = 0%,  reduce = 0%
2018-10-19 00:50:30,353 Stage-1 map = 50%,  reduce = 0%, Cumulative CPU 2.09 sec
2018-10-19 00:50:33,440 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 3.89 sec
2018-10-19 00:50:36,537 Stage-1 map = 100%,  reduce = 100%, Cumulative CPU 5.83 sec
MapReduce Total cumulative CPU time: 5 seconds 830 msec
Ended Job = job_1539108956909_0025
MapReduce Jobs Launched: 
Stage-Stage-1: Map: 2  Reduce: 1   Cumulative CPU: 5.83 sec   HDFS Read: 23491228 HDFS Write: 7 SUCCESS
Total MapReduce CPU Time Spent: 5 seconds 830 msec
OK
100000
Time taken: 28.08 seconds, Fetched: 1 row(s)
hive>

悲剧的是查询数据都是 NULL,如图所示:

hive-table-null.jpg

分析

如果出现数据为 NULL,一般都是因为在创建 hive 表的时候没有指定 列分隔符

我在创建表的时候直接使用了简单的方式:

CREATE TABLE `test_data_100w.test1_text`(
  `id` int, 
  `name` varchar(100)
}

看一下 sqoop 导出的文件中数据是怎么组织的。

[root@hd-node1 ~]# hdfs dfs -ls /data/sqoop/test10
18/10/19 01:15:53 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
Found 5 items
-rw-r--r--   1 root supergroup          0 2018-09-23 16:06 /data/sqoop/test10/_SUCCESS
-rw-r--r--   1 root supergroup    4870859 2018-09-23 16:06 /data/sqoop/test10/part-m-00000
-rw-r--r--   1 root supergroup    4881316 2018-09-23 16:06 /data/sqoop/test10/part-m-00001
-rw-r--r--   1 root supergroup    4880618 2018-09-23 16:06 /data/sqoop/test10/part-m-00002
-rw-r--r--   1 root supergroup    4880413 2018-09-23 16:06 /data/sqoop/test10/part-m-00003
[root@hd-node1 ~]# hdfs dfs -cat /data/sqoop/test10/part-m-00000
24997,康慨,40,2017-07-19 00:00:00.0,15200001111,65.51530571495157,四川省江油市洞庭湖广场138号-2-5,盖州画留航派贸易有限公司,le6l@sohu.com,371422199803278539
24998,顾卤,27,2017-07-19 00:00:00.0,15200002222,3302.0383016504006,湖南省岳阳市热河大厦90号-10-3,湖南衡阳另沙私针广告股份有限公司,sdsajb@yahoo.com.cn,450881195507138067
24999,钭誊,32,2017-07-19 00:00:00.0,15200003333,4349.148172354379,甘肃省兰州市汶水街48号-11-5,云南景洪真女谈严企业管理集团有限公司,qx5wb@126.com,653101195004073388

可以看到 sqoop 导出的 hdfs 分片数据,都是使用逗号 , 分割的,由于 hive 默认的分隔符是 /u0001(Ctrl+A),为了平滑迁移,需要在创建表格时指定数据的分割符号。

那么如果我们要导入这个数据,就需要在创建 hive 表的时候指定表的列分隔符为逗号。

CREATE TABLE `cetc_personal_infomation`(
  `id` int, 
  `realname` string, 
  `identity_card` string, 
  `base_location` string, 
  `datetime` timestamp)
row format delimited fields terminated by ',';

然后重新从 hdfs 上 load 数据:

load data inpath '/data/sqoop/cetc_personal_infomation' into table cetc_personal_infomation;

查看 hive 表数据:

hive-table-not-null.jpg

可以看到这次是正常的。

如果觉得这对你有用,请随意赞赏,给与作者支持
评论 1
最新评论
#1 楼 谦谦君子 2018-10-22

hive 建表的时候一定要注意指定分隔符,分割符号根据源数据的情况具体看。