Mac系统Java17环境下使用ParquetWriter报无法运行chmod错误如何解决?
问题原因
- 该异常是Hadoop低版本与Java 17的兼容性问题导致:Java 17调整了
ProcessBuilder的实现逻辑,当传入的工作目录不存在时,低版本Java会抛出No such file or directory错误,而Java 17会返回错误码17的File exists错误,和Hadoop旧版本的异常判断逻辑完全不匹配 - 第二个触发原因是你使用的
overwrite写入模式下,Hadoop的RawLocalFileSystem修改文件权限时,调用系统chmod命令的逻辑和Mac系统的文件权限机制、Java 17新特性存在冲突 - 少数场景是Hadoop本地文件系统默认生成的
.crc校验文件残留,重复写入时文件锁冲突也会触发该报错
解决方法
- 方案1:将Java版本降级到Java 11,这是兼容性最高的方案,目前Hadoop 3.3.x以下版本官方最高兼容的Java版本就是Java 11
- 方案2:升级项目依赖的Hadoop版本到3.3.4及以上,该版本已经修复了Java 17下
ProcessBuilder的异常处理逻辑,可以完美适配Java 17运行环境 - 方案3:如果不想调整Java和Hadoop版本,可以在初始化ParquetWriter前手动配置Hadoop参数,关闭权限校验和校验文件生成即可,代码调整如下:
val conf = new Configuration() // 关闭本地文件系统权限校验 conf.set("fs.file.impl", "org.apache.hadoop.fs.RawLocalFileSystem") // 关闭crc校验文件生成 conf.setBoolean("fs.file.impl.disable.cache", true) conf.set("fs.checksum.type", "NULL") AvroParquetWriter.builder[GenericRecord](path) .withConf(conf) .withSchema(avroSchema) .withCompressionCodec(COMPRESSION_CODE) .withPageSize(PAGE_SIZE) .withRowGroupSize(BLOCK_SIZE) .withDictionaryEncoding(ENABLE_DICT) .withWriteMode("overwrite") .withValidation(true) .build()
- 方案4:如果是Mac系统目录权限限制导致,可以先给写入目录赋最高权限,执行命令
sudo chmod -R 777 你的parquet文件存储目录路径,同时写入前手动删除目录下的旧文件和残留的.crc校验文件
内容的提问来源于stack exchange,提问作者igx
相关产品推荐
相关产品推荐

