目前正在尝试读取java中的Parquet文件而不使用spark。以下是我到目前为止得到的,基于亚当·梅尔尼克关于这个问题的博客文章。
代码
ParquetFileReader reader = ParquetFileReader.open(file);
MessageType schema = reader.getFooter().getFileMetaData().getSchema();
List<Type> fields = schema.getFields();
PageReadStore pages;
--> while ((pages = reader.readNextRowGroup()) != null) {
long rows = pages.getRowCount();
LOG.info("Number of rows: " + rows);
MessageColumnIO columnIO = new ColumnIOFactory().getColumnIO(schema);
RecordReader recordReader = columnIO.getRecordReader(pages, new GroupRecordConverter(schema));
for (int i = 0; i < rows; i++) {
SimpleGroup simpleGroup = (SimpleGroup) recordReader.read();
simpleGroups.add(simpleGroup);
}
}
(请注意,箭头是代码中抛出错误的行(167)
错误消息
org.apache.parquet.hadoop.BadConfigurationException: Class org.apache.parquet.hadoop.codec.SnappyCodec was not found
at org.apache.parquet.hadoop.CodecFactory.getCodec(CodecFactory.java:243)
at org.apache.parquet.hadoop.CodecFactory$HeapBytesDecompressor.<init>(CodecFactory.java:96)
at org.apache.parquet.hadoop.CodecFactory.createDecompressor(CodecFactory.java:212)
at org.apache.parquet.hadoop.CodecFactory.getDecompressor(CodecFactory.java:201)
at org.apache.parquet.hadoop.CodecFactory.getDecompressor(CodecFactory.java:42)
at org.apache.parquet.hadoop.ParquetFileReader$Chunk.readAllPages(ParquetFileReader.java:1519)
at org.apache.parquet.hadoop.ParquetFileReader$Chunk.readAllPages(ParquetFileReader.java:1402)
at org.apache.parquet.hadoop.ParquetFileReader.readChunkPages(ParquetFileReader.java:1023)
at org.apache.parquet.hadoop.ParquetFileReader.readNextRowGroup(ParquetFileReader.java:928)
at [myClassPath]([myClass].java:167)
依赖项
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>3.1.1.3.1.4.0-315</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>3.1.1.3.1.4.0-315</version>
</dependency>
<dependency>
<groupId>org.apache.spark</groupId>
<artifactId>spark-launcher_2.12</artifactId>
<version>3.0.0-preview2</version>
</dependency>
<dependency>
<groupId>org.apache.parquet</groupId>
<artifactId>parquet-avro</artifactId>
<version>1.12.0</version>
</dependency>
似乎在codecfactory类中找不到snappycodec类,但我查看了引用的库,发现该类就在那里:引用的库
codecfactory应该能够识别snappycodec类。有什么建议吗?谢谢
1条答案
按热度按时间o2gm4chl1#
找到了解决办法。
所以问题是snappycodec类被我为应用程序配置的maven shade插件着色了。
在用maven打包jar、用winzip打开jar并检查打包jar的codec目录(在那里我发现sanppycodec.class不再存在)之后,我意识到了这一点。
解决方案是,我需要在maven shade插件的配置中添加以下过滤器:
基本上,maven shade对来自parquet hadoop工件的看似随机的类进行着色,因此通过添加
<include>
filter,maven shade没有对其中的任何类进行着色处理,因此没有对其中的snappycodec.class文件进行着色处理。这样做之后,我需要添加另外两个过滤器,因为通过使用
<include>
在parquet hadoop工件上添加一个标签,然后它将所有其他parquet-*工件排除在已编译jar之外。所以,我需要显式地告诉它包括parquet列和parquet编码,因为我的应用程序在这些工件中使用了一些其他类。这种配置意味着maven着色器不会触及这三个工件,这意味着在编译时之前存在于这些工件中的任何类和每个类在用maven编译/打包它们之后都会保留在那里(因此,在运行时它们会在那里,而在编译前它们不会在那里,从而导致最初的错误)。令人惊叹的!