2016-05-19 9 views
13

Ich habe eine Bienenstock-Tabelle, die auf einer Last von externen Parkettdateien aufgebaut ist. Paruqet-Dateien sollten vom Funke-Job generiert werden, aber aufgrund der Einstellung von Metadaten-Flag auf false wurden sie nicht generiert. Ich frage mich, ob es möglich ist, es auf schmerzlose Weise wiederherzustellen. Die Struktur der Dateien ist wie folgt:Generieren von Metadaten für Parkettdateien

/apps/hive/warehouse/test_db.db/test_table/_SUCCESS 
/apps/hive/warehouse/test_db.db/test_table/_common_metadata 
/apps/hive/warehouse/test_db.db/test_table/_metadata 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-20 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-21 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-22 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-23 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-24 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-25 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-26 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-27 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-28 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-29 
/apps/hive/warehouse/test_db.db/test_table/end_date=2016-04-30 

Nehmen wir an, dass die Datei _metadata nonexisting oder veraltet ist. Gibt es eine Möglichkeit, es über Hive-Befehl neu zu erstellen/generieren, ohne den gesamten Funke-Job zu starten?

+0

@Niemand bitte bearbeiten Sie die Frage mit Ihrem letzten Kommentar! –

+1

Sind die _metadata nicht in Ihren partitionierten Ordnern neben der .parquet-Datei enthalten? Können Sie auch die Dateien von einer Spark-Shell lesen? –

+0

Ja, einige Metadaten sind in Dateien selbst vorhanden und ja, sie sind sowohl von Spark Shell als auch von Hive abfragbar. Es ist nur ich denke, Stock Abfragen ist viel langsamer ohne diese bestimmte _metadata Datei vorhanden. – Niemand

Antwort

7

Ok, hier ist der Drill, Metadaten können direkt mit Parkett-Tools zugegriffen werden.

import scala.collection.JavaConverters.{collectionAsScalaIterableConverter, mapAsScalaMapConverter} 

import org.apache.parquet.hadoop.ParquetFileReader 
import org.apache.hadoop.fs.{FileSystem, Path} 
import org.apache.hadoop.conf.Configuration 

val conf = spark.sparkContext.hadoopConfiguration 

def getFooters(conf: Configuration, path: String) = { 
    val fs = FileSystem.get(conf) 
    val footers = ParquetFileReader.readAllFootersInParallel(conf, fs.getFileStatus(new Path(path))) 
    footers 
} 

Jetzt können Sie Ihre Datei-Metadaten wie folgt erhalten: Hier finden Sie die Fußzeilen für Ihre Parkett Datei zuerst erhalten müssen

def getFileMetadata(conf: Configuration, path: String) = { 
    getFooters(conf, path) 
    .asScala.map(_.getParquetMetadata.getFileMetaData.getKeyValueMetaData.asScala) 
} 

Jetzt können Sie die Metadaten Ihrer Parkett Datei erhalten :

getFileMetadata(conf, "/tmp/foo").headOption 

// Option[scala.collection.mutable.Map[String,String]] = 
// Some(Map(org.apache.spark.sql.parquet.row.metadata -> 
//  {"type":"struct","fields":[{"name":"id","type":"long","nullable":false,"metadata":{"foo":"bar"}} 
//  {"name":"txt","type":"string","nullable":true,"metadata":{}}]})) 

Wir auch extrahierter Fußzeilen verwenden können eigenständige Metadaten-Datei zu schreiben, wenn erforderlich:

import org.apache.parquet.hadoop.ParquetFileWriter 

def createMetadata(conf: Configuration, path: String) = { 
    val footers = getFooters(conf, path) 
    ParquetFileWriter.writeMetadataFile(conf, new Path(path), footers) 
} 

Ich hoffe, dies beantwortet Ihre Frage. Weitere Informationen zu Spark DataFrames und Metadaten finden Sie unter spark-gotchas repo unter awesome-spark.

Verwandte Themen