Руководство по миграции Databricks Runtime 7.x (неподдерживаемое)

В этом руководстве приведены рекомендации по переносу рабочих нагрузок Azure Databricks из Databricks Runtime 6.x, построенных на Apache Spark 2.4, в Databricks Runtime 7.3 LTS (неподдерживаемые) и на основе Spark 3.0.

В настоящем руководстве перечислены изменения в поведении Spark 3.0, которые могут потребовать обновления рабочих нагрузок Azure Databricks. Некоторые из этих изменений включают полное удаление поддержки Python 2, обновление до Scala 2.12, полную поддержку JDK 11 и переключение с григорианского календаря на предваряющий календарь для дат и меток времени.

Это руководство является компаньоном в руководстве по миграции Databricks Runtime 7.3 LTS (неподдерживаемое).

Сведения о миграции между версиями среды выполнения Databricks см. в руководстве по миграции Databricks Runtime.

Новые функции и улучшения, доступные в Databricks Runtime 7.x

Список новых функций, улучшений и обновлений библиотеки, включенных в Databricks Runtime 7.3 LTS, см. в заметках о выпуске для каждой версии Databricks Runtime над версией, с помощью которых выполняется миграция. Поддерживаемые версии Databricks Runtime 7.x включают:

Обновления обслуживания после выпуска перечислены в обновлениях обслуживания для Databricks Runtime (архивировано).

Системная среда Databricks Runtime 7.3 LTS

  • Операционная система: Ubuntu 18.04.5 LTS
  • Java:
    • 7.3 LTS: Zulu 8.48.0.53-CA-linux64 (сборка 1.8.0_265-b11)
  • Scala: 2.12.10
  • Python: 3.7.5
  • R: 3.6.3 (2020-02-29)
  • Delta Lake: 0.7.0

Основные изменения в поведении Apache Spark 3.0

Следующие изменения в поведении с Spark 2.4 по Spark 3.0 могут потребовать обновления рабочих нагрузок Azure Databricks при миграции с Databricks Runtime 6.x на Databricks Runtime 7.x.

Примечание.

В настоящей статье приводится список важных изменений в поведении Spark, которые следует учитывать при миграции на Databricks Runtime 7.x. Полный список изменений в поведении см. в статье Руководство по миграции Spark 3.0.1.

Основные сведения

  • В Spark 3.0 удаляется устаревший накопитель версии 1.
  • Файл журнала событий будет записан в кодировке UTF-8, а сервер журнала Spark будет воспроизводить файлы журнала событий в кодировке UTF-8. Ранее Spark записал файл журнала событий в кодировке по умолчанию для виртуальной машины Java драйвера, поэтому для чтения старых файлов журнала событий в случае несовместимой кодировки требуется сервер журнала Spark 2.x.
  • Используется новый протокол для выборки блоков в случайном порядке. При запуске приложений Spark 3.0 рекомендуется обновить внешние службы выборки в случайном порядке. По-прежнему можно использовать старые внешние службы выборки в случайном порядке, задав для конфигурации spark.shuffle.useOldFetchProtocol значение true. В противном случае Spark может столкнуться с ошибками с такими сообщениями, как IllegalArgumentException: Unexpected message type: <number>.

PySpark

  • В Spark 3.0 Column.getItem является фиксированным, и не вызывает Column.apply. Следовательно, если Column используется в качестве аргумента для getItem, следует использовать оператор индексирования. Например, map_col.getItem(col('id')) можно заменить на map_col[col('id')].
  • Начиная с Spark 3.0, имена полей Row больше не сортируются в алфавитном порядке при создании с именованными аргументами для Python версий 3.6 и выше, и порядок расположения полей будет совпадать с введенным. Чтобы включить отсортированные поля по умолчанию, как в Spark 2.4, задайте для переменной среды PYSPARK_ROW_FIELD_SORTING_ENABLED значение true как для исполнителей, так и для драйвера. Эта переменная среды должна соответствовать во всех исполнителях и драйвере. В противном случае это может привести к сбоям или неверным ответам. Для версий Python ниже 3.6 имена полей сортируются только в алфавитном порядке.
  • Нерекомендуемая поддержка Python 2 (Spark-27884).

