在 Linux 下使用 HDFS 合并小文件,常见有 HDFS 自带命令、MapReduce / Hadoop Archive、以及 Spark / Hive 等方式。下面按最常用 → 进阶给你讲。
适合:把 HDFS 小文件合并到本地一个文件
hdfs dfs -getmerge /user/hadoop/smallfiles /local/bigfile.txt
✅ 优点:简单
❌ 缺点:文件在本地,不在 HDFS
HDFS 本身没有直接的 merge 到 HDFS 命令,变通方式:
hdfs dfs -getmerge /user/hadoop/smallfiles ./bigfile.txt
hdfs dfs -put ./bigfile.txt /user/hadoop/bigfile.txt
适合数据量不大的情况。
适合:小文件非常多(几万+)
hadoop archive -archiveName files.har \
-p /user/hadoop/smallfiles \
/user/hadoop/har
查看:
hdfs dfs -ls har:///user/hadoop/har/files.har
✅ 优点:减少 NameNode 压力
❌ 缺点:不能直接修改,读取稍慢
适合:真正在 HDFS 内合并为大文件
CombineFileInputFormat(写 MR 程序)(偏开发,适合定制)
hadoop jar $HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-examples-*.jar \
wordcount /user/hadoop/smallfiles /user/hadoop/merged
(本质是重新写文件)
适合:大数据量、ETL 场景
spark-shell
spark.read.textFile("hdfs:///user/hadoop/smallfiles")
.coalesce(1)
.write.mode("overwrite")
.text("hdfs:///user/hadoop/bigfile")
或 PySpark:
spark.read.text("hdfs:///user/hadoop/smallfiles") \
.coalesce(1) \
.write.mode("overwrite") \
.text("hdfs:///user/hadoop/bigfile")
✅ 推荐生产使用
SET hive.merge.mapfiles = true;
SET hive.merge.size.per.task = 256000000;
INSERT OVERWRITE TABLE table_name
SELECT * FROM table_name;
| 场景 | 推荐方式 |
|---|---|
| 临时合并 | getmerge |
| 小文件极多 | HAR |
| 生产 ETL | Spark |
| Hive 表 | Hive merge |
| 不修改原数据 | HAR |
如果你能告诉我:
我可以直接给你最合适的命令或脚本。