Kullanıcı tanımlı skaler işlevler - Scala

Bu makalede Scala kullanıcı tanımlı işlev (UDF) örnekleri yer alır. Spark SQL'de UDF'lerin nasıl kaydedilecekleri, UDF'lerin nasıl çağrılacakları ve alt ifadelerin değerlendirme sırasına ilişkin uyarılar gösterilir. Daha fazla ayrıntı için bkz. Dış kullanıcı tanımlı skaler işlevler (UDF).

Gereksinimler

  • Unity Kataloğu etkin hesaplama kaynaklarında standart erişim moduna sahip Scala UDF’leri için Databricks Runtime 14.2 veya üzeri gereklidir.

  • Unity Catalog etkinleştirilmiş kümelerde Scala UDF'ler için ARM instance desteği, Databricks Runtime 15.2 veya üzerini gerektirir.

İşlevi UDF olarak kaydetme

val squared = (s: Long) => {
  s * s
}
spark.udf.register("square", squared)

Spark SQL'de UDF'yi çağırma

spark.range(1, 20).createOrReplaceTempView("test")
%sql select id, square(id) as id_squared from test

DataFrame'lerle UDF kullanma

import org.apache.spark.sql.functions.{col, udf}
val squared = udf((s: Long) => s * s)
display(spark.range(1, 20).select(squared(col("id")) as "id_squared"))

Değerlendirme sırası ve null denetimi

Spark SQL (SQL ve DataFrame ile Veri Kümesi API'leri dahil) alt ifadelerin değerlendirilme sırasını garanti etmez. Özellikle, bir işlecin veya işlevin girişleri mutlaka soldan sağa veya başka bir sabit sırada değerlendirilmez. Örneğin, mantıksal AND ve OR ifadelerde soldan sağa "kısa devre" semantiği yoktur.

Bu nedenle, boole ifadelerinin yan etkilerine veya değerlendirme sırasına ve WHERE ve HAVING yan tümcelerinin sırasına güvenmek tehlikelidir, çünkü bu ifadeler ve yan tümceler sorgu iyileştirme ve planlama sırasında yeniden sıralanabilir. Özellikle, bir UDF null denetim için SQL'de kısa devre semantiği kullanıyorsa, UDF'yi çağırmadan önce null denetimin gerçekleşeceğinin garantisi yoktur. Örneğin,

spark.udf.register("strlen", (s: String) => s.length)
spark.sql("select s from test1 where s is not null and strlen(s) > 1") // no guarantee

Bu WHERE yan tümce, null değerleri filtreledikten sonra UDF'nin çağrılacağı garanti strlen etmez.

Doğru null denetimi gerçekleştirmek için aşağıdakilerden birini yapmanızı öneririz:

  • UDF'nin kendisini null algılayan hale getirin ve UDF'nin içinde null denetimi yapın
  • Null denetimi yapmak ve koşullu dalda UDF'yi çağırmak için IF veya CASE WHEN ifadelerini kullanın.
spark.udf.register("strlen_nullsafe", (s: String) => if (s != null) s.length else -1)
spark.sql("select s from test1 where s is not null and strlen_nullsafe(s) > 1") // ok
spark.sql("select s from test1 where if(s is not null, strlen(s), null) > 1")   // ok

Yazılan Veri Kümesi API'leri

Not

Bu özellik, Databricks Runtime 15.4 ve üzerinde standart erişim moduna sahip Unity Kataloğu etkin kümelerde desteklenir.

Yazılan Veri Kümesi API'leri, kullanıcı tanımlı bir işlevle elde edilen Veri Kümeleri üzerinde eşleme, filtre ve toplama gibi dönüştürmeleri çalıştırmanızı sağlar.

Örneğin, aşağıdaki Scala uygulaması map() API'sini kullanarak bir sonuç sütunundaki bir sayıyı ön ekli dizeye değiştirir.

spark.range(3).map(f => s"row-$f").show()

Bu örnekte map() API'si kullanılırken, bu durum filter(), mapPartitions(), foreach(), foreachPartition(), reduce() ve flatMap() gibi diğer türdeki Veri Kümesi API’leri için de geçerlidir.

Scala UDF özellikleri ve Databricks Runtime uyumluluğu

Aşağıdaki Scala özellikleri, Unity Kataloğu etkin kümelerde standart (paylaşılan) erişim modunda kullanıldığında en düşük Databricks Runtime sürümlerini gerektirir.

Özellik Minimimum Databricks Runtime sürümü
Skaler UDF'ler Databricks Runtime 14.2
Dataset.map, Dataset.mapPartitions, Dataset.filter, Dataset.reduce, , Dataset.flatMap Databricks Runtime 15.4
KeyValueGroupedDataset.flatMapGroups, KeyValueGroupedDataset.mapGroups Databricks Runtime 15.4
(Akış) foreachWriter Sink Databricks Runtime 15.4
(Akış) foreachBatch Databricks Çalışma Zamanı 16.1
(Akış) KeyValueGroupedDataset.flatMapGroupsWithState Databricks Runtime 16.2