hdfs小文件处理

提前规避

1.流式写入

调整流式写入的时间窗口是一个不错的选择,如果业务对实时性要求很高,那么可以根据数据类型(非结构化vs结构化)、append/update频率和数据使用模式(随机读取vs聚合),HBase和Kudu是存储层的更好选择。对于已经存在的小文件,也可以设置定期的Job对这些文件进行压缩、合并,以减少文件量和文件数量。

2.过度分区表

在决定分区的粒度时,要考虑到每个分区的数据量。为有大文件的分区做计划(用Parquet的话,约256MB或更大),即使这意味着有较少的粒度分区,例如每月而不是每天的分区。对于数据量小的表(几百MB),可以考虑创建一个非分区表。

3.Spark过度并行化

在Spark中向HDFS写入数据时,在向磁盘写入数据前要重新分区或聚合分区。这些语句中定义的分区数量将决定输出文件的数量。强烈建议检查Spark作业的输出,并验证创建的文件数量和实现的吞吐量。

4.使用工具进行压缩

hadoop本身提供merge命令,当然用户也可以自行编写工具实现。

5.使用Hive对数据进行压缩

如果你有一个现有的Hive表有大量的小文件,那么可以通过以下设置来重写这个表(parquet格式)。关于Hive压缩可以查阅其他文档获取更详细的信息。

set hive.exec.compress.output=true;set parquet.compression=snappy;set hive.merge.mapfiles=true;set hive.merge.mapredfiles=true; set hive.merge.mapredfiles=true;set hive.merge.smallfiles.avgsize=134217728; --128Mset hive.merge.size.per.task = 268435456; --256Mset hive.optiming.sort.dynamic.partition = true;set parquet.blocksize= 268435456; --256Mset dfs.block.size=268435456; --256M

关于Hive配置属性的详细信息可以在Apache Hive官方页面上找到,这里再提供一些重新数据的方法。

CREATE TABLE AS SELECT(CTAS)对于一个非分区表会比较方便。

你也可以先运行CREATE TABLE LIKE (CTL)来复制一个表结构,然后使用INSERT OVERWRITE SELECT语句将数据从源表加载数据到目标表。

注意:如果在没有定义静态分区名的情况下插入数据,需要在Hive中启用非严格的动态分区模式,可以通过设置

  •  
hive.exec.dynamic.partition.mode=non-strict

分区列必须是选择语句中的最后一列,这样动态分区才能在这种情况下工作。此外,也可以直接使用mapred.reduce.tasks设置来配置reduce的数量。创建的文件数量将等于使用的减速器数量。设置一个最佳的减速器值取决于写入的数据量。

猜你喜欢

转载自blog.csdn.net/someInNeed/article/details/113983218