内存对象复杂到没有Apache Spark的Parquet文件

时间:2017-09-28 16:19:38

标签: java scala avro parquet

我有一个对象,我想为每个列表创建一个镶木地板文件。 那个对象看起来像这样:

case class ProgramsData(programs: List[Program], switches: List[Switch], paths: List[Path],
                    activities: List[Activity], enactments: List[Enactment])
经过一番研究,我对如何实现这一点感到困惑。

似乎在没有Apache Spark的情况下执行此操作的唯一方法是将对象转换为Avro文件,然后将其读入并获取架构,然后可以从中创建镶木地板文件。

有没有办法将中间人剪掉并将对象转换为对象内每个列表的镶木地板文件? 如果没有,实现我最终目标的最简单方法是什么? 可悲的是,我见过的少数几个例子要么不起作用,要么不能完全按照我的意愿行事。

提前致谢。

修改的 因此,经过另一整天的工作,我已经制作了一些生成文件的代码。但是当编写一些代码来阅读镶木地板文件时,它告诉我它无法解码它。这告诉我编写器代码是错误的(虽然它肯定无法创建一个有效的镶木地板文件,它会抛出异常?)

以下是编写代码:

val avroSchema: Schema = ReflectData.get().getSchema(classOf[Program])

  val parquetOutputPath = new org.apache.hadoop.fs.Path(outputFilePath)

  val parquetWriter = new AvroParquetWriter[Record](parquetOutputPath, avroSchema)

  programs.foreach(program => {
    val programRecord = new GenericData.Record(avroSchema)
    programRecord.put("name", program.getName)

    parquetWriter.write(programRecord)
  })

  parquetWriter.close()

以下是阅读代码:

 val avroSchema: Schema = ReflectData.get().getSchema(classOf[Program])

val filePath = new org.apache.hadoop.fs.Path(filePathString)

val parquetReader = new AvroParquetReader[Record](filePath)

val record = parquetReader.read()

读取代码的最后一行引发以下异常:

  

.ParquetDecodingException:无法读取文件文件中第0块中1的值:/tmp/parquet/test-1506962769.parquet

希望有人可以指出我正确的方向,否则我可能不得不使用Apache Spark,因为它能够轻松创建镶木地板文件,这是过度的。

2 个答案:

答案 0 :(得分:3)

您可以使用avro架构编写镶木地板文件,而无需使用spark。

以下是java中的示例代码,它将镶木地板格式写入本地磁盘。

{
final String schemaLocation = "/tmp/avro_format.json";
final Schema avroSchema = new Schema.Parser().parse(new File(schemaLocation));
final MessageType parquetSchema = new AvroSchemaConverter().convert(avroSchema);
final WriteSupport<Pojo> writeSupport = new AvroWriteSupport(parquetSchema, avroSchema);
final String parquetFile = "/tmp/parquet/data.parquet";
final Path path = new Path(parquetFile);
ParquetWriter<GenericRecord> parquetWriter = new ParquetWriter(path, writeSupport, CompressionCodecName.SNAPPY, BLOCK_SIZE, PAGE_SIZE);
final GenericRecord record = new GenericData.Record(avroSchema);
record.put("id", 1);
record.put("age", 10);
record.put("name", "ABC");
record.put("place", "BCD");
parquetWriter.write(record);
parquetWriter.close();
}

avro_format.json,

{
   "type":"record",
   "name":"Pojo",
   "namespace":"com.xx.test",
   "fields":[
      {
         "name":"id",
         "type":[
            "int",
            "null"
         ]
      },
      {
         "name":"age",
         "type":[
            "int",
            "null"
         ]
      },
      {
         "name":"name",
         "type":[
            "string",
            "null"
         ]
      },
      {
         "name":"place",
         "type":[
            "string",
            "null"
         ]
      }
   ]
}

希望这有帮助。

答案 1 :(得分:1)

是的,你可以直接做到。 Refer

您可以从这里了解如何将数据写入实木复合地板。它以字符串为例。 要编写更多不同类型的列。首先,我们必须提供我们在MessageType中解释的模式。