Hive 2.3版本Parquet压缩失效问题求助
我之前在Hive 2.x版本也遇到过一模一样的问题——明明加了表属性配置,S3上的Parquet文件还是没压缩。其实核心问题是Hive处理Parquet压缩的配置优先级和生效条件没搞对,下面给你梳理最靠谱的解决步骤:
一、先搞懂为什么你的PARQUET.COMPRESS不生效
Hive 2.3里,PARQUET.COMPRESS这个表属性的优先级其实低于会话级/全局级的Parquet压缩配置。如果你的会话没开启压缩,或者全局配置没设置,光靠表属性根本不会生效。另外,要是你用INSERT OVERWRITE写入数据,写入时的会话配置会直接覆盖表的属性设置。
二、最优配置方案
1. 全局默认压缩(推荐所有表统一配置)
如果希望所有新建的Parquet表默认都开启压缩,直接修改hive-site.xml,添加以下配置:
<property> <name>parquet.compression</name> <value>ZLIB</value> <!-- 可选SNAPPY、GZIP:SNAPPY速度快,ZLIB压缩率高,按需选择 --> </property> <property> <name>hive.exec.compress.output</name> <value>true</value> <!-- 开启Hive输出压缩开关 --> </property> <property> <name>mapreduce.output.fileoutputformat.compress</name> <value>true</value> <!-- 底层MapReduce输出压缩开关 --> </property>
修改后重启Hive服务,后续新建的Parquet表都会自动应用这个压缩配置。
2. 单表级配置(针对特定表)
如果只需要给某个表开启压缩,建表时要同时指定表属性+确保压缩开关开启,示例建表语句:
CREATE TABLE your_s3_table ( id INT, username STRING, create_time TIMESTAMP ) STORED AS PARQUET LOCATION 's3://your-bucket/table-path/' TBLPROPERTIES ( 'parquet.compression'='ZLIB', 'hive.exec.compress.output'='true' );
如果是修改已存在的表:
ALTER TABLE your_s3_table SET TBLPROPERTIES ( 'parquet.compression'='ZLIB' );
注意:修改现有表后,之前写入的数据不会自动压缩,只有新写入的数据会生效。
3. 写入时的关键配置(必做!)
不管是全局还是表级配置,在执行INSERT写入数据前,务必在Hive会话中执行以下命令,确保临时会话的压缩配置是开启的:
SET parquet.compression=ZLIB; SET hive.exec.compress.output=true; SET mapreduce.output.fileoutputformat.compress=true;
这一步能避免会话中存在的默认关闭压缩的配置,覆盖你的表/全局设置。
三、验证压缩是否生效
别用cat看!Parquet是二进制列式存储格式,正常压缩后的文件用cat看应该是乱码,如果能看到明文,说明你的表可能根本不是Parquet格式(比如建表时写错了STORED AS),或者数据是文本格式写入的。
正确的验证方法是用parquet-tools工具:
parquet-tools meta s3://your-bucket/table-path/xxx.parquet
输出结果里会显示Compression: ZLIB(或你设置的压缩算法),就说明压缩生效了。
四、额外注意事项
- 压缩算法选择:追求查询速度选
SNAPPY,追求存储成本选ZLIB,GZIP压缩率更高但速度慢,一般不推荐在Hive中使用。 - 如果是分区表,确保
hive.exec.dynamic.partition.mode=nonstrict(默认应该是这个),否则动态分区写入可能会忽略压缩配置。 - 要是你用Spark写入Hive表,还要同步配置Spark的Parquet压缩:
spark.sql.parquet.compression.codec=zlib,因为Spark的配置优先级会高于Hive的配置。
内容的提问来源于stack exchange,提问作者1EnemyLeft

