2016-02-04 15 views
11

Trong tài liệu của Spark, nó nói rằng phương thức RDDs reduce yêu cầu hàm nhị phân kết hợp và giao hoán.Spark: sự khác nhau về ngữ nghĩa giữa giảm và giảmByKey

Tuy nhiên, phương thức reduceByKey CHỈ yêu cầu hàm nhị phân kết hợp.

sc.textFile("file4kB", 4) 

Tôi đã thực hiện một số thử nghiệm và dường như đó là hành vi tôi nhận được. Tại sao sự khác biệt này? Tại sao reduceByKey đảm bảo chức năng nhị phân luôn được áp dụng theo thứ tự nhất định (để phù hợp với việc thiếu tính giao hoán) khi reduce không?

Ví dụ, nếu một tải một số (nhỏ) văn bản với 4 phân vùng (tối thiểu):

val r = sc.textFile("file4k", 4) 

thì:

r.reduce(_ + _) 

trả về một chuỗi nơi phụ tùng không phải lúc nào theo thứ tự, trong khi:

r.map(x => (1,x)).reduceByKey(_ + _).first 

luôn trả về cùng một chuỗi (trong đó mọi thứ theo cùng thứ tự so với trong origina l tập tin).

(Tôi đã kiểm tra với r.glom và nội dung tệp thực sự trải rộng trên 4 phân vùng, không có phân vùng trống).

+2

Tôi đoán ý tưởng với 'reduceByKey' là bạn có thể có rất nhiều các khóa khác nhau để bạn có thể giảm mọi thứ cho một khóa duy nhất trên một chuỗi đơn lẻ, điều đó có nghĩa là bạn luôn có thể chạy tính toán từ trái sang phải. Ngược lại, 'reduce' sẽ thường được sử dụng trên một tập dữ liệu lớn, do đó, không được quan tâm đến thứ tự các hoạt động. –

+0

Bạn đang sử dụng bao nhiêu trình thực thi trong thử nghiệm của mình? – gprivitera

Trả lời

7

Theo như tôi lo ngại đây là lỗi trong tài liệu và kết quả bạn thấy chỉ đơn giản là ngẫu nhiên. Thực hành, other resources và đơn giản analysis of the code cho thấy chức năng được chuyển đến reduceByKey không chỉ là kết hợp mà còn giao hoán.

  • thực hành - trong khi có vẻ như thứ tự được giữ nguyên ở chế độ cục bộ, nó không còn đúng khi bạn chạy Spark trên một cụm, bao gồm chế độ độc lập.

  • các nguồn lực khác - để trích dẫn Data Exploration Using Spark từ AmpCamp 3:

    Có một phương pháp thuận tiện gọi reduceByKey trong Spark cho chính xác mô hình này. Lưu ý rằng đối số thứ hai để reduceByKey xác định số lượng bộ giảm tốc để sử dụng. Theo mặc định, Spark giả định rằng hàm reduce là giao hoán và kết hợp và áp dụng các combiners ở phía người lập bản đồ.

  • mã - reduceByKey được thực hiện sử dụng combineByKeyWithClassTag và tạo ShuffledRDD. Vì Spark không đảm bảo thứ tự sau khi xáo trộn, cách duy nhất để khôi phục nó là đính kèm một số siêu dữ liệu vào các bản ghi được giảm một phần. Theo như tôi có thể nói không có gì như thế này xảy ra.

Trên ghi chú bên reduce vì nó được triển khai trong PySpark sẽ hoạt động tốt với chức năng chỉ giao hoán. Đó là tất nhiên chỉ là một chi tiết của một thực hiện và không phải là một phần của hợp đồng.

+3

Tôi muốn thêm rằng giảm là một hành động, trả về dữ liệu cho trình điều khiển, trong khi reduceByKey là một phép biến đổi, trả về một RDD – rhernando

+0

Cảm ơn! Nhưng sau đó, có cách nào đó trong Spark để đảm bảo tính chính xác của một điều trị không giao hoán không? Hoặc là nó vượt ra ngoài phạm vi của Spark? –

+0

Tôi không chắc chắn nếu hiểu câu hỏi. Bạn có hỏi liệu có thể tự động kiểm tra/chứng minh tính giao hoán hay chỉ đơn giản là muốn sử dụng hàm không giao hoán với 'reduce'? Nếu đây là trường hợp thứ hai bắt chước hành vi PySpark ('mapPartitions (reduceFunc)' => 'collect' => reduce (reduceFunc)') nên làm việc với một số hình phạt hiệu suất. – zero323

1

Theo tài liệu mã, cập nhật/sửa chữa gần đây.(Nhờ @ zero323):

reduceByKey kết hợp các giá trị cho mỗi phím sử dụng kết hợp và giao hoán chức năng giảm. Điều này cũng sẽ thực hiện việc hợp nhất cục bộ trên mỗi trình ánh xạ trước khi gửi kết quả tới bộ giảm tốc, tương tự như "bộ kết hợp" trong MapReduce.

Vì vậy, trên thực tế, đó là lỗi tài liệu như @ zero323 được chỉ ra trong câu trả lời của anh ấy.

Bạn có thể kiểm tra các liên kết sau để mã để đảm bảo:

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