Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Собственный механизм выполнения в Microsoft Fabric теперь поддерживает Python определяемые пользователем функции (UDFs), Scala UDFs и сложные типы данных (массивы, карты и структуры). Эти возможности позволяют создавать экспрессивные приложения Spark без ущерба для производительности.
поддержка UDF Python
Python является одним из самых популярных языков в области проектирования и обработки и анализа данных. Исторически пользовательские функции Python (UDF) в Spark создавали значительные накладные расходы из-за затрат на сериализацию между JVM и рабочими процессами Python. Машинный обработчик выполнения сводит к минимуму эти дорогостоящие переходы, что позволяет ускорить выполнение без изменений кода.
Как работают пользовательские функции Python (UDF) во встроенном механизме выполнения
В обычной модели выполнения Spark Python выполнение UDF включает:
- Преобразование данных из внутреннего формата Spark.
- Сериализация и передача в рабочие процессы Python.
- Выполнение UDF Python.
- Сериализация результатов обратно в JVM.
- Spark возобновляет выполнение.
Это перемещение между разными средами выполнения создает издержки на сериализацию и десериализацию, приводит к неэффективному использованию ЦП и нарушению конвейеров колоночного выполнения. Собственный модуль выполнения сокращает эти затраты, оптимизируя путь передачи данных и сохраняя векторную обработку, где это возможно.
Поддерживаемые типы UDF Python
Собственный обработчик выполнения поддерживает следующее:
-
Скалярные UDF: построчные функции Python, зарегистрированные с помощью
udf(). -
Векторизованные UDF (Pandas): функции, декорированные с помощью
@pandas_udf, которые обрабатывают пакеты данных, используя Apache Arrow для их эффективной передачи.
Векторизованные пользовательские UDF обеспечивают наибольший прирост производительности, поскольку они естественным образом согласуются со столбцовой моделью обработки механизма нативного выполнения.
Пример: Векторизованная Python UDF
import pandas as pd
from pyspark.sql.functions import pandas_udf
from pyspark.sql.types import DoubleType
@pandas_udf(DoubleType())
def calculate_discount(price: pd.Series, rate: pd.Series) -> pd.Series:
return price * (1 - rate)
df = spark.table("sales.transactions")
result = df.withColumn("discounted_price", calculate_discount(df.price, df.discount_rate))
result.show()
Никакой дополнительной настройки, помимо включения встроенного механизма выполнения, не требуется. Существующие пользовательские функции Python автоматически получают эти преимущества.
Поддержка UDF в Scala
Встроенный движок выполнения также ускоряет пользовательские функции Scala (UDF). Поскольку Scala UDF выполняются непосредственно в JVM, движок может передавать поддерживаемые операции в векторизованный контур выполнения на C++, при этом обеспечивая эффективное вычисление Scala UDF в той же среде выполнения.
Пример: Scala UDF
import org.apache.spark.sql.functions.udf
val toUpperCase = udf((s: String) => s.toUpperCase)
val df = spark.table("catalog.customers")
val result = df.withColumn("name_upper", toUpperCase(df("name")))
result.show()
UDF на Scala, работающие с поддерживаемыми типами данных, ускоряются без изменения кода при включении собственного механизма выполнения.
Поддержка сложных типов данных
Современные архитектуры Lakehouse опираются на полуструктурированные и вложенные данные. В собственном обработчике выполнения теперь реализована оптимизированная поддержка:
| Тип данных | Description | Пример варианта использования |
|---|---|---|
| массива | Упорядоченная коллекция элементов | Теги событий, категории продуктов |
| Схема | Пары "ключ-значение" | Свойства конфигурации, метаданные |
| Структура | Именованные поля с разными типами | Вложенные записи клиента, объекты адресов |
Операции, поддерживаемые для сложных типов
Собственный механизм выполнения ускоряет распространенные операции с сложными типами данных:
- Функции массива:
explode,array_contains,sizeflattentransform - Функции карты:
map_keys,map_valueselement_at - Доступ к структуре: доступ к полю через точечную нотацию,
getField - Вложенные сочетания: массивы структур, карты со значениями массивов
Пример. Работа с массивами и структурами
from pyspark.sql.functions import explode, col, size
# Read data with nested schema
df = spark.table("events.telemetry")
# Operations on arrays - accelerated by native engine
result = (df
.filter(size(col("tags")) > 0)
.select(
col("event_id"),
col("metadata.source"), # Struct field access
explode(col("tags")).alias("tag")
)
)
result.show()
Пример. Работа с картами
from pyspark.sql.functions import map_keys, map_values, col
df = spark.table("config.settings")
# Map operations - accelerated by native engine
result = (df
.select(
col("setting_id"),
map_keys(col("properties")).alias("keys"),
map_values(col("properties")).alias("values")
)
)
result.show()
Результаты производительности
Внутренние сравнительные тесты показывают значительные улучшения для различных рабочих нагрузок, использующих пользовательские функции Python (UDF) и сложные типы данных:
| Тип рабочей нагрузки | Повышение производительности |
|---|---|
| Векторизованные пользовательские функции Python | До 5,76x быстрее |
| Скалярные пользовательские функции Python | До 1,08x быстрее |
| Сквозной TPC-DS (со сложными типами) | До 2,35x быстрее |
Эти преимущества приводят к снижению затрат на сериализацию, улучшению векторизации и сквозной обработке столбцов.
Преимущества расширенных шаблонов lakehouse
Сложное ускорение типов данных особенно важно для:
- Оптимизация Z-ORDER: вложенные столбцы участвуют в оптимизированном макете данных.
- Жидкая кластеризация: столбцы сложных типов можно кластеризовать без разворачивания.
- Частично структурированная аналитика: полезные данные JSON и потоки событий остаются вложенными для естественного запроса.
- Архитектуры, управляемые событиями: данные телеметрии и Интернета вещей сохраняют иерархическую структуру.
Вместо выравнивания данных или перестройки конвейеров ради повышения производительности работайте со сложными структурами данных, сохраняя высокую эффективность исполнения.
Включение функции
Поддержка Python UDF, Scala UDF и сложных типов данных доступна при включении собственного механизма выполнения. Никаких дополнительных настроек не требуется.
Сведения о включении собственного механизма выполнения см. в разделе «Механизм выполнения для проектирования данных Fabric».
Необходимые условия
- Среда выполнения 1.3 (Apache Spark 3.5) или среда выполнения 2.0 (Apache Spark 4.0).
- Собственный механизм выполнения включен на уровне среды, записной книжки или определения задания Spark.
Ограничения
- Не все библиотеки Python поддерживаются в векторизованном пути. Библиотеки, требующие сериализации произвольных объектов Python, могут по-прежнему вызывать переключение на резервный режим.
- Глубоко вложенные сложные типы (например, массивы карт структур) могут вернуться к подсистеме JVM для определенных операций.
- Режим ANSI не поддерживается в собственном обработчике выполнения.