Поделиться через


Основные сведения о коде Apache Spark для разработчиков U-SQL

Внимание

Azure Data Lake Analytics вышел из эксплуатации 29 февраля 2024 года. Дополнительные сведения см. в этом объявлении.

Для аналитики данных ваша организация может использовать Azure Synapse Analytics или Microsoft Fabric.

В этом разделе содержатся общие руководства по преобразованию скриптов U-SQL в Apache Spark.

Общие сведения о скриптах U-SQL, языке Spark и парадигмах обработки

Прежде чем приступить к миграции скриптов U-SQL Azure Data Lake Analytics в Spark, полезно понять общие языковые и обрабатывающие философии двух систем.

U-SQL — это похожий на SQL язык декларативных запросов, использующий парадигму потока данных и позволяющий легко внедрять и масштабировать пользовательский код, написанный на .NET (например, C#), Python и R. Пользовательские расширения могут реализовывать простые выражения или определяемые пользователем функции, но также могут предоставить пользователю возможность реализовывать так называемые пользовательские операторы для выполнения преобразований, извлечения и записи выходных данных на уровне наборов строк.

Spark — это платформа с горизонтальным увеличением масштаба, предлагающая несколько языковых привязок в Scala, Java, Python, .NET и т. д., где вы в основном пишете код на одном из этих языков, создаете абстракции данных, которые называются отказоустойчивыми распределенными наборами (RDD), кадрами и наборами данных, а затем используете LINQ-ориентированный язык DSL для их преобразования. Он также предоставляет SparkSQL в качестве декларативного подъязыка, работающего на абстракциях датафреймов и наборов данных. DSL предусматривает две категории операций, преобразований и действий. Применение преобразований к абстракции данных не будет выполнять преобразование, а вместо этого создает план выполнения, который будет отправлен для оценки с помощью действия (например, запись результата во временную таблицу или файл или печать результата).

Таким образом, при переводе скрипта U-SQL в программу Spark необходимо решить, какой язык вы хотите использовать, чтобы по крайней мере создать абстракцию кадра данных (которая в настоящее время является наиболее часто используемой абстракцией данных) и следует ли записывать декларативные преобразования потока данных с помощью DSL или SparkSQL. В некоторых более сложных случаях может потребоваться разделить скрипт U-SQL на последовательность шагов, таких как Spark, и других операций, реализованных с помощью Azure Batch или Azure Functions.

Кроме того, Azure Data Lake Analytics предлагает U-SQL в бессерверной среде службы заданий, где ресурсы выделяются для каждого задания, в то время как Azure Synapse Spark, Azure Databricks и Azure HDInsight предлагают Spark в виде службы кластера или с так называемыми шаблонами пула Spark. При преобразовании приложения необходимо учитывать последствия создания, изменения размера, масштабирования и вывода из эксплуатации кластеров или пулов.

Преобразование скриптов U-SQL

Скрипты U-SQL соответствуют следующему шаблону обработки:

  1. Данные считываются либо из неструктурированных файлов, используя инструкцию EXTRACT, с указанием местоположения или спецификации набора файлов, и встроенного или определяемого пользователем средства извлечения с желаемой схемой, либо из таблиц U-SQL (управляемых или внешних). Он представлен как набор строк.
  2. Наборы строк преобразуются в ряд инструкций U-SQL, которые применяют выражения U-SQL к наборам строк и создают новые наборы строк.
  3. Наконец, результирующие наборы строк выводятся либо в файлы с помощью инструкции OUTPUT, которая задает местоположение и используется со встроенным или заданным пользователем средством вывода, либо в таблицу U-SQL.

Сценарий выполняется лениво, то есть каждый шаг извлечения и преобразования объединяется в дерево выражений и просчитывается на глобальном уровне (поток обработки данных).

Программы Spark схожи тем, что используют соединители Spark для чтения и создания кадров данных, а затем применяются преобразования для кадров данных на языке DSL или SparkSQL, а после этого результаты записываются в файлы, временные таблицы Spark, некоторые типы языков программирования или выводятся на консоль.

Преобразование кода .NET

Язык выражений U-SQL — C# и предлагает различные способы масштабирования пользовательского кода .NET с помощью определяемых пользователем функций, определяемых пользователем операторов и определяемых пользователем агрегатов.

Azure Synapse и Azure HDInsight Spark теперь поддерживают выполнение кода .NET с помощью .NET для Apache Spark. Это означает, что вы можете повторно использовать некоторые или все пользовательские функции .NET с помощью Spark. Обратите внимание, что U-SQL использует платформу .NET Framework, в то время как .NET для Apache Spark основан на .NET Core 3.1 или более поздней.

Пользовательские операторы U-SQL (UDOs) используют модель U-SQL UDO для распределённого выполнения кода оператора. Таким образом, объекты, определяемые пользователем (UDO), должны быть переписаны как функции, определяемые пользователем, чтобы соответствовать модели выполнения Spark.

В настоящее время .NET для Apache Spark не поддерживает определяемые пользователем агрегаты. Таким образом, определяемые пользователем агрегаты U-SQL должны быть переведены в определяемые пользователем агрегаты Spark, написанные в Scala.

Если вы не хотите воспользоваться возможностями .NET для Apache Spark, вам придется переписать свои выражения, функции, агрегаторы или соединители в эквиваленты на Spark, Scala, Java или Python.

В любом случае, если в скриптах U-SQL используется большой объем логики .NET, свяжитесь с нами через своего менеджера по работе с клиентами, чтобы получить дополнительные указания.

Следующие сведения относятся к различным случаям использования .NET и C# в скриптах U-SQL.

Преобразуйте встроенные скалярные выражения в языке U-SQL на C#

Язык выражений U-SQL — C#. Многие скалярные встроенные выражения U-SQL реализуются изначально для повышения производительности, а более сложные выражения можно выполнять путем вызова платформы .NET.

Spark имеет собственный скалярный язык выражений (как часть DSL или SparkSQL) и позволяет вызывать определяемые пользователем функции, написанные для среды выполнения JVM, .NET или Python.

Если у вас есть скалярные выражения в U-SQL, сначала следует найти наиболее подходящее скалярное выражение Spark, чтобы получить большую производительность, а затем сопоставить другие выражения с определяемой пользователем функцией языка среды выполнения Spark.

Имейте в виду, что семантика типов в .NET и C# отличается от семантики типов в средах выполнения JVM и Python, а также в DSL Spark. Дополнительные сведения о различиях в системе типов см. ниже .

Преобразование определяемых пользователем скалярных функций .NET и определяемых пользователем агрегатов

U-SQL предусматривает способы вызова произвольных скалярных функций .NET и вызова определяемых пользователем агрегатов, написанных на платформе .NET.

Spark также предлагает поддержку функций и агрегаторов, определяемых пользователем, написанных на большинстве языков, поддерживаемых Spark, которые можно вызывать из DSL и SparkSQL.

Как упоминалось выше, .NET для Apache Spark поддерживает определяемые пользователем функции, написанные в .NET, но не поддерживает определяемые пользователем агрегаты. Таким образом, для определяемых пользователем функций можно использовать .NET для Apache Spark, а определяемые пользователем агрегаты должны создаваться в Scala для Spark.

Преобразование определяемых пользователем операторов (UDO)

U-SQL предусматривает несколько категорий определяемых пользователем операторов (UDO), например средства извлечения, средства вывода, модули сжатия, процессоры, средства применения и средства объединения, которые могут быть написаны на .NET (и в некоторой степени — на Python и R).

Spark не предлагает ту же модель расширяемости для операторов, но имеет эквивалентные возможности для некоторых.

Аналогом средств извлечения и средств вывода данных в Spark являются подключаемые модули Spark. Для многих средств извлечения U-SQL можно найти эквивалентный соединитель в сообществе Spark. Для других случаев придется написать настраиваемый соединитель. Если средство извлечения U-SQL является сложным и использует несколько библиотек .NET, то может оказаться предпочтительнее создать соединитель в Scala, использующий взаимодействие для вызова библиотеки .NET, которая выполняет фактическую обработку данных. В этом случае необходимо развернуть среду выполнения .NET Core в кластере Spark и убедиться, что указанные библиотеки .NET соответствуют .NET Standard 2.0.

Другие типы UDO в U-SQL придется переработать с использованием пользовательских функций и агрегаторов, а также семантически подходящих выражений Spark DLS или SparkSQL. Например, обработчик можно сопоставить с функцией SELECT различных вызовов UDF, упакованной как функцию, которая принимает кадр данных в качестве аргумента и возвращает кадр данных.

Преобразование опциональных библиотек U-SQL

U-SQL предоставляет набор необязательных и демонстрационных библиотек, предлагающих поддержку Python, R, JSON, XML, AVRO и некоторые возможности служб ИИ Azure.

Spark предлагает собственные возможности интеграции Python и R, pySpark и SparkR, а также предусматривает соединители для чтения и записи JSON, XML и AVRO.

Если вам нужно преобразовать скрипт, ссылающийся на библиотеки служб искусственного интеллекта Azure, рекомендуется обратиться к нам через представителя учетной записи Майкрософт.

Преобразование типизированных значений

Так как система типов U-SQL основана на системе типов .NET, а Spark имеет собственную систему типов, которая влияет на связь с языком хоста, необходимо убедиться, что типы, с которыми вы работаете, близки, и для определенных типов диапазоны типов, точность и/или масштабирование могут немного отличаться. Более того, U-SQL и Spark по-разному трактуют значения null.

Типы данных

В следующей таблице приведены эквиваленты типов в Spark, Scala и PySpark для заданных типов U-SQL.

U-SQL Spark Scala PySpark
byte
sbyte ByteType Byte ByteType
int IntegerType Int IntegerType
uint
long LongType Long LongType
ulong
float FloatType Float FloatType
double DoubleType Double DoubleType
decimal DecimalType java.math.BigDecimal DecimalType
short ShortType Short ShortType
ushort
char Char
string StringType String StringType
DateTime DateType, TimestampType java.sql.Date, java.sql.Timestamp DateType, TimestampType
bool BooleanType Boolean BooleanType
Guid
byte[] BinaryType Array[Byte] BinaryType
SQL.MAP<K,V> MapType(keyType, valueType, valueContainsNull) scala.collection.Map MapType(keyType, valueType, valueContainsNull=True)
SQL.ARRAY<T> ArrayType(elementType, containsNull) scala.collection.Seq ArrayType(elementType, containsNull=True)

Дополнительные сведения см. в разделе:

Обработка значений NULL

В Spark типы по умолчанию допускают значения NULL, тогда как в U-SQL нужно явным образом помечать скалярные необъектные типы как допускающие значения NULL. Хотя Spark позволяет определить столбец как не допускающий значение NULL, он не будет применять ограничение и может привести к неправильному результату.

В Spark NULL указывает на то, что значение неизвестно. Значение NULL в Spark отлично от любого значения, включая само себя. В Spark при сравнении двух значений NULL либо значения NULL и какого-либо иного значения возвращается неизвестное значение, так как значение каждого из значений NULL неизвестно.

В U-SQL это поведение отличается, поскольку следуют семантике C#, где null различается с любым значением, но равно самому себе.

Таким образом, инструкция SELECT в SparkSQL, которая использует WHERE column_name = NULL, не вернет ни одной строки, даже если в column_name есть значения NULL, тогда как U-SQL вернет строки, где column_name установлено в null. Аналогичным образом, в Spark SELECT инструкция, которая использует WHERE column_name != NULL, не вернет ни одной строки, даже если в column_name есть значения, отличные от NULL, тогда как U-SQL вернет строки, где есть значения, отличные от NULL. Таким образом, если требуется семантика проверки null в U-SQL, следует использовать isnull и isnotnull соответственно (или их эквивалент в DSL).

Преобразование объектов каталога U-SQL

Одно из основных различий заключается в том, что скрипты U-SQL могут использовать собственные объекты каталога, многие из которых не имеют прямого эквивалента Spark.

Spark обеспечивает поддержку концепций хранилища метаданных Hive, в основном баз данных, таблиц и представлений, поэтому вы можете сопоставить базы данных и схемы U-SQL с базами данных Hive и таблицы U-SQL с таблицами Spark (см. перемещение данных, хранящихся в таблицах U-SQL), но не поддерживает функции с табличным значением (TVFs), хранимые процедуры, сборки U-SQL, внешние источники данных и т. д.

Такие объекты кода U-SQL, как представления, ТВФы, хранимые процедуры и сборки, можно моделировать с помощью функций кода и библиотек в Spark и ссылаться на них через функции и процедурные механизмы абстракции языков размещения (например, путем импорта модулей Python или обращения к функциям Scala).

Если каталог U-SQL служит для совместного использования данных и объектов кода в проектах и командах, то необходимо использовать эквивалентные механизмы общего доступа (например, Maven для совместного использования объектов кода).

Преобразование выражений набора строк U-SQL и скалярных выражений на основе SQL

Базовый язык U-SQL преобразует наборы строк и основан на языке SQL. Ниже приведен неисчерпаемый список наиболее распространенных выражений набора строк, предлагаемых в U-SQL:

  • SELECT / FROM / WHERE / GROUP BY+Агрегаты+HAVING/ORDER BY+FETCH

  • Выражения INNER/OUTER/CROSS/SEMIJOIN

  • Выражения CROSS/OUTERAPPLY

  • Выражения PIVOT/UNPIVOT

  • Конструктор набора строк VALUES

  • Выражения присваивания UNION/OUTER UNION/INTERSECT/EXCEPT

Кроме того, U-SQL предоставляет различные скалярные выражения на основе SQL, такие как

  • оконные выражения OVER
  • различные встроенные агрегаторы и функции ранжирования (SUM, FIRST и т. д.)
  • Некоторые из самых распространенных скалярных выражений SQL: CASE, LIKE, (NOT) IN, AND, OR и т. д.

Для большинства из этих выражений Spark предлагает эквивалентные выражения как в DSL, так и в SparkSQL. Некоторые выражения, не поддерживаемые изначально в Spark, придется переписывать, используя сочетание собственных выражений Spark и семантически эквивалентных шаблонов. Например, OUTER UNION следует перевести в эквивалентное сочетание проекций и объединений.

Из-за разной обработки значений NULL соединение в U-SQL всегда сопоставит строку, если оба сравниваемых столбца содержат значение NULL, в то время как соединение в Spark не будет сопоставлять такие столбцы, если только не добавлены явные проверки на NULL.

Трансформация других концепций U-SQL

U-SQL также предлагает различные другие функции и понятия, такие как федеративные запросы к базам данных SQL Server, параметрам, скалярным и лямбда-переменным, системным переменным, OPTION указаниям.

Федеративные запросы к базам данных SQL Server и внешним таблицам

U-SQL поддерживает источник данных и внешние таблицы, а также прямые запросы к базе данных SQL Azure. Хотя Spark не предлагает те же абстракции объектов, он предоставляет соединитель Spark для Базы данных SQL Azure , который можно использовать для запроса баз данных SQL.

Параметры и переменные U-SQL

Параметры и пользовательские переменные имеют эквивалентные концепции в Spark и языках размещения.

Например, в Scala можно определить переменную с помощью ключевого слова var:

var x = 2 * 3;
println(x)

Системные переменные U-SQL (переменные, начинающиеся с @@) можно разделить на две категории:

  • настраиваемые системные переменные, для которых можно задать конкретные значения, влияющие на поведение скриптов;
  • информационные переменные системы, которые запрашивают информацию о системе и уровне задания.

Большинство настраиваемых системных переменных не имеют прямого эквивалента в Spark. Некоторые информационные системные переменные могут быть смоделированы путем передачи информации в аргументах во время выполнения задания, другие могут иметь эквивалентную функцию на языке размещения Spark.

Подсказки U-SQL

U-SQL предусматривает несколько синтаксических способов предоставления указаний оптимизатору запросов и подсистеме выполнения.

  • Установка системной переменной U-SQL
  • Предложение OPTION, связанное с выражением набора строк, для указания подсказок данных или плана
  • параметр соединения в синтаксисе выражения JOIN (например, BROADCASTLEFT)

Оптимизатор запросов Spark на основе стоимости обладает собственными возможностями для предоставления указаний и настройки производительности запросов. См. соответствующую документацию.

Следующие шаги