Структурированная потоковая передача

  • В Spark 3.0 структурированный поток позволяет принудительно допустить значение NULL в исходной схеме при использовании таких файловых источников данных, как text, json, csv, parquet и orc, с помощью spark.readStream(...). Прежде соблюдалось допустимость значений NULL в исходной схеме. Однако это привело к проблемам при отладке с помощью NPE. Чтобы восстановить прежнее поведение, присвойте параметру spark.sql.streaming.fileSource.schema.forceNullable значение false.
  • Spark 3.0 устраняет проблему с точностью во внешнем соединении поток-поток, что изменяет схему состояния. Дополнительные сведения см. в статье SPARK-26154. При запуске запроса из контрольной точки, созданной из Spark 2.x, которая использует внешнее соединение поток-поток, Spark 3.0 отменяет запрос. Чтобы повторно вычислить выходные данные, отклонить контрольную точку и воспроизвести предыдущие входные данные.
  • В Spark 3.0 был удален устаревший класс org.apache.spark.sql.streaming.ProcessingTime. Вместо этого используйте org.apache.spark.sql.streaming.Trigger.ProcessingTime. Аналогично, org.apache.spark.sql.execution.streaming.continuous.ContinuousTrigger был удален и заменен на Trigger.Continuous, а org.apache.spark.sql.execution.streaming.OneTimeTrigger был скрыт и заменен на Trigger.Once. См. раздел Spark-28199.

