Guía de migración de Databricks Runtime 7.x (sin soporte técnico)

En esta guía se proporcionan instrucciones para ayudarle a migrar las cargas de trabajo de Azure Databricks desde Databricks Runtime 6.x, basado en Apache Spark 2.4, a Databricks Runtime 7.3 LTS (sin soporte técnico), ambas creadas en Spark 3.0.

En esta guía se enumeran los cambios de comportamiento de Spark 3.0 que pueden requerir que se actualice a las cargas de trabajo de Azure Databricks. Algunos de esos cambios incluyen la eliminación completa de la compatibilidad con Python 2, la actualización a Scala 2.12, la compatibilidad completa con JDK 11 y el cambio del calendario gregoriano al calendario proléctico para fechas y marcas de tiempo.

Esta guía es un complemento de la guía de migración de Databricks Runtime 7.3 LTS (sin soporte técnico).

Para obtener información sobre la migración entre versiones de Databricks Runtime, consulte la guía de migración de Databricks Runtime.

Nuevas características y mejoras disponibles en Databricks Runtime 7.x

Para obtener una lista de las nuevas características, mejoras y actualizaciones de biblioteca incluidas en Databricks Runtime 7.3 LTS, consulte las notas de la versión de cada versión de Databricks Runtime superior a la que va a migrar. Las versiones admitidas de Databricks Runtime 7.x incluyen:

Las actualizaciones de mantenimiento posteriores a la publicación se enumeran en Actualizaciones de mantenimiento para Databricks Runtime (archivado).

