2015-09-29 16 views
10

Tôi có một cấu trúc thư mục dựa trên hai phân vùng, như thế này:tiết kiệm để gỗ parquet subpartition

People 
    > surname=Doe 
     > name=John 
     > name=Joe 
    > surname=White 
     > name=Josh 
     > name=Julien 

Tôi đọc file gỗ với thông tin duy nhất về tất cả Liệu, và do đó tôi trực tiếp nêu rõ họ = Doe như một thư mục đầu ra cho DataFrame của tôi. Bây giờ vấn đề là tôi đang cố gắng để thêm phân vùng dựa trên tên với partitionBy("name") trên văn bản.

df.write.partitionBy("name").parquet(outputDir) 

(outputDir chứa một đường dẫn đến thư mục Doe)

Điều này gây ra một lỗi như dưới đây:

Caused by: java.lang.AssertionError: assertion failed: Conflicting partition column names detected: 
    Partition column name list #0: surname, name 
    Partition column name list #1: surname 

Bất cứ lời khuyên làm thế nào để giải quyết nó? Nó có thể xảy ra do tệp _SUCCESS được tạo trong thư mục họ, cung cấp các gợi ý sai cho Spark - khi tôi xóa các tệp _SUCCESS_metadata Spark có thể đọc mọi thứ mà không gặp bất kỳ sự cố nào.

Trả lời

7

tôi đã quản lý để giải quyết nó với một workaround - Tôi không nghĩ rằng đây là một ý tưởng tốt, nhưng tôi vô hiệu hóa việc tạo ra _SUCCESS bổ sung và các file _metadata với:

sc.hadoopConfiguration.set("mapreduce.fileoutputcommitter.marksuccessfuljobs", "false") 
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false") 

Bằng cách đó Spark sẽ không nhận được bất kỳ ý tưởng ngu ngốc nào về cấu trúc phân vùng.

Tùy chọn khác sẽ lưu vào thư mục "thích hợp" - Mọi người và phân vùng theo họ và tên, nhưng bạn phải nhớ rằng tùy chọn duy nhất là thiết lập SaveMode thành Append và xóa thủ công các thư mục mà bạn mong muốn ghi đè (điều này là thực sự dễ bị lỗi):

df.write.mode(SaveMode.Append).partitionBy("surname","name").parquet("/People") 

không sử dụng SaveMode ghi đè lên trong trường hợp này - điều này sẽ xóa tất cả các directores họ.

+0

Kể từ khi không ai khác gửi và tiền thưởng của tôi hết hạn , Tôi chấp nhận giải pháp này là giải pháp duy nhất được biết đến hiện nay. – Niemand

+0

Điều này làm việc cho tôi cho Spark 1.6.3 'sc._jsc.hadoopConfiguration(). Set (" mapreduce.fileoutputcommitter.marksuccessfuljobs "," false ") sc._jsc.hadoopConfiguration(). Set (" parquet.enable.summary -metadata "," false ")' – Vezir

2
sc.hadoopConfiguration.set("parquet.enable.summary-metadata", "false") 

là khá hợp lý, nếu bạn đã bật siêu dữ liệu tóm tắt thì ghi tệp siêu dữ liệu có thể trở thành nút cổ chai IO khi đọc và ghi.

Cách thay thế cho giải pháp của bạn có thể để thêm một .mode ("thêm") để ghi của bạn, nhưng với thư mục cha gốc là điểm đến,

df.write.mode("append").partitionBy("name").parquet("/People") 
+0

Vấn đề với phụ thêm là tôi sẽ phải xóa dữ liệu theo cách thủ công, điều này sẽ khó chịu trong trường hợp của tôi. – Niemand

+0

Đúng, nhưng sau đó xóa phân vùng tệp trong Spark là thô sơ lúc tốt nhất ... –