Іскра: АДС виконується багато разів


9

У мене є кадр даних із таким кодом:

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"))

Тепер перевіривши журнали, я з’ясував, що для кожного рядка UDF виконується 3 рази. Якщо я додаю "test3" із стовпця "test.three", то UDF виконується ще раз.

Хтось може мені пояснити, чому?

Чи можна цього уникнути належним чином (без кешування кадрів даних після додавання "тесту", навіть якщо це працює)?


Що ви маєте на увазі? Ви тричі викликаєте тестову функцію. Ось чому його виконують тричі. Не впевнений, чому ви робите це АДС. Чому б просто не зробити Карту вал?
user4601931

Це лише приклад, щоб показати поведінку іскри. Для мене "тест" - це новий стовпець, який містить структуру, то доступ до будь-якої частини структури не повинен виконувати UDF знову. Як я помиляюся?
Rolintocour

Я спробував надрукувати схему, DataType "тесту" є, Mapа не Struct. Тепер замість повернення Map, якщо UDF повертає клас регістрів, як Test (одна строка, два: String), то testце справді структура, але завжди існує стільки виконання UDF.
Rolintocour


кешування має працювати відповідно до цієї відповіді: stackoverflow.com/a/40962714/1138523
Рафаель Рот

Відповіді:


5

Якщо ви хочете уникнути багаторазових дзвінків до udf (що корисно, особливо якщо udf є вузьким місцем у вашій роботі), ви можете зробити це наступним чином:

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

В основному ви говорите Spark, що ваша функція не є детермінованою, і тепер Spark переконуєсь, що вона викликається лише один раз, оскільки її не можна безпечно викликати кілька разів (кожен виклик може призвести до різного результату).

Також майте на увазі, що цей трюк не є безкоштовним, виконуючи це, ви накладаєте певні обмеження на оптимізатор. Одним з побічних ефектів цього є, наприклад, що Spark Optimizer не натискає фільтри через вирази, які не є детермінованими, тому ви станете відповідальними за оптимальне положення фільтрів у вашому запиті.


приємно! ця відповідь також належить тут: stackoverflow.com/questions/40320563/…
Рафаель Рот

У моєму випадку asNondeterministicзмушує АДС виконати лише один раз. З explode(array(myUdf($"id")))рішенням воно все одно виконується двічі.
Ролінтокур
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.