2015-06-25 18 views
5

Tôi có đoạn mã sau vào Spark:Spark: kết thành một khối rất chậm ngay cả những dữ liệu đầu ra là rất nhỏ

myData.filter(t => t.getMyEnum() == null) 
     .map(t => t.toString) 
     .saveAsTextFile("myOutput") 

Có 2000+ tập tin trong thư mục myOutput, nhưng chỉ có một vài t.getMyEnum() == null, vì vậy chỉ có rất ít bản ghi đầu ra. Vì tôi không muốn tìm kiếm chỉ là một vài kết quả đầu ra trong 2000+ file đầu ra, tôi đã cố gắng để kết hợp đầu ra sử dụng kết thành một khối như dưới đây:

myData.filter(t => t.getMyEnum() == null) 
     .map(t => t.toString) 
     .coalesce(1, false) 
     .saveAsTextFile("myOutput") 

Sau đó, công việc trở nên rất chậm! Tôi tự hỏi tại sao nó quá chậm? Chỉ có một vài bản ghi đầu ra phân tán trong 2000 phân vùng? Có cách nào tốt hơn để giải quyết vấn đề này không?

Trả lời

8

nếu bạn đang kết hợp quyết liệt, ví dụ: để numPartitions = 1, điều này có thể dẫn đến việc tính toán của bạn diễn ra trên ít nút hơn bạn thích (ví dụ: một nút trong trường hợp numPartitions = 1). Để tránh điều này, bạn có thể chuyển shuffle = true. Điều này sẽ thêm một bước ngẫu nhiên, nhưng có nghĩa là các phân vùng ngược dòng hiện tại sẽ được thực thi song song (cho dù phân vùng hiện tại là gì).

Lưu ý: Với shuffle = true, bạn thực sự có thể kết hợp với số phân vùng lớn hơn. Điều này rất hữu ích nếu bạn có một số lượng nhỏ phân vùng, nói 100, có khả năng với một vài phân vùng lớn bất thường. Gọi coalesce (1000, shuffle = true) sẽ dẫn đến 1000 phân vùng với dữ liệu được phân phối bằng cách sử dụng trình phân vùng băm.

Vì vậy hãy thử bằng cách chuyển giá trị đúng cho hàm coalesce. tức là

myData.filter(_.getMyEnum == null) 
     .map(_.toString) 
     .coalesce(1, shuffle = true) 
     .saveAsTextFile("myOutput") 
+2

Là 'coalesce (1, shuffle = true)' tương đương với 'repartition (1)'? – asmaier

+1

Có, nó là như nhau: nếu bạn nhìn vào mã nguồn, phân vùng (1) có shuffle được đặt thành true theo mặc định. – sversch

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