Основные сведения о коде 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 или Функции Azure.

Кроме того, 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. Обратите внимание, что В-SQL используется платформа .NET Framework в то время как .NET для Apache Spark основан на .NET Core 3.1 или более поздней версии.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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 различных вызовов определяемой пользователем функции, упакованной в виде функции, которая принимает кадр данных в качестве аргумента и возвращает кадр данных.

Преобразование опциональных библиотек 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), но не поддерживает функции с табличным значением (TVF), хранимые процедуры, сборки 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 для Azure SQL Database, который можно использовать для запросов к базам данных 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 на основе стоимости обладает собственными возможностями для предоставления указаний и настройки производительности запросов. См. соответствующую документацию.

Дальнейшие действия