在没有 Hadoop Path API 的情况下读取本地 Parquet 文件

Ben*_*son 9 java hadoop parquet

我正在尝试读取本地 Parquet 文件,但是我能找到的唯一 API 与 Hadoop 紧密耦合,并且需要 HadoopPath作为输入(即使是指向本地文件)。

ParquetReader<GenericRecord> reader = AvroParquetReader.<GenericRecord>builder(file).build();
GenericRecord nextRecord = reader.read();
Run Code Online (Sandbox Code Playgroud)

如何在独立的 Java 代码中读取镶木地板文件的最流行的答案,但需要一个 HadoopPath并且现在已被弃用为一个神秘的InputFile代替。InputFile我能找到的唯一实现是HadoopInputFile,所以再次没有帮助。

在 Avro 这很简单:

DatumReader<GenericRecord> datumReader = new GenericDatumReader<>();
this.dataFileReader = new DataFileReader<>(file, datumReader);
Run Code Online (Sandbox Code Playgroud)

(文件在哪里java.io.File)。什么是 Parquet 等价物?

Path在答案中要求没有 Hadoop依赖,因为 Hadoop 会导致膨胀和 jar 地狱,并且需要它来读取本地文件似乎很愚蠢。

为了进一步解释背景故事,我维护了一个小的IntelliJ 插件,它允许用户将 Avro 文件拖放到一个窗格中以便在表格中查看。这个插件目前是 5MB。如果我包含 Parquet 和 Hadoop 依赖项,它会膨胀到超过 50MB,甚至无法工作


回复后附录

现在我已经开始工作了(感谢接受的答案),这是我的工作解决方案,它避免了严重依赖 Hadoop PathAPI可能会拖入的所有烦人的错误:

Jör*_*ann 9

不幸的是,java parquet 实现并不独立于某些 hadoop 库。他们的 bugtracker 中存在一个问题,可以在不依赖于 hadoop 的情况下轻松地在 java 中读取和写入 parquet 文件,但似乎没有太大进展。InputFile添加该接口是为了增加一些解耦,但是许多实现 parquet 元数据部分的类以及所有压缩编解码器都存在于 hadoop 依赖项中。

在smile library 中找到了另一个实现InputFile,这可能比通过hadoop 文件系统抽象更有效,但并没有解决依赖问题。

正如其他答案已经提到的,您可以Path为本地文件创建一个 hadoop并毫无问题地使用它。

java.io.File file = ...
new org.apache.hadoop.fs.Path(file.toURI())
Run Code Online (Sandbox Code Playgroud)

通过定义一些排除项,可以大大减少hadoop拉入的依赖树。我正在使用以下内容来减少膨胀(使用 gradle 语法):

compile("org.apache.hadoop:hadoop-common:3.1.0") {
    exclude(group: 'org.slf4j')
    exclude(group: 'org.mortbay.jetty')
    exclude(group: 'javax.servlet.jsp')
    exclude(group: 'com.sun.jersey')
    exclude(group: 'log4j')
    exclude(group: 'org.apache.curator')
    exclude(group: 'org.apache.zookeeper')
    exclude(group: 'org.apache.kerby')
    exclude(group: 'com.google.protobuf')
}
Run Code Online (Sandbox Code Playgroud)