Entorno del sistema de Databricks Runtime 7.3 LTS

  • Sistema operativo: Ubuntu 18.04.5 LTS
  • Java:
    • 7.3 LTS: Zulu 8.48.0.53-CA-linux64 (compilación 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

Principales cambios de comportamiento en Apache Spark 3.0

Los siguientes cambios de comportamiento de Spark 2.4 a Spark 3.0 pueden requerir que actualice las cargas de trabajo de Azure Databricks al migrar de Databricks Runtime 6.x a Databricks Runtime 7.x.

Nota:

En este artículo se proporciona una lista de los cambios de comportamiento importantes de Spark que debe tener en cuenta al migrar a Databricks Runtime 7.x. Para obtener una lista completa de los cambios de comportamiento, consulte la guía de migración de Spark 3.0.1.

Core

  • En Spark 3.0 se quita el acumulador v1 en desuso.
  • El archivo de registro de eventos se escribirá como con codificación UTF-8 y el servidor de historial de Spark reproducirá los archivos de registro de eventos como con codificación UTF-8. Anteriormente Spark escribía el archivo de registro de eventos como con el juego de caracteres predeterminado del proceso de JVM del controlador, por lo que se necesita el servidor de historial de Spark de Spark 2.x para leer los archivos de registro de eventos antiguos en caso de que la codificación no sea compatible.
  • Se usa un nuevo protocolo para capturar bloques aleatorios. Se recomienda actualizar los servicios aleatorios externos al ejecutar aplicaciones de Spark 3.0. Puede seguir utilizando servicios aleatorios externos antiguos estableciendo la configuración de spark.shuffle.useOldFetchProtocol en true. De lo contrario, Spark puede encontrar errores con mensajes como IllegalArgumentException: Unexpected message type: <number>.

PySpark

  • En Spark 3.0, Column.getItem se ha corregido de forma que no llama a Column.apply. Por lo tanto, si se usa Column como argumento para getItem, se debe usar el operador de indexación. Por ejemplo, map_col.getItem(col('id')) se debe reemplazar por map_col[col('id')].
  • A partir de Spark 3.0, los nombres del campo Row ya no se ordenan alfabéticamente al construir con argumentos con nombre para las versiones de Python 3.6 y posteriores, y el orden de los campos coincidirá con el especificado. Para habilitar los campos ordenados de forma predeterminada, como en Spark 2.4, establezca la variable de entorno PYSPARK_ROW_FIELD_SORTING_ENABLED en true para los ejecutores y el controlador. Esta variable de entorno debe ser coherente en todos los ejecutores y el controlador. De lo contrario, podrían producirse errores o respuestas incorrectas. Para las versiones de Python inferiores a 3.6, los nombres de campo se ordenan alfabéticamente como única opción.
  • Compatibilidad con Python 2 en desuso (SPARK-27884).

Structured Streaming

  • En Spark 3.0, Structured Streaming fuerza el esquema de origen para que acepte valores NULL cuando se usan orígenes de datos basados en archivos como text, json, csv, parquet y orc a través de spark.readStream(...). Anteriormente, respetaba la nulabilidad en el esquema de origen, pero provocaba problemas complicados de depurar con NPE. Para restaurar el comportamiento anterior, establezca spark.sql.streaming.fileSource.schema.forceNullable en false.
  • Spark 3.0 corrige el problema de corrección en la combinación externa de streaming con streaming, con lo que se cambia el esquema de estado. Consulte SPARK-26154 para obtener más detalles. Si inicia la consulta desde un punto de control construido a partir de Spark 2.x que usa la combinación externa de streaming con streaming, Spark 3.0 produce un error en la consulta. Para volver a calcular las salidas, descarte el punto de control y reproduzca las entradas anteriores.
  • En Spark 3.0 se ha eliminado la clase org.apache.spark.sql.streaming.ProcessingTime en desuso. En su lugar, use org.apache.spark.sql.streaming.Trigger.ProcessingTime. Del mismo modo, se ha eliminado org.apache.spark.sql.execution.streaming.continuous.ContinuousTrigger en favor de Trigger.Continuous, y org.apache.spark.sql.execution.streaming.OneTimeTrigger se ha ocultado en favor de Trigger.Once. Consulte SPARK-28199.

SQL, conjuntos de datos y DataFrame

  • En Spark 3.0, al insertar un valor en una columna de tabla con otro tipo de datos, la coerción de tipo se realiza según ANSI SQL estándar. No se permite realizar determinadas conversiones de tipo no razonables, como convertir string a int y double a boolean. Se producirá una excepción en tiempo de ejecución si el valor está fuera del intervalo para el tipo de datos de la columna. En Spark 2.4 y versiones anteriores, las conversiones de tipo durante la inserción de tablas se permiten siempre que sean un valor de Cast válido. Al insertar un valor fuera del intervalo en un campo de entero, se insertan los bits de orden inferior del valor (lo mismo que la conversión de tipo numérico de Java/Scala). Por ejemplo, si se inserta 257 en un campo de tipo byte, el resultado es 1. El comportamiento se controla mediante la opción spark.sql.storeAssignmentPolicy, con un valor predeterminado de "ANSI". Al establecer la opción en "heredado", se restaura el comportamiento anterior.
  • En Spark 3.0, al convertir el valor de cadena a tipos enteros (tinyint, smallint, int y bigint), tipos de fecha y hora (date, timestamp e interval) y tipo booleano, los espacios en blanco iniciales y finales (<= ACSII 32) se recortan antes de convertirse a estos valores de tipo; por ejemplo, cast(' 1\t' as int) devuelve 1, cast(' 1\t' as boolean) devuelve true y cast('2019-10-10\t as date)devuelve el valor de fecha2019-10-10. En Spark 2.4 y versiones anteriores, al convertir de cadenas a enteros y booleanos, no se recortarán los espacios en blanco de ambos extremos, los resultados anteriores serán null, mientras que al convertir a fecha y hora solo se quitarán los espacios finales (= ASCII 32). Vea https://databricks.com/blog/2020/07/22/a-comprehensive-look-at-dates-and-timestamps-in-apache-spark-3-0.html.
  • En Spark 3.0, los métodos en desuso SQLContext.createExternalTable y SparkSession.createExternalTable se han eliminado en favor de su reemplazo, createTable.
  • En Spark 3.0, la configuración spark.sql.crossJoin.enabled se convierte en configuración interna y es true de forma predeterminada, por lo que Spark no producirá una excepción en SQL con combinaciones cruzadas implícitas de forma predeterminada.
  • En Spark 3.0, hemos invertido el orden de argumentos de la función de recorte de TRIM(trimStr, str) a TRIM(str, trimStr) para que sea compatible con otras bases de datos.
  • En Spark 2.4 y versiones anteriores, las consultas SQL como FROM <table> o FROM <table> UNION ALL FROM <table> son compatibles por accidente. En FROM <table> SELECT <expr> de estilo Hive, la cláusula SELECT no es insignificante. Ni Hive ni Presto admiten esta sintaxis. Por lo tanto, a partir de Spark 3.0 se tratarán estas consultas como no válidas.
  • A partir de Spark 3.0, la API de conjunto de datos y DataFrame unionAll ya no está en desuso. Es un alias de union.
  • En Spark 2.4 y versiones anteriores, el analizador del origen de datos JSON trata las cadenas vacías como NULL para algunos tipos de datos, como IntegerType. Para FloatType y DoubleType, se produce un error en las cadenas vacías y se producen excepciones. A partir de Spark 3.0, no se permiten cadenas vacías y se producirán excepciones para los tipos de datos, excepto para StringType y BinaryType.
  • A partir de Spark 3.0, las funciones from_json admiten dos modos: PERMISSIVE y FAILFAST. Los modos se pueden configurar mediante la opción mode. El modo predeterminado ha pasado a ser PERMISSIVE. En versiones anteriores, el comportamiento de from_json no se ajustaba a PERMISSIVE ni a FAILFAST,, especialmente al procesar registros JSON con formato incorrecto. Por ejemplo, en versiones anteriores, la cadena JSON {"a" 1} con el esquema a INT se convierte a null, pero Spark 3.0 la convierte a Row(null).

Instrucciones DDL

  • En Spark 3.0, CREATE TABLE sin un proveedor específico usa el valor spark.sql.sources.default como proveedor. En Spark 2.4 y versiones inferiores, era Hive. Para restaurar el comportamiento anterior al de Spark 3.0, puede establecer spark.sql.legacy.createHiveTableByDefault.enabled en true.
  • En Spark 3.0, al insertar un valor en una columna de tabla con otro tipo de datos, la coerción de tipo se realiza según ANSI SQL estándar. No se permite realizar determinadas conversiones de tipo no razonables, como convertir string a int y double a boolean. Se produce una excepción en tiempo de ejecución si el valor está fuera del intervalo para el tipo de datos de la columna. En Spark 2.4 y versiones inferiores, las conversiones de tipo durante la inserción de tablas se permiten siempre que sean un valor de Cast válido. Al insertar un valor fuera del intervalo en un campo de entero, se insertan los bits de orden inferior del valor (lo mismo que la conversión de tipo numérico de Java/Scala). Por ejemplo, si se inserta 257 en un campo de tipo byte, el resultado es 1. El comportamiento se controla mediante la opción spark.sql.storeAssignmentPolicy, con un valor predeterminado de "ANSI". Al establecer la opción en "heredado", se restaura el comportamiento anterior.
  • En Spark 3.0, SHOW CREATE TABLE siempre devuelve Spark DDL, incluso cuando la tabla dada es una tabla Hive SerDe. Para generar un DDL de Hive, use el comando SHOW CREATE TABLE AS SERDE en su lugar.
  • En Spark 3.0, no se permite la columna de tipo CHAR en tablas que no son Hive SerDe, y los comandos CREATE/ALTER TABLE producirán un error si se detecta el tipo CHAR. Use el tipo STRING en su lugar. En Spark 2.4 y versiones inferiores, el tipo CHAR se trata como tipo STRING y el parámetro Length simplemente se omite.

UDF y funciones integradas

  • En Spark 3.0, no se permite el uso de org.apache.spark.sql.functions.udf(AnyRef, DataType) de forma predeterminada. Establezca spark.sql.legacy.allowUntypedScalaUDF en true para seguir usándolo. En Spark 2.4 y versiones inferiores, si org.apache.spark.sql.functions.udf(AnyRef, DataType) obtiene un cierre de Scala con un argumento de tipo primitivo, la UDF devuelta devuelve NULL si los valores de entrada son NULL. Pero en Spark 3.0, la UDF devuelve el valor predeterminado del tipo Java si el valor de entrada es NULL. Por ejemplo, val f = udf((x: Int) => x, IntegerType), f($"x") devuelve NULL en Spark 2.4 y versiones inferiores si la columna x es NULL, mientras que en Spark 3.0 devuelve 0. Se introduce este cambio de comportamiento porque Spark 3.0 se ha creado con Scala 2.12 de forma predeterminada.
  • En Spark 2.4 y versiones inferiores, puede crear un mapa con claves duplicadas a través de funciones integradas como CreateMap, StringToMap, etc. El comportamiento del mapa con claves duplicadas es indefinido; por ejemplo, la visualización del mapa respeta primero la clave duplicada, Dataset.collect solo mantiene que la clave duplicada aparece en último lugar, MapKeys devuelve claves duplicadas, etc. En Spark 3.0, Spark devuelve RuntimeException si se encuentran claves duplicadas. Puede establecer spark.sql.mapKeyDedupPolicy en LAST_WIN para desduplicar las claves de mapa con la directiva "el último gana". Los usuarios todavía pueden leer valores del mapa con claves duplicadas de orígenes de datos que no lo aplican (por ejemplo, Parquet), pero el comportamiento no se ha definido.

Orígenes de datos

  • En Spark 2.4 y versiones inferiores, el valor de la columna de partición se convierte como NULL si no se puede convertir a un esquema correspondiente proporcionado por el usuario. En la versión 3.0, el valor de la columna de partición se valida con un esquema proporcionado por el usuario. Se produce una excepción si se produce un error en la validación. Puede deshabilitar dicha validación estableciendo spark.sql.sources.validatePartitionColumns en false.
  • En Spark 2.4 y versiones inferiores, el analizador del origen de datos JSON trata las cadenas vacías como NULL para algunos tipos de datos, como IntegerType. Para FloatType, DoubleType, DateType y TimestampType se produce un error en las cadenas vacías y se producen excepciones. Spark 3.0 no permite cadenas vacías y producirá una excepción para los tipos de datos excepto para StringType y BinaryType. Se puede restaurar el comportamiento anterior de permitir una cadena vacía estableciendo spark.sql.legacy.json.allowEmptyString.enabled en true.
  • En Spark 3.0, si los archivos o subdirectorios desaparecen durante la lista recursiva de directorios (es decir, aparecen en una lista intermedia, pero luego no se pueden leer ni enumerar durante las fases posteriores de la lista recursiva de directorios debido a eliminaciones de archivos simultáneas o problemas de coherencia del almacén de objetos), se producirá un error en la lista con una excepción a menos que spark.sql.files.ignoreMissingFiles sea true (el valor predeterminado es false). En versiones anteriores, se omitían estos archivos o subdirectorios que faltaban. Tenga en cuenta que este cambio de comportamiento solo se aplica durante la lista inicial de archivos de tabla (o durante REFRESH TABLE), no durante la ejecución de consultas: el cambio neto es que ahora spark.sql.files.ignoreMissingFiles se cumple durante la lista de archivos de tabla y el planeamiento de consultas, no solo en tiempo de ejecución de las consultas.
  • En Spark 2.4 y versiones inferiores, el origen de datos CSV convierte una cadena CSV con formato incorrecto en una fila con todos los valores NULL en el modo PERMISSIVE. En Spark 3.0, la fila devuelta puede contener campos que no son NULL si algunos de los valores de columna CSV se han analizado y convertido correctamente a los tipos deseados.
  • En Spark 3.0, el tipo lógico de Parquet TIMESTAMP_MICROS se usa de forma predeterminada al guardar columnas TIMESTAMP. En Spark 2.4 y versiones inferiores, las columnas TIMESTAMP se guardan como INT96 en archivos Parquet. Tenga en cuenta que algunos sistemas SQL como Hive 1.x e Impala 2.x solo pueden leer marcas de tiempo INT96. Puede establecer spark.sql.parquet.outputTimestampType en INT96 para restaurar el comportamiento anterior y mantener la interoperabilidad.
  • En Spark 3.0, cuando los archivos Avro se escriben con el esquema proporcionado por el usuario, los campos coinciden con los nombres de campo entre el esquema de Spark y el esquema de Avro en lugar de con las posiciones.

Motor de consultas

  • En Spark 3.0, se produce un error en la consulta del conjunto de datos si contiene una referencia de columna ambigua provocada por la autocombinación. Ejemplo típico: val df1 = ...; val df2 = df1.filter(...);, then df1.join(df2, df1("a") > df2("a")) devuelve un resultado vacío que resulta bastante confuso. Esto se debe a que Spark no puede resolver las referencias de columna de conjunto de datos que apunten a tablas autocombinadas y df1("a") es exactamente igual que df2("a") en Spark. Para restaurar el comportamiento anterior al de Spark 3.0, puede establecer spark.sql.analyzer.failAmbiguousSelfJoin en false.
  • En Spark 3.0, los números escritos en la notación científica (por ejemplo, 1E2) se analizan como Double. En Spark 2.4 y versiones inferiores, se analizan como Decimal. Para restaurar el comportamiento anterior al de Spark 3.0, puede establecer spark.sql.legacy.exponentLiteralAsDecimal.enabled en true.
  • En Spark 3.0, la configuración spark.sql.crossJoin.enabled se convierte en una configuración interna y es true de forma predeterminada. De forma predeterminada, Spark no producirá excepciones en SQL con combinaciones cruzadas implícitas.
  • En Spark 2.4 y versiones inferiores, float/double -0.0 es semánticamente igual a 0.0, pero -0.0 y 0.0 se consideran valores diferentes cuando se usan en claves de agrupación agregada, claves de partición de ventana y claves de combinación. En Spark 3.0, este error se ha corregido. Por ejemplo, Seq(-0.0, 0.0).toDF("d").groupBy("d").count() devuelve [(0.0, 2)] en Spark 3.0 y [(0.0, 1), (-0.0, 1)] en Spark 2.4 y versiones inferiores.
  • En Spark 3.0, los literales TIMESTAMP se convierten en cadenas mediante la configuración de SQL spark.sql.session.timeZone. En Spark 2.4 y versiones inferiores, la conversión usa la zona horaria predeterminada de la máquina virtual Java.
  • En Spark 3.0, Spark convierte String em Date/Timestamp en comparaciones binarias con fechas y marcas de tiempo. El comportamiento anterior de la conversión de Date/Timestamp a String se puede restaurar estableciendo spark.sql.legacy.typeCoercion.datetimeToString.enabled en true.
  • En Spark 2.4 y versiones inferiores, los identificadores de zona horaria no válidos se omiten en modo silencioso y se reemplazan por la zona horaria GMT, por ejemplo, en la función from_utc_timestamp. En Spark 3.0, estos identificadores de zona horaria se rechazan y Spark devuelve java.time.DateTimeException.
  • En Spark 3.0, se usa el calendario gregoriano proléptico para analizar, dar formato y convertir las fechas y marcas de tiempo, así como para extraer subcomponentes como años, días, etc. Spark 3.0 usa las clases de la API de Java 8 de los paquetes java.time que se basan en la cronología ISO. En Spark 2.4 y posteriores inferiores, esas operaciones se realizan usando el calendario híbrido (juliano y gregoriano). Los cambios afectan a los resultados de las fechas anteriores al 15 de octubre de 1582 (gregoriano) y afectan a la siguiente API de Spark 3.0:
    • Análisis y formato de cadenas de marca de tiempo y fecha. Esto afecta a los orígenes de datos CSV/JSON y a las funciones unix_timestamp, date_format, to_unix_timestamp, from_unixtime, to_date y to_timestamp cuando se usan patrones especificados por los usuarios para el análisis y el formato. En Spark 3.0, definimos nuestras propias cadenas de patrón en sql-ref-datetime-pattern.md, que se implementa a través de java.time.format.DateTimeFormatter en segundo plano. La nueva implementación realiza una comprobación estricta de su entrada. Por ejemplo, la marca de tiempo 2015-07-22 10:00:00 no se puede analizar si el patrón es yyyy-MM-dd, porque el analizador no consume la entrada completa. Otro ejemplo es que el patrón dd/MM/yyyy hh:mm no puede analizar la entrada 31/01/2015 00:00 porque hh presupone horas en el intervalo 1 a 12. En Spark 2.4 y versiones inferiores, se usa java.text.SimpleDateFormat para las conversiones de cadenas de marca de tiempo y fecha, y los patrones admitidos se describen en simpleDateFormat. El comportamiento anterior se puede restaurar estableciendo spark.sql.legacy.timeParserPolicy en LEGACY.
    • Las funciones weekofyear, weekday, dayofweek, date_trunc, from_utc_timestamp, to_utc_timestamp y unix_timestamp usan la java.timeAPI para calcular el número de semana del año el número de día de la semana, así como para la conversión de o hacia valores TimestampType en la zona horaria UTC.
    • Las opciones de JDBC lowerBound y upperBound se convierten en valores TimestampType/DateType de la misma manera que las cadenas de conversión en valores TimestampType/DateType. La conversión se basa en el calendario gregoriano proléptico y la zona horaria definida por la configuración SQL spark.sql.session.timeZone. En Spark 2.4 y versiones inferiores, la conversión se basa en el calendario híbrido (juliano + gregoriano) y en la zona horaria predeterminada del sistema.
    • Formato de los literales TIMESTAMP y DATE.
    • Creación de literales con tipo TIMESTAMP y DATE a partir de cadenas. En Spark 3.0, la conversión de cadenas a literales con tipo TIMESTAMP/DATE se realiza mediante la conversión a valores TIMESTAMP/DATE. Por ejemplo, TIMESTAMP '2019-12-23 12:59:30' es semánticamente igual a CAST('2019-12-23 12:59:30' AS TIMESTAMP). Cuando la cadena de entrada no contiene información sobre la zona horaria, se usa la zona horaria de la configuración SQL spark.sql.session.timeZone. En Spark 2.4 y versiones inferiores, la conversión se basa en la zona horaria del sistema JVM. Los distintos orígenes de la zona horaria predeterminada pueden cambiar el comportamiento de los literales con tipo TIMESTAMP y DATE.

Apache Hive

  • En Spark 3.0, actualizamos la versión integrada de Hive de 1.2 a 2.3, lo cual afecta de la manera siguiente:
    • Es posible que tenga que establecer spark.sql.hive.metastore.version y spark.sql.hive.metastore.jars según la versión de la metastore de Hive a la que quiere conectarse. Por ejemplo: establezca spark.sql.hive.metastore.version en 1.2.1 y spark.sql.hive.metastore.jars en maven si la versión de la metastore de Hive es la 1.2.1.
    • Debe migrar los SerDe personalizados a Hive 2.3 o crear su propia instancia de Spark con el perfil hive-1.2. Consulte HIVE-15167 para obtener más detalles.
    • La representación de cadena decimal puede diferir entre Hive 1.2 y Hive 2.3 cuando se usa el operador TRANSFORM en SQL para la transformación de script, que depende del comportamiento de Hive. En Hive 1.2, la representación de cadena omite los ceros finales, pero en Hive 2.3, siempre se completa hasta 18 dígitos, añadiendo ceros finales si es necesario.
    • En Databricks Runtime 7.x, al leer una tabla SerDe de Hive, Spark no permite de forma predeterminada leer archivos en un subdirectorio que no sea una partición de tabla. Para habilitarlo, establezca la configuración spark.databricks.io.hive.scanNonpartitionedDirectory.enabled en true. Esto no afecta a los lectores de tablas nativas de Spark ni a los lectores de archivos.

MLlib

  • OneHotEncoder, que está en desuso en la versión 2.3, se ha eliminado en la versión 3.0 OneHotEncoderEstimator y ahora se ha cambiado el nombre a OneHotEncoder.
  • org.apache.spark.ml.image.ImageSchema.readImages, que está en desuso en la versión 2.3, se ha eliminado en la versión 3.0. En su lugar, use spark.read.format('image').
  • org.apache.spark.mllib.clustering.KMeans.train con el parámetro Int runs, que está en desuso en la versión 2.1, se ha eliminado en la versión 3.0. Use el método train sin ejecuciones en su lugar.
  • org.apache.spark.mllib.classification.LogisticRegressionWithSGD, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0, use org.apache.spark.ml.classification.LogisticRegressiono spark.mllib.classification.LogisticRegressionWithLBFGS en su lugar.
  • org.apache.spark.mllib.feature.ChiSqSelectorModel.isSorted, que está en desuso en la versión 2.1, se ha eliminado en la versión 3.0 y no está pensado para que las subclases lo usen.
  • org.apache.spark.mllib.regression.RidgeRegressionWithSGD, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. Use org.apache.spark.ml.regression.LinearRegression con elasticNetParam = 0.0. Tenga en cuenta que el valor predeterminado de regParam es 0,01 para RidgeRegressionWithSGD, pero es 0,0 para LinearRegression.
  • org.apache.spark.mllib.regression.LassoWithSGD, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. Use org.apache.spark.ml.regression.LinearRegression con elasticNetParam = 1.0. Tenga en cuenta que el valor predeterminado de regParam es 0,01 para LassoWithSGD, pero es 0,0 para LinearRegression.
  • org.apache.spark.mllib.regression.LinearRegressionWithSGD, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. Use org.apache.spark.ml.regression.LinearRegression o LBFGS en su lugar.
  • org.apache.spark.mllib.clustering.KMeans.getRuns y setRuns, que están en desuso en la versión 2.1, se han eliminado en la versión 3.0 y no han tenido ningún efecto desde Spark 2.0.0.
  • org.apache.spark.ml.LinearSVCModel.setWeightCol, que está en desuso en la versión 2.4, se ha eliminado en la versión 3.0 y no está pensado para que los usuarios lo usen.
  • En la versión 3.0, org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel extiende MultilayerPerceptronParams para exponer los parámetros s de entrenamiento. Como resultado, layers en MultilayerPerceptronClassificationModel se ha cambiado de Array[Int] a IntArrayParam. Debe usar MultilayerPerceptronClassificationModel.getLayers en lugar de MultilayerPerceptronClassificationModel.layers para recuperar el tamaño de las capas.
  • org.apache.spark.ml.classification.GBTClassifier.numTrees, que está en desuso en la versión 2.4.5, se ha eliminado en la versión 3.0. En su lugar, use getNumTrees.
  • org.apache.spark.ml.clustering.KMeansModel.computeCost, que está en desuso en la versión 2.4, se ha eliminado en la versión 3.0, use ClusteringEvaluator en su lugar.
  • La precisión de la variable de miembro en org.apache.spark.mllib.evaluation.MulticlassMetrics, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. Use la precisión en su lugar.
  • La recuperación de la variable de miembro en org.apache.spark.mllib.evaluation.MulticlassMetrics, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. En su lugar, use accuracy.
  • La variable de miembro fMeasure en org.apache.spark.mllib.evaluation.MulticlassMetrics, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. En su lugar, use accuracy.
  • org.apache.spark.ml.util.GeneralMLWriter.context, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. En su lugar, use session.
  • org.apache.spark.ml.util.MLWriter.context, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. En su lugar, use session.
  • org.apache.spark.ml.util.MLReader.context, que está en desuso en la versión 2.0, se ha eliminado en la versión 3.0. En su lugar, use session.
  • Se ha cambiado abstract class UnaryTransformer[IN, OUT, T <: UnaryTransformer[IN, OUT, T]] a abstract class UnaryTransformer[IN: TypeTag, OUT: TypeTag, T <: UnaryTransformer[IN, OUT, T]] en la versión 3.0.
  • En Spark 3.0, una regresión logística multiclase en Pyspark ahora devolverá (correctamente) LogisticRegressionSummary, no la subclase BinaryLogisticRegressionSummary. De todos modos, los métodos adicionales expuestos por BinaryLogisticRegressionSummary no funcionarán en este caso. (SPARK-31681)
  • En Spark 3.0, los mixins de pyspark.ml.param.shared.Has* ya no proporcionan ningún método Setter set*(self, value). En su lugar, use la instrucción self.set(self.*, value) correspondiente. Consulte SPARK-29093 para más detalles. (SPARK-29093)

Otros cambios de comportamiento

  • La actualización a Scala 2.12 implica los siguientes cambios:

    • La serialización de celdas de paquetes se controla de forma diferente. En el ejemplo siguiente se muestra el cambio de comportamiento y cómo controlarlo.

      Si se ejecuta foo.bar.MyObjectInPackageCell.run() como se define en la siguiente celda de paquetes, se desencadenará el error 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)
        }
      }
      

      Para evitar este error, puede encapsular MyObjectInPackageCell dentro de una clase serializable.

    • Algunos casos que usan DataStreamWriter.foreachBatch requerirán una actualización del código fuente. Este cambio se debe al hecho de que Scala 2.12 tiene conversión automática de expresiones lambda a tipos SAM y puede provocar ambigüedad.

      Por ejemplo, el siguiente código de Scala no se puede compilar:

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

      Para corregir el error de compilación, cambie foreachBatch { (df, id) => myFunc(df, id) } a foreachBatch(myFunc _) o use la API de Java explícitamente: foreachBatch(new VoidFunction2 ...).

  • Dado que la versión de Apache Hive que se usa para controlar las funciones definidas por el usuario de Hive y Hive SerDes se actualiza a la versión 2.3, se requieren dos cambios:

    • La interfaz SerDe de Hive se sustituye por una clase abstracta AbstractSerDe. Para cualquier implementación personalizada SerDe de Hive es necesario migrar a AbstractSerDe.
    • Establecer spark.sql.hive.metastore.jars en builtin implica que se usará el cliente de metastore de Hive 2.3 para acceder a los metastores de Databricks Runtime 7.x. Si necesita acceder a los metastores externos basados en Hive 1.2, establezca spark.sql.hive.metastore.jars en la carpeta que contiene los archivos JAR de Hive 1.2.

