如何无Spark或框架将Parquet文件存入HDFS?Java直存方案咨询
直接用Java将Parquet文件写入HDFS(无需Spark等框架)
我来给你一步步拆解这个问题——既然你已经有本地生成Parquet的代码,那核心就是把本地文件输出逻辑替换成HDFS的输出流,同时让Parquet的Writer适配Hadoop的文件系统。下面是具体的实现方案:
一、先搞定必要的依赖
你需要在项目中引入Parquet的Hadoop适配包,以及Hadoop的客户端核心包(用来操作HDFS)。如果是Maven项目,把下面的依赖加到pom.xml里(版本可以根据你实际的Hadoop集群版本调整,比如Hadoop 3.x对应Parquet 1.12+):
<dependencies> <!-- Parquet Hadoop适配包 --> <dependency> <groupId>org.apache.parquet</groupId> <artifactId>parquet-hadoop</artifactId> <version>1.12.3</version> </dependency> <!-- Hadoop客户端核心包 --> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>3.3.4</version> <scope>provided</scope> <!-- 如果集群环境已提供,可设为provided --> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>3.3.4</version> <scope>provided</scope> </dependency> </dependencies>
二、核心代码修改(从本地到HDFS)
假设你原来的本地代码是用ParquetWriter写入本地文件,现在只需要把输出目标换成HDFS的路径,核心是用Hadoop的FileSystem来创建输出流,或者直接用Parquet支持的Hadoop Path构造Writer。
完整示例代码
下面是一个可直接参考的完整例子,包含Schema定义、HDFS配置初始化、Parquet写入的全部逻辑:
import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FileSystem; import org.apache.hadoop.fs.Path; import org.apache.parquet.hadoop.ParquetWriter; import org.apache.parquet.hadoop.api.WriteSupport; import org.apache.parquet.hadoop.example.GroupWriteSupport; import org.apache.parquet.schema.MessageType; import org.apache.parquet.schema.MessageTypeParser; import java.io.IOException; public class ParquetToHdfsWriter { public static void main(String[] args) throws IOException { // 1. 定义Parquet的Schema(和你本地代码的Schema保持一致即可) String schemaStr = "message User { " + "required int32 id; " + "required binary name (UTF8); " + "optional int32 age; " + "}"; MessageType schema = MessageTypeParser.parseMessageType(schemaStr); // 2. 初始化Hadoop配置,指定HDFS NameNode地址 Configuration hadoopConf = new Configuration(); // 替换成你的HDFS NameNode地址和端口,比如hdfs://localhost:9000 hadoopConf.set("fs.defaultFS", "hdfs://your-nn-host:9000"); // 如果集群开启了Kerberos认证,还需要配置krb5.conf和用户凭证,这里省略非认证场景 // 3. 获取HDFS的FileSystem实例 FileSystem fs = FileSystem.get(hadoopConf); // 4. 定义HDFS目标路径(比如/hadoop/data/user.parquet) Path hdfsPath = new Path("/hadoop/data/user.parquet"); // 如果路径已存在,先删除(可选,根据你的业务需求) if (fs.exists(hdfsPath)) { fs.delete(hdfsPath, true); } // 5. 配置ParquetWriter的WriteSupport WriteSupport writeSupport = GroupWriteSupport.writeSupport(schema); // 6. 构建ParquetWriter,直接传入HDFS的Path和Hadoop配置 try (ParquetWriter writer = ParquetWriter.builder(writeSupport) .withPath(hdfsPath) .withConf(hadoopConf) .withCompressionCodecName("SNAPPY") // 可选,设置压缩格式 .withWriteMode(ParquetWriter.Mode.OVERWRITE) .build()) { // 7. 写入数据(这里用示例数据,替换成你自己的业务数据生成逻辑) org.apache.parquet.example.data.Group user = new org.apache.parquet.example.data.Group(schema); user.add("id", 1); user.add("name", "Alice"); user.add("age", 28); writer.write(user); // 可以循环写入更多数据... } catch (Exception e) { e.printStackTrace(); } finally { // 关闭FileSystem资源 fs.close(); } } }
三、关键注意事项
- 配置文件适配:如果你的Hadoop集群有自定义的
core-site.xml、hdfs-site.xml,可以把这些文件放到项目的resources目录下,Hadoop的Configuration会自动加载,这样就不用在代码里硬编码fs.defaultFS等配置。 - 权限问题:运行代码的用户需要拥有HDFS目标路径的写入权限,否则会抛出
Permission denied异常。可以用hdfs dfs -chmod或者hdfs dfs -chown调整路径权限。 - 资源关闭:一定要用
try-with-resources或者手动关闭ParquetWriter和FileSystem,避免资源泄漏。 - 版本兼容性:确保Parquet和Hadoop的版本匹配,比如Parquet 1.12.x兼容Hadoop 2.7+和3.x,不要混用跨大版本的依赖。
四、替换你现有代码的要点
如果你已经有本地生成Parquet的代码,只需要做这几个改动:
- 引入上面提到的Parquet-Hadoop和Hadoop依赖;
- 移除本地
FileOutputStream相关的代码,换成HadoopFileSystem创建的输出流,或者直接用ParquetWriter.builder().withPath(hdfsPath).withConf(hadoopConf)的方式构建Writer; - 初始化Hadoop配置,指定NameNode地址。
内容的提问来源于stack exchange,提问作者javier_orta
相关产品推荐
相关产品推荐

