如何读写多子文件夹?按日期合并ORC文件转存为Parquet
嘿,这个需求我熟,咱们用PySpark就能轻松搞定把按日期分区的ORC文件合并成对应日期的单个Parquet文件的任务,下面是具体的实现步骤和代码:
实现方案:ORC转Parquet并按日期合并文件
1. 用PySpark完成数据转换与合并
PySpark是处理这类大数据文件转换的绝佳工具,它能自动识别分区结构,还能灵活控制输出文件数量。直接上代码:
from pyspark.sql import SparkSession # 初始化SparkSession,配置参数避免生成小文件 spark = SparkSession.builder \ .appName("ORC-to-Parquet-Merge") \ .config("spark.sql.shuffle.partitions", "1") \ # 限制shuffle分区数,减少小文件 .getOrCreate() # 读取ORC分区数据,Spark会自动把mydate识别为分区列 df = spark.read.orc("/mypath/orc/") # 按mydate分区输出,保证每个日期只生成一个Parquet文件 df.repartition("mydate") \ .write \ .mode("overwrite") \ # 若目标路径已有数据则覆盖,可改为"append"保留原有数据 .partitionBy("mydate") \ .option("mergeSchema", "true") \ # 自动合并不同日期ORC文件的schema差异 .parquet("/mypath/parquet/") # 关闭Spark会话 spark.stop()
关键参数说明
spark.sql.shuffle.partitions = 1:减少shuffle操作的分区数量,避免生成大量小文件repartition("mydate"):让每个日期对应一个RDD分区,这样写出时每个日期只会生成一个Parquet文件partitionBy("mydate"):保持输出路径和原ORC一致的分区结构,方便后续使用
2. 批量重命名输出文件(可选)
默认Spark生成的文件名是类似part-00000-xxxx.snappy.parquet,如果想改成你要的part1and2together.parquet,可以用下面的bash脚本批量处理:
#!/bin/bash # 遍历所有mydate分区目录 for date_dir in /mypath/parquet/mydate=*; do # 进入当前分区目录 cd "$date_dir" || continue # 找到目录下的Parquet文件并改名 for parquet_file in *.parquet; do mv "$parquet_file" part1and2together.parquet break # 因为每个目录只有一个文件,找到就退出循环 done # 返回上级目录 cd - > /dev/null done
3. 运行步骤
- 先执行PySpark脚本,完成ORC到Parquet的转换与合并
- 再执行bash脚本,批量将每个分区下的文件重命名为你想要的名称
注意事项
- 如果某日期的数据量特别大,单个文件可能会过大,这时候可以调整
repartition的参数(比如按mydate再加一个分区键),但如果你的需求就是每个日期一个文件,当前配置就够用 - 确保运行脚本的用户对
/mypath/orc/有读权限,对/mypath/parquet/有写权限 - Spark环境默认支持ORC和Parquet格式,无需额外配置
内容的提问来源于stack exchange,提问作者tooptoop4
相关产品推荐
相关产品推荐

