如何使用HDFS命令或Spark无需本地下载提取HDFS中的tar.gz文件
解决方案
方案1:纯HDFS Shell命令实现(无需依赖Spark)
全程流式处理,不会将压缩包或解压文件落地本地磁盘,直接写入目标HDFS路径:
hadoop fs -cat /dataset1/sample.tar.gz | tar -xz --to-command='hadoop fs -put - /dataset1/extracted/$TAR_FILENAME'
- 命令说明:
hadoop fs -cat直接读取HDFS上的压缩包内容到标准输出,tar从标准输入流式解压,通过--to-command参数将每个解压出的CSV文件直接通过hadoop fs -put写入目标HDFS路径,内置变量$TAR_FILENAME自动保留压缩包内的原文件名。 - 注意:只需在任意配置了HDFS客户端权限的节点执行即可,仅占用少量内存缓存,不会消耗大量本地磁盘空间。
方案2:Spark实现(同时满足后续并行运算需求)
你遇到的「单个gzip无法并行读取」的问题仅针对单个大文件压缩成的gzip包,你的场景是tar打包了多个独立CSV文件,Spark可以直接并行处理包内的每个子文件,无需提前拆分外层压缩包。
Scala 示例
val df = spark.read .option("compression", "gzip") .option("header", "true") // 按需调整,CSV无表头则设为false .csv("tar:/dataset1/sample.tar.gz/*") // 若需保存解压后的CSV到目标路径 df.write .option("header", "true") .csv("/dataset1/extracted/") // 后续可直接基于df做聚合运算,无需落地解压文件
Python 示例
from pyspark.sql import SparkSession spark = SparkSession.builder.appName("extract_tar_csv").getOrCreate() df = spark.read \ .option("compression", "gzip") \ .option("header", "true") \ .csv("tar:/dataset1/sample.tar.gz/*") # 写入目标路径 df.write.option("header", "true").csv("/dataset1/extracted/")
- 说明:路径前缀
tar:是Spark原生支持的tar包读取协议,会自动识别并解压外层tar.gz,将包内每个CSV作为独立分片并行读取,性能远高于单节点解压。 - 若需拆分数据方便后续处理,写入时可通过
repartition(分区数)调整分区,例如df.repartition(20).write(...)会将数据拆分为20个分片存储。
内容的提问来源于stack exchange,提问作者vkt
相关产品推荐
相关产品推荐