Desusos y eliminaciones

  • El índice de omisión de datos quedó obsoleto en Databricks Runtime 4.3 y se eliminó en Databricks Runtime 7.x. Se recomienda usar tablas Delta en su lugar, que ofrecen funcionalidades mejoradas de omisión de datos.
  • En Databricks Runtime 7.x, la versión subyacente de Apache Spark usa Scala 2.12. Dado que las bibliotecas compiladas en Scala 2.11 pueden deshabilitar los clústeres de Databricks Runtime 7.x de forma inesperada, los clústeres que ejecutan Databricks Runtime 7.x no instalan bibliotecas configuradas para instalarse en todos los clústeres. La pestaña Libraries (Bibliotecas) del clúster muestra un estado Skipped y un mensaje de desuso que explica los cambios en el control de bibliotecas. Pero si tiene un clúster que se creó en una versión anterior de Databricks Runtime antes de que se publicara la versión 3.20 de la plataforma Azure Databricks en el área de trabajo y ahora edita ese clúster para usar Databricks Runtime 7.x, todas las bibliotecas configuradas para instalarse en todos los clústeres se instalarán en ese clúster. En este caso, los archivos JAR incompatibles de las bibliotecas instaladas pueden hacer que el clúster se deshabilite. La solución alternativa es clonar el clúster o crear uno nuevo.

Problemas conocidos

  • El análisis del día del año mediante la letra de patrón "D" devuelve un resultado incorrecto si falta el campo de año. Esto puede ocurrir en funciones SQL como to_timestamp, que analiza la cadena datetime como valores de datetime (fecha y hora) mediante una cadena de patrón. (SPARK-31939)
  • Las subconsultas internas de combinación, de ventana o de funciones agregadas pueden dar lugar a resultados incorrectos, si las claves tienen valores -0.0 y 0.0. (SPARK-31958)
  • Una consulta de ventana puede producir un error inesperado de autocombinación ambigua. (SPARK-31956)
  • Es posible que las consultas de streaming con el operador dropDuplicates no puedan reiniciarse con el punto de control escrito por Spark 2.x. (SPARK-31990)