У меня есть набор TSV с их схемами:
val data: RDD[(Schema, List[String]) = ???
Этот СДР является гетерогенным, и схема каждой строки неизвестна во время компиляции, поэтому она может иметь вместе String, Int
и Bool, Bool, Double
, но очень точный во время выполнения.
Я хочу записать эти данные в Apache Parquet, разбитый по схеме. Очевидно, я могу получить StructType
из моего Schema
, но я не могу понять, как сгруппировать все мои строки (List[String]
) по схеме и эффективно их записать.
Ранее я писал данные TSV как:
data
.map { case (s, d) => (s, d.mkString("\t")) }
.toDF("schema", "data")
.partitionBy("schema")
.text(path)
Но это не подразумевало схемы и рассматривало все строки как один большой двоичный объект.
Один из возможных способов сделать то, что я хочу, - написать каждую схему одну за другой:
schemas.foreach { schema => // Set of schemas from dataset, gathered during intermediate action
val schemaedData = data.flatMap {
case (s, row) if schema == s =>
Some(Row.fromSeq(row))
case _ => None
}
val sparkSchema = derive(schema)
spark.createDataFrame(schemaedData, sparkSchema)
.write
.partitionBy("schema")
.parquet(path)
}
Но это выглядит супер-неэффективно, поскольку будет распределять данные между исполнителями для каждой схемы. Но у меня будут сотни схем с разной кардинальностью.