Spark: UDF thực thi nhiều lần


9

Tôi có một khung dữ liệu với mã sau đây:

def test(lat: Double, lon: Double) = {
  println(s"testing ${lat / lon}")
  Map("one" -> "one", "two" -> "two")
}

val testUDF = udf(test _)

df.withColumn("test", testUDF(col("lat"), col("lon")))
  .withColumn("test1", col("test.one"))
  .withColumn("test2", col("test.two"))

Bây giờ kiểm tra các bản ghi, tôi phát hiện ra rằng đối với mỗi hàng, UDF được thực thi 3 lần. Nếu tôi thêm "test3" từ cột "test.three" thì UDF được thực thi một lần nữa.

Ai đó có thể giải thích cho tôi tại sao?

Điều này có thể tránh được một cách chính xác (mà không lưu bộ đệm dữ liệu sau khi "kiểm tra" được thêm vào, ngay cả khi điều này hoạt động)?


Ý anh là gì? Bạn đang gọi chức năng kiểm tra ba lần. Đó là lý do tại sao nó được thực hiện ba lần. Không chắc chắn tại sao bạn biến nó thành UDF. Tại sao không chỉ làm cho Bản đồ một val?
dùng4601931

Đây chỉ là một ví dụ để hiển thị hành vi của tia lửa. Đối với tôi "test" là một cột mới chứa cấu trúc, sau đó truy cập vào bất kỳ phần nào của cấu trúc không nên thực hiện lại UDF. Làm thế nào tôi sai?
Rolintocour

Tôi đã thử in lược đồ, DataType của "test" Mapkhông phải là Struct. Bây giờ thay vì trả về một Bản đồ, nếu UDF trả về một lớp trường hợp như Test (một Chuỗi, hai: Chuỗi) thì testthực sự là Cấu trúc nhưng luôn có nhiều lệnh thực thi của UDF.
Rolintocour


bộ nhớ đệm nên hoạt động theo câu trả lời này: stackoverflow.com/a/40962714/1138523
Raphael Roth

Câu trả lời:


5

Nếu bạn muốn tránh nhiều cuộc gọi đến udf (rất hữu ích, đặc biệt nếu udf là nút cổ chai trong công việc của bạn), bạn có thể thực hiện như sau:

val testUDF = udf(test _).asNondeterministic()

Về cơ bản, bạn nói với Spark rằng chức năng của bạn không mang tính quyết định và bây giờ Spark đảm bảo rằng nó chỉ được gọi một lần vì không an toàn khi gọi nó nhiều lần (mỗi cuộc gọi có thể trả về kết quả khác nhau).

Ngoài ra, hãy lưu ý rằng thủ thuật này không miễn phí, bằng cách này, bạn đang đặt một số ràng buộc cho trình tối ưu hóa, một tác dụng phụ của ví dụ này là trình tối ưu hóa Spark không đẩy các bộ lọc qua các biểu thức không xác định để bạn có trách nhiệm tối ưu vị trí của các bộ lọc trong truy vấn của bạn.


đẹp! câu trả lời này cũng thuộc về đây: stackoverflow.com/questions / 40320563 / Từ
Raphael Roth

Trong trường hợp của tôi, asNondeterministiccác UDF chỉ thực hiện một lần. Với explode(array(myUdf($"id")))giải pháp, nó vẫn được thực hiện hai lần.
Rolintocour
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.