hive 中可能产生小文件的场景

在 Hive 中,小文件是指文件大小远小于 HDFS 块大小(通常为 128 MB 或 256 MB)的文件。小文件过多会导致 NameNode 内存压力增大、查询性能下降以及资源浪费。以下是 Hive 中可能产生小文件的常见场景:


1. 高频插入数据

场景描述

  • 使用 INSERT INTOINSERT OVERWRITE 语句频繁插入少量数据。

  • 每次插入操作都会生成一个新的文件。

示例

sql 复制代码
INSERT INTO TABLE example_table VALUES (1, 'Alice');
INSERT INTO TABLE example_table VALUES (2, 'Bob');
  • 每次插入都会生成一个小文件。

2. 动态分区插入

场景描述

  • 使用动态分区插入数据时,如果分区数量较多且每个分区的数据量较小,会导致每个分区生成一个小文件。

示例

sql 复制代码
INSERT OVERWRITE TABLE partitioned_table PARTITION (dt)
SELECT id, name, dt FROM source_table;
  • 如果 dt 分区字段有大量不同的值,且每个分区的数据量较小,会生成大量小文件。

3. 使用 GROUP BYDISTINCT

场景描述

  • GROUP BYDISTINCT 操作中,如果分组字段的基数(Cardinality)较高,且每个分组的数据量较小,会导致每个分组生成一个小文件。

示例

sql 复制代码
INSERT OVERWRITE TABLE grouped_table
SELECT key, COUNT(*) 
FROM source_table 
GROUP BY key;
  • 如果 key 的基数较高,且每个 key 的数据量较小,会生成大量小文件。

4. 使用 UNION ALL

场景描述

  • 使用 UNION ALL 合并多个查询结果时,如果每个查询的结果数据量较小,会导致生成多个小文件。

示例

sql 复制代码
INSERT OVERWRITE TABLE union_table
SELECT * FROM table_a
UNION ALL
SELECT * FROM table_b;
  • 如果 table_atable_b 的数据量较小,会生成多个小文件。

5. 使用 CREATE TABLE AS SELECT (CTAS)

场景描述

  • 使用 CREATE TABLE AS SELECT 创建新表时,如果源表的数据分布不均匀或数据量较小,会导致生成小文件。

示例

sql 复制代码
CREATE TABLE new_table AS
SELECT * FROM source_table;
  • 如果 source_table 的数据量较小或分布不均匀,会生成小文件。

6. 使用 MAPREDUCE 任务

场景描述

  • 在 MapReduce 任务中,如果 Reduce 任务数设置过多,且每个 Reduce 任务处理的数据量较小,会导致生成大量小文件。

示例

sql 复制代码
SET hive.exec.reducers.bytes.per.reducer = 1000000; -- 每个 Reducer 处理 1 MB 数据
INSERT OVERWRITE TABLE reduced_table
SELECT key, COUNT(*) 
FROM source_table 
GROUP BY key;
  • 如果数据量较小且 Reducer 数量过多,会生成大量小文件。

7. 使用 STORED AS SEQUENCEFILETEXTFILE

场景描述

  • 使用 SEQUENCEFILETEXTFILE 格式存储数据时,如果数据量较小,容易生成小文件。

示例

sql 复制代码
CREATE TABLE textfile_table (
    id INT,
    name STRING
) STORED AS TEXTFILE;
  • 如果插入的数据量较小,会生成小文件。

8. 使用 BUCKETING

场景描述

  • 使用分桶表时,如果分桶数设置过多且每个分桶的数据量较小,会导致生成小文件。

示例

sql 复制代码
CREATE TABLE bucketed_table (
    id INT,
    name STRING
) CLUSTERED BY (id) INTO 100 BUCKETS;
  • 如果数据量较小且分桶数过多,会生成大量小文件。

9. 使用 INSERT INTO 追加数据

场景描述

  • 使用 INSERT INTO 追加数据时,如果每次追加的数据量较小,会导致生成小文件。

示例

sql 复制代码
INSERT INTO TABLE example_table VALUES (1, 'Alice');
INSERT INTO TABLE example_table VALUES (2, 'Bob');
  • 每次插入都会生成一个小文件。

10. 使用 MERGEUPDATE 操作

场景描述

  • 在支持 ACID 的 Hive 表中,使用 MERGEUPDATE 操作时,可能会生成大量小文件。

示例

sql 复制代码
MERGE INTO acid_table AS target
USING source_table AS source
ON target.id = source.id
WHEN MATCHED THEN UPDATE SET target.name = source.name;
  • 每次更新操作可能会生成新的小文件。

小文件的危害

  1. NameNode 压力:

    • 小文件过多会占用大量 NameNode 内存,影响 HDFS 性能。
  2. 查询性能下降:

    • 小文件会增加 MapReduce 任务的启动开销,降低查询性能。
  3. 资源浪费:

    • 小文件会占用额外的存储空间和计算资源。

解决方法

  1. 合并小文件:

    • 使用 hive.merge.mapfileshive.merge.mapredfiles 参数自动合并小文件。

    • 示例:

      sql 复制代码
      SET hive.merge.mapfiles = true;
      SET hive.merge.mapredfiles = true;
      SET hive.merge.size.per.task = 256000000; -- 256 MB
  2. 调整 Reduce 任务数:

    • 通过 hive.exec.reducers.bytes.per.reducer 参数控制每个 Reducer 处理的数据量。

    • 示例:

      sql 复制代码
      SET hive.exec.reducers.bytes.per.reducer = 256000000; -- 256 MB
  3. 使用分区和分桶:

    • 合理设计分区和分桶策略,避免生成过多小文件。
  4. 定期合并小文件:

    • 使用 ALTER TABLE 命令或工具(如 hadoop fs -getmerge)定期合并小文件。
  5. 使用 ORC 或 Parquet 格式:

    • 列式存储格式(如 ORC、Parquet)具有更高的压缩率和查询性能,适合存储大规模数据
相关推荐
叮铃铃上课了3 小时前
Hive实战:精准拆分中英文混合字符串(含重音/空格场景)
数据仓库·hive·hadoop
走遍西兰花.jpg7 小时前
hive怎么实现连续登录
数据仓库·hive·hadoop
a努力。9 小时前
中国邮政Java面试被问:MySQL的ICP(索引条件下推)优化原理
java·开发语言·数据仓库·面试·职场和发展·重构·maven
像豆芽一样优秀11 小时前
深入理解与应用SQL递归CTE处理层级数据
大数据·hive·sql
【赫兹威客】浩哥12 小时前
【赫兹威客】伪分布式Hadoop测试教程
大数据·hadoop·分布式
Hello.Reader13 小时前
Flink on Hadoop YARN 从 0 到可上线的 Session / Application 部署指南
大数据·hadoop·flink
B站计算机毕业设计超人13 小时前
计算机毕业设计Python+Django考研院校推荐系统 考研分数线预测系统 大数据毕业设计 (代码+LW文档+PPT+讲解视频)
大数据·人工智能·hive·python·django·毕业设计·课程设计
Gain_chance13 小时前
22-学习笔记尚硅谷数仓搭建-日志表建表语句解析、数据装载及脚本装载数据
数据仓库·笔记·学习
yumgpkpm14 小时前
Cloudera CDP/CDH/Hadoop 信创大模型AI时代何去何从?
人工智能·hive·hadoop·elasticsearch·zookeeper·kafka·cloudera
Gain_chance14 小时前
18-学习笔记尚硅谷数仓搭建-数据仓库运行环境搭建(hive的安装及配置)
数据仓库·hive·笔记·学习