2016-05-19 15 views
13

Mam tabelę ula, która jest zbudowana na obciążeniu zewnętrznych plików parkietu. Pliki Paruqet powinny być generowane przez zadanie iskry, ale z powodu ustawienia flagi metadanych na wartość false, nie zostały wygenerowane. Zastanawiam się, czy możliwe jest przywrócenie go w jakiś bezbolesny sposób. Struktura plików jest jak następuje:Generowanie metadanych dla plików parkietu

/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 

Załóżmy, że plik _metadata jest nieistniejącego lub nieaktualne. Czy istnieje sposób na odtworzenie go za pomocą komendy hive/generowanie go bez konieczności rozpoczynania całej pracy iskier?

+0

@Niemand proszę edytować pytanie z najnowszym komentarzem! –

+1

Czy _metadata nie znajdowałby się wewnątrz folderów podzielonych na partycje obok pliku .parquet? Czy możesz również czytać pliki z iskrzaku? –

+0

Tak, niektóre metadane są obecne w samych plikach i tak, są one możliwe do wyśledzenia zarówno ze skorupy iskry, jak i ula. Wydaje mi się, że wyszukiwanie ula jest znacznie wolniejsze bez tego konkretnego pliku _metadata. – Niemand

Odpowiedz

7

OK, więc tutaj jest wiertło, do metadanych można uzyskać bezpośredni dostęp za pomocą narzędzi do parkietów. Musisz uzyskać stopki do pliku parkietu pierwszy:

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 
} 

Teraz można uzyskać metadanych plików jak następuje:

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

Teraz można uzyskać metadanych pliku parkietu :

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":{}}]})) 

Możemy również użyć wyodrębnione stopek napisać samodzielny plik metadanych, gdy są potrzebne:

import org.apache.parquet.hadoop.ParquetFileWriter 

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

Mam nadzieję, że to odpowie na twoje pytanie. Możesz przeczytać więcej o Spark DataFrames i Metadata na awesome-spark 's spark-gotchas repo.

Powiązane problemy