2016-05-19 10 views
13

私は外部の寄木張りファイルの負荷の上に構築されたハイブテーブルを持っています。 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コマンドで再作成する方法はありますか?スパークジョブ全体を開始する必要はありません。

+0

@Niemand最新のコメントで質問を編集してください。 –

+1

_metadataは、.parquetファイルと一緒にパーティション化されたフォルダの内側にはありませんか?また、あなたはsparkシェルからファイルを読むことができますか? –

+0

はい、いくつかのメタデータはファイル自体に存在し、はい、それらはsparkシェルとハイブの両方からクエリ可能です。これは、この特定の_metadataファイルが存在しなければ、ハイブのクエリ処理がはるかに遅いと私は思っています。 – Niemand

答えて

7

ここではドリルがあります。メタデータは、パーケットツールを使用して直接アクセスできます。あなたはまず自分の寄木細工のファイルのフッタを取得する必要があります:

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) 
} 

これがあなたの質問に答えることを願っています。 awesome-sparkspark-gotchas repoのSpark DataFrameとメタデータについて詳しく読むことができます。

関連する問題