Parquet 支持的 Hive table:数组列在 Impala 中不可查询
Parquet-backed Hive table: array column not queryable in Impala
虽然Impala比Hive快很多,但我们使用Hive是因为它支持复杂(嵌套)的数据类型,例如数组和映射。
我注意到 Impala,从 CDH5.5 开始,现在支持复杂数据类型。由于也可以在 Impala 中 运行 Hive UDF,我们可以在 Impala 中做任何我们想做的事情,但速度要快得多。这是个好消息!
当我浏览文档时,我看到 Impala 希望数据以 Parquet 格式存储。我的原始数据恰好是一个双列 CSV,其中第一列是一个 ID,第二列是一个以竖线分隔的字符串数组,例如:
123,ASDFG|SDFGH|DFGHJ|FGHJK
234,QWERT|WERTY|ERTYU
已创建 Hive table:
CREATE TABLE `id_member_of`(
`id` INT,
`member_of` ARRAY<STRING>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '|'
LINES TERMINATED BY '\n'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';
原始数据已加载到 Hive table:
LOAD DATA LOCAL INPATH 'raw_data.csv' INTO TABLE id_member_of;
已创建 table 的 Parquet 版本:
CREATE TABLE `id_member_of_parquet` (
`id` STRING,
`member_of` ARRAY<STRING>)
STORED AS PARQUET;
CSV 支持的数据 table 已插入 Parquet table:
INSERT INTO id_member_of_parquet SELECT id, member_of FROM id_member_of;
并且 Parquet table 现在可以在 Hive 中查询:
hive> select * from id_member_of_parquet;
123 ["ASDFG","SDFGH","DFGHJ","FGHJK"]
234 ["QWERT","WERTY","ERTYU"]
奇怪的是,当我在 Impala 中查询相同的 Parquet-backed table 时,它不会 return 数组列:
[hadoop01:21000] > invalidate metadata;
[hadoop01:21000] > select * from id_member_of_parquet;
+-----+
| id |
+-----+
| 123 |
| 234 |
+-----+
问:数组列怎么了?你能看出我做错了什么吗?
事实证明这很简单:我们可以通过将数组添加到 FROM
中用点来访问数组,例如
Query: select * from id_member_of_parquet, id_member_of_parquet.member_of
+-----+-------+
| id | item |
+-----+-------+
| 123 | ASDFG |
| 123 | SDFGH |
| 123 | DFGHJ |
| 123 | FGHJK |
| 234 | QWERT |
| 234 | WERTY |
| 234 | ERTYU |
+-----+-------+
虽然Impala比Hive快很多,但我们使用Hive是因为它支持复杂(嵌套)的数据类型,例如数组和映射。
我注意到 Impala,从 CDH5.5 开始,现在支持复杂数据类型。由于也可以在 Impala 中 运行 Hive UDF,我们可以在 Impala 中做任何我们想做的事情,但速度要快得多。这是个好消息!
当我浏览文档时,我看到 Impala 希望数据以 Parquet 格式存储。我的原始数据恰好是一个双列 CSV,其中第一列是一个 ID,第二列是一个以竖线分隔的字符串数组,例如:
123,ASDFG|SDFGH|DFGHJ|FGHJK
234,QWERT|WERTY|ERTYU
已创建 Hive table:
CREATE TABLE `id_member_of`(
`id` INT,
`member_of` ARRAY<STRING>)
ROW FORMAT DELIMITED
FIELDS TERMINATED BY ','
COLLECTION ITEMS TERMINATED BY '|'
LINES TERMINATED BY '\n'
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';
原始数据已加载到 Hive table:
LOAD DATA LOCAL INPATH 'raw_data.csv' INTO TABLE id_member_of;
已创建 table 的 Parquet 版本:
CREATE TABLE `id_member_of_parquet` (
`id` STRING,
`member_of` ARRAY<STRING>)
STORED AS PARQUET;
CSV 支持的数据 table 已插入 Parquet table:
INSERT INTO id_member_of_parquet SELECT id, member_of FROM id_member_of;
并且 Parquet table 现在可以在 Hive 中查询:
hive> select * from id_member_of_parquet;
123 ["ASDFG","SDFGH","DFGHJ","FGHJK"]
234 ["QWERT","WERTY","ERTYU"]
奇怪的是,当我在 Impala 中查询相同的 Parquet-backed table 时,它不会 return 数组列:
[hadoop01:21000] > invalidate metadata;
[hadoop01:21000] > select * from id_member_of_parquet;
+-----+
| id |
+-----+
| 123 |
| 234 |
+-----+
问:数组列怎么了?你能看出我做错了什么吗?
事实证明这很简单:我们可以通过将数组添加到 FROM
中用点来访问数组,例如
Query: select * from id_member_of_parquet, id_member_of_parquet.member_of
+-----+-------+
| id | item |
+-----+-------+
| 123 | ASDFG |
| 123 | SDFGH |
| 123 | DFGHJ |
| 123 | FGHJK |
| 234 | QWERT |
| 234 | WERTY |
| 234 | ERTYU |
+-----+-------+