SQL, наборы данных и DataFrame

  • В Spark 3.0 при вставке значения в столбец таблицы с другим типом данных приведение типов выполняется в соответствии со стандартом SQL ANSI. Некоторые недопустимые преобразования типов, такие как преобразование из string в int и из double в boolean, запрещены. Если значение выходит за пределы допустимого диапазона для типа данных столбца, будет сгенерировано исключение среды выполнения. В Spark версии 2.4 и более ранних версиях разрешены преобразования типов во время вставки таблицы, если преобразования являются допустимыми Cast. При вставке значения, выходящего за пределы диапазона, в целочисленное поле вставляются младшие биты значения (как и в приведении числовых типов Java/Scala). Например, если число 257 вставляется в поле типа byte, результатом будет 1. Поведение управляется параметром spark.sql.storeAssignmentPolicy со значением по умолчанию "ANSI". Если задать для параметра значение "Legacy" (Устаревший), то будет восстановлено предыдущее поведение.
  • В Spark 3.0 в процессе приведения строкового значения к целочисленным типам (tinyint, smallint, int и bigint), типам DateTime (дата, метка времени и интервал) и логическому типу, ведущие и замыкающие пробелы (< = ACSII 32) удаляются перед преобразованием в эти значения типа, например cast(' 1\t' as int) возвращает 1, cast(' 1\t' as boolean) возвращает true, cast('2019-10-10\t as date) возвращает значение даты 2019-10-10. В Spark версии 2.4 и более ранних версиях в процессе приведения строки к целому и логическому типу, пробелы в начале и в конце удаляться не будут, предыдущие результаты будут иметь значение null, а для типов datetime будут удаляться только конечные пробелы (= ASCII 32). См. раздел https://databricks.com/blog/2020/07/22/a-comprehensive-look-at-dates-and-timestamps-in-apache-spark-3-0.html.
  • В Spark 3.0 устаревшие методы SQLContext.createExternalTable и SparkSession.createExternalTable были удалены и заменены на createTable.
  • В Spark 3.0 конфигурация spark.sql.crossJoin.enabled становится внутренней, и по умолчанию имеет значение true, поэтому по умолчанию Spark не генерирует исключение для SQL с неявными перекрестными соединениями.
  • В Spark 3.0 мы поменяли местами аргументы в функции trim с TRIM(trimStr, str) на TRIM(str, trimStr) в для совместимости с другими базами данных.
  • В Spark версии 2.4 и более ранних версиях запросы SQL, такие как FROM <table> или FROM <table> UNION ALL FROM <table> поддерживаются случайным образом. В стиле hive FROM <table> SELECT <expr> предложение SELECT не является незначительным. Этот синтаксис не поддерживается ни Hive, ни Presto. Поэтому эти запросы будут рассматриваться как недопустимые с момента выпуска Spark 3.0.
  • С момента выпуска Spark 3.0, unionAll API набора данных и API DataFrame больше не являются устаревшими. Это псевдоним для union.
  • В Spark версии 2.4 и более ранних версиях, средство синтаксического анализа источника данных JSON обрабатывает пустые строки как значения NULL для некоторых типов данных, таких как IntegerType. Для FloatType и DoubleType это приводит к возникновению ошибки при пустой строке и возникают исключения. Начиная с Spark 3.0, запрещены пустые строки, будут генерироваться исключения для типов данных, кроме StringType и BinaryType.
  • Начиная с Spark 3.0, функции from_json поддерживают два режима: PERMISSIVE и FAILFAST. Эти режимы можно задать с помощью параметра mode. Режимом по умолчанию стал PERMISSIVE. В предыдущих версиях поведение from_json не соответствует ни PERMISSIVE, ни FAILFAST,, особенно, при обработке неправильных записей JSON. Например, строка JSON {"a" 1} со схемой a INT преобразуется в null с помощью предыдущей версии, но Spark 3.0 преобразует ее в Row(null).

Инструкции DDL

  • В Spark 3.0 CREATE TABLE без конкретного поставщика в качестве поставщика используется значение spark.sql.sources.default. В Spark версии 2.4 и более ранних версиях это был Hive. Задайте для параметра spark.sql.legacy.createHiveTableByDefault.enabled значение true, чтобы восстановить поведение, действовавшее до Spark 3.0.
  • В Spark 3.0 при вставке значения в столбец таблицы с другим типом данных приведение типов выполняется в соответствии со стандартом SQL ANSI. Некоторые недопустимые преобразования типов, такие как преобразование из string в int и из double в boolean, запрещены. Если значение выходит за пределы допустимого диапазона для типа данных столбца, будет сгенерировано исключение среды выполнения. В Spark версии 2.4 и более ранних версиях преобразования типов во время вставки в таблицу разрешено, если преобразования являются допустимыми Cast. При вставке значения, выходящего за пределы диапазона, в целочисленное поле вставляются младшие биты значения (как и в приведении числовых типов Java/Scala). Например, если число 257 вставляется в поле типа byte, результатом будет 1. Поведение управляется параметром spark.sql.storeAssignmentPolicy со значением по умолчанию "ANSI". Если задать для параметра значение "Legacy" (Устаревший), то будет восстановлено предыдущее поведение.
  • В Spark 3.0 SHOW CREATE TABLE всегда возвращает Spark DDL, даже если данная таблица является таблицей Hive SerDe. Для создания Hive DDL используйте команду SHOW CREATE TABLE AS SERDE.
  • В Spark 3.0 столбец типа CHAR не допускается в таблицах не-Hive-Serde, а команды CREATE/ALTER TABLE завершатся ошибкой, если тип CHAR обнаружен. Используйте вместо него тип STRING. В Spark версии 2.4 и ниже тип CHAR обрабатывается как тип STRING, а параметр длины просто игнорируется.

UDF и встроенные функции

  • В Spark 3.0 использование org.apache.spark.sql.functions.udf(AnyRef, DataType) не разрешено по умолчанию. Задайте для spark.sql.legacy.allowUntypedScalaUDF значение true, чтобы продолжать использовать его. В Spark версии 2.4 и ниже, если org.apache.spark.sql.functions.udf(AnyRef, DataType) возвращает замыкание Scala с аргументом-примитивом, возвращаемая UDF возвращает значение NULL, если входные значения равны NULL. Однако в Spark 3.0 функция UDF возвращает значение типа Java по умолчанию, если входное значение равно NULL. Например, val f = udf((x: Int) => x, IntegerType), f($"x") возвращает значение NULL в Spark 2.4 и ниже, если столбец x имеет значение NULL, и возвращает 0 в Spark 3.0. Это изменение поведения введено потому, что Spark 3.0 собрана вместе с Scala 2.12 по умолчанию.
  • В Spark версии 2.4 и ниже можно создать сопоставление с повторяющимися ключами с помощью встроенных функций, таких как CreateMap, StringToMap и т. д. Поведение сопоставления с повторяющимися ключами не определено, например, если поиск сопоставления учитывает дубликат ключа, то в первую очередь будет сохраняться только повторяющийся ключ Dataset.collect, MapKeys возвращает повторяющиеся ключи и т. д. В Spark 3.0 при обнаружении повторяющихся ключей создается исключение RuntimeException Spark. Можно задать для параметра spark.sql.mapKeyDedupPolicy значение LAST_WIN, чтобы удалить повторяющиеся ключи сопоставления с последней политикой WINS. Пользователи по-прежнему могут считывать значения сопоставления с повторяющимися ключами из источников данных, которые не применяют его принудительно (например, Parquet), поэтому поведение не определено.

Источники данных

  • В Spark версии 2.4 и ниже значение столбца раздела преобразуется в NULL, если его невозможно привести к соответствующей схеме, указанной пользователем. В 3.0 значение столбца раздела проверяется с помощью схемы, указанной пользователем. Если проверка завершается с ошибкой, генерируется исключение. Такую проверку можно отключить, задав для параметра spark.sql.sources.validatePartitionColumns значение false.
  • В Spark версии 2.4 и более ранних версиях, средство синтаксического анализа источника данных JSON обрабатывает пустые строки как значения NULL для некоторых типов данных, таких как IntegerType. Для FloatType, DoubleType, DateType и TimestampType это приводит к возникновению ошибки при пустой строке и появлению исключения. Spark 3.0 запрещает пустые строки и генерирует исключение для типов данных, кроме StringType и BinaryType. Предыдущее поведение разрешения пустой строки можно восстановить, задав для параметра spark.sql.legacy.json.allowEmptyString.enabled значение true.
  • В Spark 3.0, если файлы или подкаталоги исчезают во время рекурсивного формирования списка каталогов (то есть они появляются в промежуточном списке, но не могут быть прочитаны или перечислены на последующих этапах рекурсивного формирования списка каталогов из-за одновременного удаления файлов или проблем согласованности хранилища объектов), формирование списка завершится ошибкой с исключением, пока для параметра spark.sql.files.ignoreMissingFiles не установлено значение true (по умолчанию false). В предыдущих версиях эти отсутствующие файлы или подкаталоги будут пропущены. Обратите внимание, что это изменение поведения применяется только во время первоначального формирования списка файлов таблицы (или во время REFRESH TABLE), а не во время выполнения запроса: это изменение spark.sql.files.ignoreMissingFiles теперь используется при формировании списка файлов таблицы и планирования запроса, а не только при выполнении запроса.
  • В Spark версии 2.4 и более ранних версиях источник данных CSV преобразует неправильно сформированную строку CSV в строку со всеми значениями NULL в режиме PERMISSIVE (разрешение). В Spark 3.0 возвращаемая строка может содержать поля, отличные от NULL, если некоторые из значений столбцов CSV были проанализированы и успешно преобразованы в нужные типы.
  • В Spark 3.0 по умолчанию используется логический тип Parquet TIMESTAMP_MICROS при сохранении столбцов TIMESTAMP. В Spark версии 2.4 и ниже столбцы TIMESTAMP сохраняются в виде INT96 в файлах Parquet. Обратите внимание, что некоторые системы SQL, такие как Hive 1.x и Impala 2.x, могут считывать только метки времени INT96. Можно задать spark.sql.parquet.outputTimestampType в качестве значения INT96, чтобы восстановить предыдущее поведение и обеспечить взаимодействие.
  • В Spark 3.0, если файлы Avro записываются с помощью предоставленной пользователем схемы, поля сопоставляются по именам полей между схемой Catalyst и схемой Avro вместо позиций.

Подсистема запросов

  • В Spark 3.0 запрос набора данных завершается с ошибкой, если содержит неоднозначную ссылку на столбец, вызванную самосоединением. Типичный пример: val df1 = ...; val df2 = df1.filter(...);, then df1.join(df2, df1("a") > df2("a")) возвращает пустой результат, что сбивает с толку. Это обусловлено тем, что Spark не может разрешить ссылки на столбцы набора данных, указывающие на самосоединяемые таблицы, и df1("a") точно совпадает с df2("a") в Spark. Задайте для параметра spark.sql.analyzer.failAmbiguousSelfJoin значение false, чтобы восстановить поведение, действовавшее до Spark 3.0.
  • В Spark 3.0 числа, написанные в экспоненциальном представлении (например, 1E2), анализируются как Double. В Spark версии 2.4 и ниже они анализируются как Decimal. Чтобы восстановить поведение до Spark 3,0, можно задать для параметра spark.sql.legacy.exponentLiteralAsDecimal.enabled значение true.
  • В Spark 3.0 конфигурация spark.sql.crossJoin.enabled становится внутренней конфигурацией и по умолчанию имеет значение true. По умолчанию Spark не создает исключения в SQL с неявными перекрестными соединяемыми.
  • В Spark версии 2.4 и ниже значение типа float/Double -0,0 семантически равно 0,0, но -0,0 и 0,0 считаются разными значениями при использовании в агрегатных ключах группирования, ключах разделов окон и ключах соединений. В Spark 3.0 эта ошибка исправлена. Например, Seq(-0.0, 0.0).toDF("d").groupBy("d").count() возвращает [(0.0, 2)] в Spark 3.0 и [(0.0, 1), (-0.0, 1)] в Spark 2.4 и ниже.
  • В Spark 3.0 литералы TIMESTAMP преобразуются в строки с помощью конфигурации SQL spark.sql.session.timeZone. В Spark версии 2.4 и ниже в процессе преобразования используется часовой пояс по умолчанию для виртуальной машины Java.
  • В Spark 3.0 Spark выполняет приведение типов String к Date/Timestamp в двоичных сравнениях с датами и метками времени. Предыдущее поведение приведения типов Date/Timestamp к String можно восстановить, задав для параметра spark.sql.legacy.typeCoercion.datetimeToString.enabled значение true.
  • В Spark версии 2.4 и ниже недопустимые идентификаторы часовых поясов игнорируются и заменяются часовым поясом GMT, например в функции from_utc_timestamp. В Spark 3.0 такие идентификаторы часовых поясов отклоняются, а Spark создает исключение java.time.DateTimeException.
  • В Spark 3.0 используется предваряющий григорианский календарь для анализа, форматирования и преобразования дат и меток времени, а также для извлечения подкомпонентов, таких как годы, дни и т. д. Spark 3.0 использует классы API Java 8 из пакетов java.time, основанных на хронологии ISO. В Spark версии 2.4 и ниже эти операции выполняются с помощью гибридного календаря (юлианский + григорианский). Изменения влияют на результаты дат до 15 октября 1582 г. (григориан) и влияют на следующий API Spark 3.0:
    • Синтаксический анализ и форматирование строк даты и времени. Это влияет на источники данных CSV/JSON и на функции unix_timestamp, date_format, to_unix_timestamp, from_unixtime, to_date, to_timestamp, когда шаблоны, заданные пользователями, используются для синтаксического анализа и форматирования. В Spark 3.0 мы определяем собственные строки шаблона в sql-ref-datetime-pattern.md, которые реализуются с помощью java.time.format.DateTimeFormatter. Новая реализация выполняет строгую проверку входных данных. Например, метка времени 2015-07-22 10:00:00 не может быть проанализирована, если шаблон имеет значение yyyy-MM-dd, поскольку средство синтаксического анализа не использует все входные данные. Другой пример: входные данные 31/01/2015 00:00 не могут быть проанализированы с помощью шаблона dd/MM/yyyy hh:mm, так как hh предполагает значения часов в диапазоне 1-12. В Spark версии 2.4 и более ранних версиях java.text.SimpleDateFormat используется для преобразования строк меток времени и дат, а поддерживаемые шаблоны описываются в формате simpleDateFormat. Предыдущее поведение можно восстановить, задав для параметра spark.sql.legacy.timeParserPolicy значение LEGACY.
    • Функции weekofyear, weekday, dayofweek, date_trunc, from_utc_timestamp, to_utc_timestamp и unix_timestamp используют API java.time для вычисления номера недели года, номера дня недели, а также для преобразования в/из значений типа TimestampType в часовой пояс UTC.
    • Параметры JDBC lowerBound и upperBound преобразуются в значения типа Timestamp/Date тем же способом, что и приведение строк к типам Timestamp/Date. В процессе преобразования используется предваряющий григорианский календарь и часовой пояс, определяемый конфигурацией SQL spark.sql.session.timeZone. В Spark версии 2.4 и ниже в преобразовании используется гибридный календарь (юлианский + григорианский) и системный часовой пояс умолчанию.
    • Форматирование литералов TIMESTAMP и DATE.
    • Создание типизированных литералов TIMESTAMP и DATE из строк. В Spark 3.0 преобразование строк в типизированные литералы TIMESTAMP/DATE осуществляется с помощью приведения к значениям TIMESTAMP/DATE. Например, TIMESTAMP '2019-12-23 12:59:30' семантически равно CAST('2019-12-23 12:59:30' AS TIMESTAMP). Если строка исходных данных не содержит сведений о часовом поясе, в этом случае используется часовой пояс из конфигурации spark.sql.session.timeZone SQL. В Spark версии 2.4 и ниже в преобразовании используется системный часовой пояс виртуальной машины Java. Различные источники часового пояса по умолчанию могут изменить поведение типизированных литералов TIMESTAMP и DATE.

Apache Hive

  • В Spark 3.0 мы обновили встроенную версию Hive с версии 1.2 до 2.3, что приводит к следующим последствиям:
    • Может потребоваться установить spark.sql.hive.metastore.version и spark.sql.hive.metastore.jars в соответствии с версией хранилища метаданных Hive, к которой необходимо подключиться. Например: задайте для параметра spark.sql.hive.metastore.version значение 1.2.1 и для параметра spark.sql.hive.metastore.jars значение maven, если ваша версия хранилища метаданных Hive — 1.2.1.
    • Необходимо мигрировать пользовательский SerDes на Hive 2.3 или собрать собственный Spark с профилем hive-1.2. Дополнительные сведения см. в статье HIVE-15167.
    • Представление десятичной строки может отличаться между Hive 1.2 и Hive 2.3 при использовании оператора TRANSFORM в SQL для преобразования скрипта, которое зависит от поведения Hive. В Hive 1.2 в представлении строки пропущены нули в конце. Но в Hive 2.3 при необходимости она всегда дополняется 18 цифрами с нулями в конце.
    • В Databricks Runtime 7.x при чтении таблицы Hive SerDe по умолчанию Spark запрещает чтение файлов в подкаталоге, который не является разделом таблицы. Чтобы включить его, установите конфигурацию spark.databricks.io.hive.scanNonpartitionedDirectory.enabled в значение true. Это не влияет на собственные средства чтения таблиц и средства чтения файлов.

MLlib

  • OneHotEncoder, который является устаревшим в 2.3, удаляется в 3.0 и OneHotEncoderEstimator теперь переименовывается в OneHotEncoder.
  • org.apache.spark.ml.image.ImageSchema.readImages, который является устаревшим в 2.3, удаляется в 3.0. Вместо этого используйте spark.read.format('image').
  • org.apache.spark.mllib.clustering.KMeans.train с параметром int runs, который является устаревшим в 2.1, удаляется в 3.0. Вместо этого используйте метод обучения без процессов выполнения.
  • org.apache.spark.mllib.classification.LogisticRegressionWithSGD, который является устаревшим в 2.0, удаляется в 3.0, используйте org.apache.spark.ml.classification.LogisticRegression или spark.mllib.classification.LogisticRegressionWithLBFGS.
  • org.apache.spark.mllib.feature.ChiSqSelectorModel.isSorted, который является устаревшим в 2.1, удаляется в 3.0, не предназначен для использования подклассов.
  • org.apache.spark.mllib.regression.RidgeRegressionWithSGD, который является устаревшим в 2.0, удаляется в 3.0. Используйте org.apache.spark.ml.regression.LinearRegression с elasticNetParam = 0.0. Обратите внимание, что значение по умолчанию regParam — 0,01 для RidgeRegressionWithSGD, 0,0 для LinearRegression.
  • org.apache.spark.mllib.regression.LassoWithSGD, который является устаревшим в 2.0, удаляется в 3.0. Используйте org.apache.spark.ml.regression.LinearRegression с elasticNetParam = 1.0. Обратите внимание, что значение по умолчанию regParam — 0,01 для LassoWithSGD, 0,0 для LinearRegression.
  • org.apache.spark.mllib.regression.LinearRegressionWithSGD, который является устаревшим в 2.0, удаляется в 3.0. Вместо этого используются типы org.apache.spark.ml.regression.LinearRegression или LBFGS.
  • org.apache.spark.mllib.clustering.KMeans.getRuns и setRuns, которые являются устаревшими в 2.1, удаляются в 3.0 и не оказывают влияния с версии Spark 2.0.0.
  • org.apache.spark.ml.LinearSVCModel.setWeightCol, который является устаревшим в 2.4, удаляется в 3.0, не предназначен для пользователей.
  • В 3.0 org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel расширяется MultilayerPerceptronParams для предоставления обучающих параметров. В результате layers в MultilayerPerceptronClassificationModel было изменено с Array[Int] на IntArrayParam. Для получения размера слоев следует использовать MultilayerPerceptronClassificationModel.getLayers вместо MultilayerPerceptronClassificationModel.layers.
  • org.apache.spark.ml.classification.GBTClassifier.numTrees, который является устаревшим в 2.4.5, удаляется в 3.0. Вместо этого используйте getNumTrees.
  • org.apache.spark.ml.clustering.KMeansModel.computeCost, который является устаревшим в 2.4, удаляется в 3.0, вместо него используйте ClusteringEvaluator.
  • Точность переменной члена в org.apache.spark.mllib.evaluation.MulticlassMetrics, который является устаревшим в 2.0, удаляется в 3.0. Вместо этого используйте точность.
  • Полнота переменной члена в org.apache.spark.mllib.evaluation.MulticlassMetrics, который является устаревшим в 2.0, удаляется в 3.0. Вместо этого используйте accuracy.
  • Переменная члена fMeasure в org.apache.spark.mllib.evaluation.MulticlassMetrics, который является устаревшим в 2.0, удаляется в 3.0. Вместо этого используйте accuracy.
  • org.apache.spark.ml.util.GeneralMLWriter.context, который является устаревшим в 2.0, удаляется в 3.0. Вместо этого используйте session.
  • org.apache.spark.ml.util.MLWriter.context, который является устаревшим в 2.0, удаляется в 3.0. Вместо этого используйте session.
  • org.apache.spark.ml.util.MLReader.context, который является устаревшим в 2.0, удаляется в 3.0. Вместо этого используйте session.
  • abstract class UnaryTransformer[IN, OUT, T <: UnaryTransformer[IN, OUT, T]] изменяется на abstract class UnaryTransformer[IN: TypeTag, OUT: TypeTag, T <: UnaryTransformer[IN, OUT, T]] в 3.0.
  • В Spark 3.0 логистическая регрессия по нескольким классам в Pyspark теперь будет правильно возвращать LogisticRegressionSummary, а не подкласс BinaryLogisticRegressionSummary. В данном случае дополнительные методы, предоставляемые с помощью BinaryLogisticRegressionSummary, не будут работать (SPARK-31681).
  • В Spark 3.0 pyspark.ml.param.shared.Has* примеси больше не предоставляют методы задания set*(self, value), используйте вместо них соответствующий метод self.set(self.*, value). Дополнительные сведения см. в статье SPARK-29093 (SPARK-29093).

Другие изменения в поведении

  • Обновление до Scala 2.12 включает в себя следующие изменения:

    • Сериализация ячейки пакета обрабатывается по-разному. В следующем примере показано изменение в поведении и способ его решения.

      При выполнении foo.bar.MyObjectInPackageCell.run(), как определено в следующей ячейке пакета, приведет к ошибке java.lang.NoClassDefFoundError: Could not initialize class foo.bar.MyObjectInPackageCell$

      package foo.bar
      
      case class MyIntStruct(int: Int)
      
      import org.apache.spark.sql.SparkSession
      import org.apache.spark.sql.functions._
      import org.apache.spark.sql.Column
      
      object MyObjectInPackageCell extends Serializable {
      
        // Because SparkSession cannot be created in Spark executors,
        // the following line triggers the error
        // Could not initialize class foo.bar.MyObjectInPackageCell$
        val spark = SparkSession.builder.getOrCreate()
      
        def foo: Int => Option[MyIntStruct] = (x: Int) => Some(MyIntStruct(100))
      
        val theUDF = udf(foo)
      
        val df = {
          val myUDFInstance = theUDF(col("id"))
          spark.range(0, 1, 1, 1).withColumn("u", myUDFInstance)
        }
      
        def run(): Unit = {
          df.collect().foreach(println)
        }
      }
      

      Чтобы обойти эту ошибку, можно выполнить перенос MyObjectInPackageCell внутри сериализуемого класса.

    • В некоторых случаях с помощью DataStreamWriter.foreachBatch потребуется обновление исходного кода. Это изменение обусловлено тем, что Scala 2.12 имеет автоматическое преобразование из лямбда-выражений в типы SAM и может привести к неоднозначности.

      Например, не удается скомпилировать следующий код Scala:

      streams
        .writeStream
        .foreachBatch { (df, id) => myFunc(df, id) }
      

      Чтобы устранить ошибку компиляции, измените foreachBatch { (df, id) => myFunc(df, id) } на foreachBatch(myFunc _) или явно используйте API Java: foreachBatch(new VoidFunction2 ...).

  • Так как версия Apache Hive, используемая для обработки определяемых пользователем функций Hive и SerDes Hive, обновлена до 2.3, требуются два изменения:

    • Интерфейс SerDe Hive заменен абстрактным классом AbstractSerDe. Для любой реализации пользовательского Hive SerDe требуется миграция в AbstractSerDe.
    • Установка для параметра spark.sql.hive.metastore.jars значения builtin означает, что клиент хранилища метаданных Hive 2.3 будет использоваться для доступа к хранилищам метаданных для Databricks Runtime 7.x. Если необходимо получить доступ к внешним хранилищам метаданных на базе Hive 1.2, укажите для spark.sql.hive.metastore.jars папку, содержащую JAR-файл Hive 1.2.

Устаревшие и удаленные возможности

  • Индекс пропуска данных был устаревшим в Databricks Runtime 4.3 и удален в Databricks Runtime 7.x. Вместо этого рекомендуется использовать разностные таблицы, обеспечивающие улучшенные возможности для пропуска данных.
  • В Databricks Runtime 7.x базовая версия Apache Spark использует Scala 2.12. Поскольку библиотеки, скомпилированные для Scala 2.11, могут внезапно отключить кластеры Databricks Runtime 7.x, кластеры, работающие с Databricks Runtime 7.x, не устанавливают библиотеки, настроенные для установки на всех кластерах. На вкладке Библиотеки кластера отображается состояние Skipped и сообщение об устаревании, в котором объясняются изменения в обработке библиотеки. Однако при наличии кластера, созданного в более ранней версии Databricks Runtime до выпуска платформы Azure Databricks версии 3.20 в рабочей области, теперь можно изменить этот кластер для использования Databricks Runtime 7.x, все библиотеки, которые были настроены для установки на всех кластерах, будут установлены в этом кластере. В этом случае любой несовместимый JAR-файл в установленных библиотеках может привести к отключению кластера. Для решения этой проблемы кластер можно клонировать или создать новый.

Известные проблемы

  • При анализе дня года с использованием шаблона символ D возвращает неверный результат, если поле года отсутствует. Это может произойти в функциях SQL, таких как to_timestamp, в которых преобразуется строка типа datetime в значения типа datetime с помощью строки шаблона (SPARK-31939).
  • Соединение/окно/статистическое выражение внутри вложенных запросов могут привести к неверным результатам, если ключи имеют значения -0,0 и 0,0 (SPARK-31958).
  • Запрос окна может завершиться аварийно с неоднозначной ошибкой самосоединения (SPARK-31956).
  • Потоковые запросы с оператором dropDuplicates не могут быть перезапущены с помощью контрольной точки, записанной Spark 2.x (SPARK-31990)