Spark Java读取Azure空Parquet目录抛Schema异常如何提前判断处理
解决方案
方案1:预检查路径下是否存在有效Parquet文件(无Spark作业开销,性能最优)
直接调用Hadoop FileSystem API判断目标路径是否存在符合要求的Parquet文件,不需要触发Spark的读取逻辑,适配Azure存储的abfs/wasb等协议,自动复用Spark已配置的存储认证信息。
import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.hadoop.fs.FileStatus; FileSystem fs = FileSystem.get(spark.sparkContext().hadoopConfiguration()); Path inputPath = new Path(configuration.getInputDataLocation()); boolean hasValidParquet = false; if (fs.exists(inputPath)) { FileStatus[] fileStatuses = fs.listStatus(inputPath); for (FileStatus status : fileStatuses) { // 跳过目录、隐藏文件/临时文件,匹配Parquet后缀 if (!status.isDirectory() && !status.getPath().getName().startsWith("_") && !status.getPath().getName().startsWith(".") && status.getPath().getName().endsWith(".parquet")) { hasValidParquet = true; break; } } } if (hasValidParquet) { Dataset input = spark.read().parquet(configuration.getInputDataLocation()); // 正常业务逻辑 } else { // 空目录自定义处理逻辑 }
如果你的输入数据存在多级子目录,可将
listStatus替换为递归遍历方法listFiles(inputPath, true)实现多层目录扫描。
方案2:指定固定Schema读取,兼容空目录场景
如果Parquet数据的Schema是固定的,直接手动指定Schema读取即可,空目录下不会抛出Schema推断异常,后续直接判断数据集行数即可,代码更简洁:
import org.apache.spark.sql.types.StructType; // 按实际业务的Parquet字段定义Schema StructType parquetSchema = new StructType() .add("user_id", "long") .add("user_name", "string") .add("op_time", "timestamp"); // 指定Schema读取,空目录不会报错 Dataset input = spark.read().schema(parquetSchema).parquet(configuration.getInputDataLocation()); if (input.count() == 0) { // 空数据处理逻辑 } else { // 正常业务逻辑 }
内容的提问来源于stack exchange,提问作者HARDIK SINGH NEGI
相关产品推荐
相关产品推荐

