2016-05-19 13 views
13

Tôi có bảng hive được xây dựng trên một tải các tệp sàn gỗ bên ngoài. Các tệp Paruqet phải được tạo bởi công việc tạo tia lửa, nhưng do đặt cờ siêu dữ liệu thành sai nên chúng không được tạo. Tôi tự hỏi nếu nó có thể khôi phục lại nó một cách không đau đớn. Cấu trúc tệp như sau:Tạo siêu dữ liệu cho các tệp lát gỗ

/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 

Giả sử tệp _metadata không tồn tại hoặc lỗi thời. Có cách nào để tạo lại nó thông qua lệnh hive/tạo ra nó mà không cần phải bắt đầu công việc toàn bộ tia lửa?

+0

@Niemand vui lòng chỉnh sửa câu hỏi bằng nhận xét mới nhất của bạn! –

+1

Không phải _metadata nằm trong thư mục được phân đoạn của bạn cùng với tệp .parquet? Ngoài ra, bạn có thể đọc các tập tin từ một vỏ tia lửa? –

+0

Có, một số siêu dữ liệu có mặt trong các tệp của chính chúng và có, chúng có thể truy vấn được từ cả hai trình bao vỏ và tổ ong. Nó chỉ là tôi nghĩ rằng truy vấn hive là chậm hơn nhiều mà không có tập tin _metadata cụ thể này hiện nay. – Niemand

Trả lời

7

Ok vì vậy đây là máy khoan, siêu dữ liệu có thể được truy cập trực tiếp bằng cách sử dụng công cụ Parquet. Bạn sẽ cần phải nhận được footers cho file gỗ của bạn đầu tiên:

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 
} 

Bây giờ bạn có thể nhận được siêu dữ liệu tập tin của bạn như sau:

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

Bây giờ bạn có thể nhận được các siêu dữ liệu của tập tin sàn gỗ của bạn :

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

Chúng tôi cũng có thể sử dụng chân trang được trích xuất để ghi tệp siêu dữ liệu độc lập khi cần:

import org.apache.parquet.hadoop.ParquetFileWriter 

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

Tôi hy vọng điều này sẽ trả lời câu hỏi của bạn. Bạn có thể đọc thêm về Spark DataFrames và Metadata trên spark-gotchas repo của awesome-spark.

Các vấn đề liên quan