Подтвердить что ты не робот

Создание метаданных для паркетных файлов

У меня есть таблица улья, которая построена поверх нагрузки внешних паркетных файлов. Файлы Paruqet должны генерироваться искровым заданием, но из-за установки флага метаданных на false они не были сгенерированы. Мне интересно, можно ли восстановить его каким-то безболезненным способом. Структура файлов выглядит следующим образом:

/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

Предположим, что файл _metadata не существует или устарел. Есть ли способ воссоздать его с помощью команды hive/сгенерировать ее без необходимости запуска всей искровой работы?

4b9b3361

Ответ 1

Итак, вот дрель, метаданные можно получить непосредственно с помощью инструментов Паркет. Сначала вам нужно получить нижние колонтитулы для вашего паркетного файла:

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
}

Теперь вы можете получить метаданные файлов следующим образом:

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

Теперь вы можете получить метаданные вашего файла паркета:

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

Мы также можем использовать извлеченные нижние колонтитулы для записи автономного файла метаданных при необходимости:

import org.apache.parquet.hadoop.ParquetFileWriter

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

Надеюсь, это ответит на ваш вопрос. Вы можете больше узнать о Spark DataFrames и Metadata на awesome-spark spark-gotchas Сделки рЕПО.