前言
前面说了,HDFS上的数据在生产环境中一定是以压缩格式存储的,那么在Hive中如何使用Parquet格式存储数据呢?
测试数据
在本地服务器上面vim test.txt
1,zs
2,ls
3,ww
4,zl
由于我们一般接到的数据都是gzip压缩的文件,这里就将文件压缩为gzip
gzip -c test.txt > .test.gz
错误的方式
- 创建parquet的hive表
CREATE TABLE raw_parquet (id INT,name STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
STORED AS PARQUET;
- 导入数据
LOAD DATA LOCAL INPATH '/var/lib/hadoop-hdfs/test.gz' INTO TABLE raw_parquet ;
- 查看数据
SELECT * FROM raw_parquet;
- 结果
Failed with exception java.io.IOException:java.lang.RuntimeException:
hdfs://nameservice1/user/hive/warehouse/ads.db/raw_sequence1/test.gz
is not a Parquet file. expected magic number at tail [80, 65, 82, 49] but found [20, 0, 0, 0]
大概意思就是:你创建表的时候,指定了存储文件格式是parquet,但是你导入的数据根本不是,我只认识parquet,其他的都鸟你。
这就麻烦了,难道我每次都得把文件先想办法转为parquet,然后再导入hive表?这真的好麻烦,况且也没有现成的命令转换,还得写代码(之前一直用spark代码很方便,之后会总结)
正确的导入方式
从官网找到了唯一给的一种方式:
- 先创建一张临时的默认格式(TextFile)表:
CREATE TABLE raw (id INT,name STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n';
- 将gzip数据导入该表
LOAD DATA LOCAL INPATH '/var/lib/hadoop-hdfs/test.gz' INTO TABLE raw;
- 创建parquet格式表
CREATE TABLE raw_sequence (id INT,name STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY ',' LINES TERMINATED BY '\n'
STORED AS PARQUET;
- 将临时表的数据导入到parquet表
SET hive.exec.compress.output=true;
INSERT OVERWRITE TABLE raw_sequence SELECT * FROM raw;
- 查看数据
select * from raw_sequence;
- 结果
1 zs
2 ls
3 ww
4 zl
这种方式,看起来也不方便,这样每次都得删除临时表,不过目前官网只给了这个方案,我自己的方案,更偏向于使用Spark,这个后续再说。
Hive Parquet格式建表方式
CREATE TABLE语句可以使用取决于Hive版本的语法来指定Parquet存储格式
Hive 0.10 - 0.12
CREATE TABLE parquet_test (
id int,
str string,
mp MAP<STRING,STRING>,
lst ARRAY<STRING>,
strct STRUCT<A:STRING,B:STRING>)
PARTITIONED BY (part string)
ROW FORMAT SERDE 'parquet.hive.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT 'parquet.hive.DeprecatedParquetInputFormat'
OUTPUTFORMAT 'parquet.hive.DeprecatedParquetOutputFormat';
Hive 0.13 and later
CREATE TABLE parquet_test (
id int,
str string,
mp MAP<STRING,STRING>,
lst ARRAY<STRING>,
strct STRUCT<A:STRING,B:STRING>)
PARTITIONED BY (part string)
STORED AS PARQUET;
显然Hive 0.13之后写起来更简单咯