Guide de migration Databricks Runtime 7.x (non pris en charge)

Ce guide fournit des conseils pour vous aider à migrer vos charges de travail Azure Databricks depuis Databricks Runtime 6.x, basées sur Apache Spark 2.4 vers Databricks Runtime 7.3 LTS (non pris en charge), tous deux basés sur Spark 3.0.

Ce guide répertorie les changements de comportement de Spark 3.0 qui peuvent vous obliger à mettre à jour des charges de travail Azure Databricks. Certains de ces changements incluent la suppression complète de la prise en charge de Python 2, la mise à niveau vers Scala 2.12, le support complet de JDK 11 et le passage du calendrier grégorien au calendrier proleptique pour les dates et les timestamps.

Ce guide est un prolongement du Guide de migration Databricks Runtime 7.3 LTS (non pris en charge).

Pour plus d’informations sur la migration entre les versions de Databricks Runtime, consultez le guide de migration de Databricks Runtime.

Nouvelles fonctionnalités et améliorations disponibles sur Databricks Runtime 7.x

Pour obtenir la liste des nouvelles fonctionnalités, des améliorations et des mises à niveau de bibliothèque incluses dans Databricks Runtime 7.3 LTS, consultez les notes de publication de chaque version de Databricks Runtime supérieure à votre version avant migration. Les versions prises en charge de Databricks Runtime 7.x sont les suivantes :

Les mises à jour de maintenance postérieures à la publication sont répertoriées dans Mises à jour de maintenance pour Databricks Runtime (archivées).

Environnement système Databricks Runtime 7.3 LTS

  • Système d’exploitation : Ubuntu 18.04.5 LTS
  • Java :
    • 7.3 LTS : Zulu 8.48.0.53-CA-linux64 (build 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

Changements de comportement majeurs d’Apache Spark 3.0

Les changements de comportement suivants entre Spark 2.4 et Spark 3.0 peuvent vous obliger à mettre à jour les charges de travail Azure Databricks lors de la migration de Databricks Runtime 6.x vers Databricks Runtime 7.x.

Notes

Cet article fournit une liste des changements de comportement importants de Spark que vous devez prendre en compte lorsque vous migrez vers Databricks Runtime 7.x. Pour obtenir la liste complète des changements de comportement, consultez le Guide de migration vers Spark 3.0.1.

Core

  • Dans Spark 3.0, l’accumulateur déconseillé v1 est supprimé.
  • Le fichier journal des événements sera écrit en encodage UTF-8, et le serveur d’historique Spark lira les fichiers journaux des événements en tant qu’encodage UTF-8. Auparavant, Spark écrivait le fichier journal des événements en tant que jeu de caractères par défaut du processus JVM du pilote. Par conséquent, le serveur d’historique Spark de Spark 2.x est nécessaire pour lire les anciens fichiers journaux des événements en cas d’incompatibilité de l’encodage.
  • Un nouveau protocole de récupération des blocs de lecture aléatoire est utilisé. Il est recommandé de mettre à niveau les services de lecture aléatoire externes lors de l’exécution d’applications Spark 3.0. Vous pouvez toujours utiliser les anciens services de lecture aléatoire externe en affectant à la configuration spark.shuffle.useOldFetchProtocol la valeur true. Dans le cas contraire, Spark peut renvoyer des messages d’erreur comme : IllegalArgumentException: Unexpected message type: <number>.

PySpark

  • Dans Spark 3.0, Column.getItem a été corrigé de telle sorte qu’il n’appelle pas Column.apply. Par conséquent, si Column est utilisé comme argument de getItem, l’opérateur d’indexation doit être utilisé. Par exemple, map_col.getItem(col('id')) peut être remplacé par map_col[col('id')].
  • À partir de Spark 3.0, les noms de champs Row ne sont plus triés par ordre alphabétique lors de la construction avec des arguments nommés pour les versions de Python 3.6 et ultérieures, et l’ordre des champs correspond à ce qui est entré. Pour activer les champs triés par défaut, comme dans Spark 2.4, affectez à la variable d’environnement PYSPARK_ROW_FIELD_SORTING_ENABLED la valeur true pour les deux exécuteurs et le pilote. Cette variable d’environnement doit être cohérente sur tous les exécuteurs et pilotes. Dans le cas contraire, cela peut engendrer des échecs ou des réponses incorrectes. Pour les versions de Python inférieures à la version 3.6, la seule option disponible pour le tri des noms de champs est l’ordre alphabétique.
  • Prise en charge de Python 2 déconseillée (SPARK-27884).

Structured Streaming

  • Dans Spark 3.0, Structured Streaming force le schéma source à accepter les valeurs NULL lorsque les sources de fichiers de type texte, JSON, CSV, parquet et ORC sont utilisées via spark.readStream(...). Auparavant, cette fonctionnalité respectait la possibilité de valeur NULL dans le schéma source. Toutefois, cela causait des problèmes difficiles à déboguer avec NPE. Pour restaurer le comportement précédent, affectez à spark.sql.streaming.fileSource.schema.forceNullable la valeur false.
  • Spark 3.0 résout le problème d’exactitude sur la jointure externe flux-flux, ce qui modifie le schéma de l’état. Consultez SPARK-26154 pour plus de détails. Si vous démarrez votre requête depuis un point de contrôle construit à partir de Spark 2.x qui utilise la jointure externe flux-flux, Spark 3.0 fait échouer la requête. Pour recalculer les sorties, ignorez le point de contrôle et relisez les entrées précédentes.
  • Dans Spark 3.0, la classe déconseillée org.apache.spark.sql.streaming.ProcessingTime a été supprimée. Utilisez org.apache.spark.sql.streaming.Trigger.ProcessingTime à la place. De même, org.apache.spark.sql.execution.streaming.continuous.ContinuousTrigger a été supprimé en faveur de Trigger.Continuous, et org.apache.spark.sql.execution.streaming.OneTimeTrigger a été masqué en faveur de Trigger.Once. Consultez SPARK-28199.

SQL, jeux de données et dataFrame

  • Dans Spark 3.0, lors de l’insertion d’une valeur dans une colonne de table avec un type de données différent, le forçage de type est effectué conformément à la norme ANSI SQL standard. Certaines conversions de type déraisonnables, telles que la conversion de string vers int et de double vers boolean sont interdites. Une exception de type Runtime est levée si la valeur est hors limites pour le type de données de la colonne. Dans Spark version 2.4 et les versions antérieures, les conversions de type pendant l’insertion de table sont autorisées tant qu’elles sont des Cast valides. Lors de l’insertion d’une valeur hors limites dans un champ intégral, les bits de poids faible de la valeur sont insérés (tout comme lors du forçage de type numérique Java/Scala). Par exemple, si 257 est inséré dans un champ de type Octet, le résultat est 1. Le comportement est contrôlé par l’option spark.sql.storeAssignmentPolicy, avec une valeur par défaut définie sur « ANSI ». Si vous affectez à l’option la valeur « Legacy », le comportement précédent est restauré.
  • Dans Spark 3.0, lors du forçage de type d’une valeur de chaîne en type intégral (tinyint, smallint, int et bigint), type DateTime (date, timestamp et intervalle) et type booléen, les espaces blancs de début et de fin (< = ACSII 32) sont supprimés avant d’être convertis en ces valeurs de type, par exemple cast(' 1\t' as int) renvoie 1, cast(' 1\t' as boolean) renvoie true, cast('2019-10-10\t as date) renvoie la valeur de date 2019-10-10. Dans Spark version 2.4 et les versions antérieures, lors du forçage de type d’une chaîne en caractères intégraux et booléens, les espaces ne sont pas supprimés des deux extrémités. Les résultats ci-dessus seront null, alors que pour les valeurs DateTime, seuls les espaces de fin (= ASCII 32) seront supprimés. Consultez https://databricks.com/blog/2020/07/22/a-comprehensive-look-at-dates-and-timestamps-in-apache-spark-3-0.html.
  • Dans Spark 3.0, les méthodes déconseillées SQLContext.createExternalTable et SparkSession.createExternalTable ont été supprimées en faveur de createTable.
  • Dans Spark 3.0, la configuration spark.sql.crossJoin.enabled devient une configuration interne et est vraie par défaut. Par conséquent, Spark ne lève pas d’exception sur SQL avec des jointures croisées implicites.
  • Dans Spark 3.0, nous avons inversé l’ordre des arguments de la fonction trim de TRIM(trimStr, str) à TRIM(str, trimStr) pour être compatible avec d’autres bases de données.
  • Dans Spark version 2.4 et les versions antérieures, des requêtes SQL telles que FROM <table> ou FROM <table> UNION ALL FROM <table> sont prises en charge par accident. Avec Hive FROM <table> SELECT <expr>, la clause SELECT n’est pas négligeable. Hive et Presto ne prennent pas en charge cette syntaxe. Par conséquent, nous traiterons ces requêtes comme des requêtes non valides à partir de Spark 3.0.
  • À partir de Spark 3.0, les API DataSet et DataFrame unionAll ne sont plus déconseillées. C’est un alias pour union.
  • Dans Spark version 2.4 et les versions antérieures, l’analyseur de la source de données JSON traite les chaînes vides comme NULL pour certains types de données tels que IntegerType. Pour FloatType et DoubleType, il échoue sur les chaînes vides et lève des exceptions. À partir de Spark 3.0, nous n’acceptons pas les chaînes vides et des exceptions sont levées pour les types de données, à l’exception de StringType et BinaryType.
  • Dans Spark 3.0, les fonctions from_json prennent en charge deux modes : PERMISSIVE et FAILFAST. Les modes peuvent être définis à l’aide de l’option mode. Le mode par défaut devient PERMISSIVE. Dans les versions précédentes, le comportement de from_json n’était pas conforme à PERMISSIVE ni FAILFAST,, en particulier dans le traitement des enregistrements JSON mal formés. Par exemple, dans les versions précédentes, la chaîne JSON {"a" 1} avec le schéma a INT est convertie en null, tandis que Spark 3.0 la convertit en Row(null).

Instructions DDL

  • Dans Spark 3.0, CREATE TABLE n’a pas de fournisseur spécifique et utilise la valeur de spark.sql.sources.default en tant que fournisseur. Dans Spark version 2.4 et les versions antérieures, Hive était considéré comme le fournisseur. Définissez spark.sql.legacy.createHiveTableByDefault.enabled sur true pour restaurer le comportement utilisé avant la mise à niveau vers Spark 3.0.
  • Dans Spark 3.0, lors de l’insertion d’une valeur dans une colonne de table avec un type de données différent, le forçage de type est effectué conformément à la norme ANSI SQL standard. Certaines conversions de type déraisonnables, telles que la conversion de string vers int et de double vers boolean sont interdites. Une exception de type Runtime est levée si la valeur est hors limites pour le type de données de la colonne. Dans Spark version 2.4 et les versions antérieures, les conversions de type pendant l’insertion de table sont autorisées tant qu’elles sont des Cast valides. Lors de l’insertion d’une valeur hors limites dans un champ intégral, les bits de poids faible de la valeur sont insérés (tout comme lors du forçage de type numérique Java/Scala). Par exemple, si 257 est inséré dans un champ de type Octet, le résultat est 1. Le comportement est contrôlé par l’option spark.sql.storeAssignmentPolicy, avec une valeur par défaut définie sur « ANSI ». Si vous affectez à l’option la valeur « Legacy », le comportement précédent est restauré.
  • Dans Spark 3.0, SHOW CREATE TABLE renvoie toujours le DDL Spark, même si la table donnée est une table Hive SerDe. Pour générer un DDL Hive, utilisez plutôt la commande SHOW CREATE TABLE AS SERDE.
  • Dans Spark 3.0, la colonne de type CHAR n’est pas autorisée dans les tables SerDe non-Hive, et les commandes CREATE/ALTER TABLE échouent si le type CHAR est détecté. Utilisez le type STRING à la place. Dans Spark version 2.4 et les versions antérieures, le type CHAR est traité en tant que type STRING et le paramètre de longueur est simplement ignoré.

Fonctions définies par l’utilisateur et fonctions intégrées

  • Dans Spark 3.0, l’utilisation de org.apache.spark.sql.functions.udf(AnyRef, DataType) n’est pas autorisée par défaut. Affectez à spark.sql.legacy.allowUntypedScalaUDF la valeur true pour continuer à l’utiliser. Dans Spark version 2.4 et les versions antérieures, si org.apache.spark.sql.functions.udf(AnyRef, DataType) obtient une fermeture Scala avec un argument de type primitif, le paramètre UDF renvoyé renvoie la valeur NULL si les valeurs d’entrée sont NULL. Toutefois, dans Spark 3.0, la fonction UDF renvoie la valeur par défaut du type Java si la valeur d’entrée est NULL. Par exemple, val f = udf((x: Int) => x, IntegerType), f($"x") renvoie la valeur NULL dans Spark 2.4 et les versions antérieures si la colonne x est NULL, et renvoie 0 dans Spark 3.0. Ce changement de comportement vient du fait que Spark 3.0 est généré avec Scala 2.12 par défaut.
  • Dans Spark version 2.4 et les versions antérieures, vous pouvez créer une carte avec des clés dupliquées via des fonctions intégrées telles que CreateMap, StringToMap, etc. Le comportement de la fonction map avec des clés dupliquées n’est pas défini, par exemple, les recherches de mappage respectent le fait que la clé dupliquée apparaît en premier, Dataset.collect fait que la clé dupliquée apparaît en dernier, MapKeys renvoie les clés dupliquées, etc. Dans Spark 3.0, Spark lève une exception RuntimeException quand des clés dupliquées sont trouvées. Vous pouvez définir spark.sql.mapKeyDedupPolicy sur LAST_WIN pour dédupliquer les clés de mappage avec la dernière stratégie WINS. Les utilisateurs peuvent toujours lire les valeurs de mappage avec des clés dupliquées à partir de sources de données qui ne l’appliquent pas (par exemple, Parquet). Le comportement n’est pas défini.

Sources de données

  • Dans Spark Version 2.4 et les versions antérieures, la valeur de colonne de partition est convertie en valeur NULL si elle ne peut pas être convertie en un schéma fourni par l’utilisateur correspondant. Dans 3.0, la valeur de colonne de partition est validée avec un schéma fourni par l’utilisateur. Une exception est levée en cas d’échec de la validation. Vous pouvez désactiver cette validation en affectant à spark.sql.sources.validatePartitionColumns la valeur false.
  • Dans Spark version 2.4 et les versions antérieures, l’analyseur de la source de données JSON traite les chaînes vides comme NULL pour certains types de données tels que IntegerType. Pour FloatType, DoubleType, DateType et TimestampType, il échoue sur les chaînes vides et lève des exceptions. Spark 3.0 interdit les chaînes vides et lève une exception pour les types de données, à l’exception de StringType et BinaryType. L’ancien comportement d’autorisation d’une chaîne vide peut être restauré en affectant à spark.sql.legacy.json.allowEmptyString.enabled la valeur true.
  • Dans Spark 3.0, si des fichiers ou des sous-répertoires disparaissent pendant le listing des répertoires récursifs (c’est-à-dire qu’ils apparaissent dans une liste intermédiaire, mais ne peuvent pas être lus ou répertoriés au cours des phases ultérieures de la liste de répertoires récursifs, en raison de la suppression simultanée des fichiers ou de problèmes de cohérence du magasin d’objet), alors la liste échoue avec une exception à moins que spark.sql.files.ignoreMissingFiles soit true (faux par défaut). Dans les versions précédentes, ces fichiers ou sous-répertoires manquants seraient ignorés. Notez que ce changement de comportement s’applique uniquement lors du listing initial des fichiers de la table (ou pendant REFRESH TABLE) et non lors de l’exécution de la requête : le changement notable est que spark.sql.files.ignoreMissingFiles est désormais respecté lors du listing des fichiers de la table et de la planification des requêtes, pas seulement au moment de l’exécution de la requête.
  • Dans Spark version 2.4 et les versions antérieures, la source du fichier CSV convertit une chaîne CSV incorrecte en ligne avec toutes les valeurs NULL en mode PERMISSIF. Dans Spark 3.0, la ligne renvoyée peut contenir des champs non NULL si certaines valeurs de colonne CSV ont été analysées et converties correctement vers les types souhaités.
  • Dans Spark 3.0, le type logique parquet TIMESTAMP_MICROS est utilisé par défaut lors de l’enregistrement des colonnes TIMESTAMP. Dans Spark version 2.4 et les versions antérieures, les colonnes TIMESTAMP sont enregistrées en tant que INT96 dans les fichiers parquet. Notez que certains systèmes SQL tels que Hive 1.x et Impala 2.x ne peuvent lire que les timestamps INT96. Vous pouvez définir spark.sql.parquet.outputTimestampType sur INT96 pour restaurer le comportement précédent et maintenir l’interopérabilité.
  • Dans Spark 3.0, lorsque des fichiers Avro sont écrits avec le schéma fourni par l’utilisateur, les champs sont mis en correspondance avec les noms de champs entre le schéma de catalyseur et le schéma Avro au lieu de positions.

Moteur de requête

  • Dans Spark 3.0, la requête DataSet échoue si elle contient une référence de colonne ambiguë qui est provoquée par une jointure réflexive. Exemple fréquent : val df1 = ...; val df2 = df1.filter(...);, then df1.join(df2, df1("a") > df2("a")) renvoie un résultat vide, ce qui est assez confus. En effet, Spark ne peut pas résoudre les références de colonne de jeu de données qui pointent vers des tables réflexives, et df1("a") est tout à fait similaire à df2("a") dans Spark. Définissez spark.sql.analyzer.failAmbiguousSelfJoin sur false pour restaurer le comportement utilisé avant la mise à niveau vers Spark 3.0.
  • Dans Spark 3.0, les nombres écrits en notation scientifique (par exemple, 1E2) sont analysés en tant que Double. Dans Spark version 2.4 et les versions antérieures, ils sont analysés en tant que Decimal. Pour restaurer le comportement pré-Spark 3.0, vous pouvez affecter spark.sql.legacy.exponentLiteralAsDecimal.enabled à la valeur true.
  • Dans Spark 3.0, la configuration spark.sql.crossJoin.enabled devient une configuration interne et est vraie par défaut. Par défaut, Spark ne déclenche pas d’exceptions sur les SQL avec des jointures croisées implicites.
  • Dans Spark version 2.4 et les versions antérieures, la valeur float/double-0.0 est sémantiquement égale à 0.0, mais -0.0 et 0.0 sont considérées comme des valeurs différentes lorsqu’elles sont utilisées dans des clés de regroupement agrégées, des clés de partition de fenêtre et des clés de jointure. Dans Spark 3.0, ce bogue est résolu. Par exemple, Seq(-0.0, 0.0).toDF("d").groupBy("d").count() renvoie [(0.0, 2)] dans Spark 3.0, et [(0.0, 1), (-0.0, 1)] dans Spark 2.4 et les versions antérieures.
  • Dans Spark 3.0, les littéraux TIMESTAMP sont convertis en chaînes à l’aide de la configuration SQL spark.sql.session.timeZone. Dans Spark version 2.4 et les versions antérieures, la conversion utilise le fuseau horaire par défaut de la machine virtuelle Java.
  • Dans Spark 3.0, Spark convertit String en Date/Timestamp en comparaisons binaires avec des dates/timestamps. Vous pouvez restaurer le précédent comportement de forçage de type Date/Timestamp vers String en attribuant à la propriété spark.sql.legacy.typeCoercion.datetimeToString.enabled la valeur true.
  • Dans Spark version 2.4 et les versions antérieures, les ID de fuseau horaire non valides sont ignorés silencieusement et remplacés par le fuseau horaire GMT, par exemple dans la fonction from_utc_timestamp. Dans Spark 3.0, ces ID de fuseau horaire sont rejetés et Spark lève une exception java.time.DateTimeException.
  • Dans Spark 3.0, le calendrier grégorien proleptique est utilisé pour l’analyse, la mise en forme et la conversion des dates et des timestamps, ainsi que pour l’extraction des sous-composants comme les années, les jours, etc. Spark 3.0 utilise les classes d’API Java 8 des packages java.time basés sur la chronologie ISO. Dans Spark version 2.4 et les versions antérieures, ces opérations sont effectuées à l’aide du calendrier hybride (julien + grégorien). Les changements ont un impact sur les résultats des dates antérieures au 15 octobre 1582 (grégorien) et affectent l’API Spark 3.0 suivante :
    • Analyse/mise en forme des chaînes timestamp/date. Cet effet est présent sur les sources de donnée CSV/JSON et sur les fonctions unix_timestamp, date_format, to_unix_timestamp, from_unixtime, to_date, to_timestamp lorsque les modèles spécifiés par les utilisateurs sont utilisés pour l’analyse et la mise en forme. Dans Spark 3.0, nous définissons nos propres chaînes de modèle dans sql-ref-datetime-pattern.md, qui sont implémentées via java.time.format.DateTimeFormatter de manière sous-jacente. La nouvelle implémentation effectue une vérification stricte de son entrée. Par exemple, le timestamp 2015-07-22 10:00:00 ne peut pas être analysé si le modèle est yyyy-MM-dd, car l’analyseur ne consomme pas l’intégralité de l’entrée. Autre exemple : l’entrée 31/01/2015 00:00 ne peut pas être analysée par le modèle dd/MM/yyyy hh:mm, car hh suppose des heures dans la plage 1-12. Dans Spark version 2.4 et les versions antérieures, java.text.SimpleDateFormat est utilisé pour les conversions de chaînes timestamp/date, et les modèles pris en charge sont décrits dans simpleDateFormat. L’ancien comportement peut être restauré en configurant spark.sql.legacy.timeParserPolicy sur LEGACY.
    • Les fonctions weekofyear, weekday, dayofweek, date_trunc, from_utc_timestamp, to_utc_timestamp et unix_timestamp utilisent l’API java.time pour calculer le numéro de semaine de l’année, le jour de la semaine également pour la conversion de valeurs depuis/vers les valeurs TimestampType dans le fuseau horaire UTC.
    • Les options JDBC lowerBound et upperBound sont converties en valeurs TimestampType/DateType de la même façon que les chaînes de conversion en valeurs TimestampType/DateType. La conversion est basée sur le calendrier grégorien proleptique et le fuseau horaire défini par la configuration SQL spark.sql.session.timeZone. Dans Spark version 2.4 et les versions antérieures, la conversion est basée sur le calendrier hybride (Julien + Grégorien) et sur le fuseau horaire système par défaut.
    • Mise en forme des littéraux TIMESTAMP et DATE.
    • Création de littéraux typés TIMESTAMP et DATE à partir de chaînes. Dans Spark 3.0, la conversion de chaînes en littéraux typés TIMESTAMP/DATE est effectuée via le forçage de type vers les valeurs TIMESTAMP/DATE. Par exemple, TIMESTAMP '2019-12-23 12:59:30' est sémantiquement égal à CAST('2019-12-23 12:59:30' AS TIMESTAMP). Lorsque la chaîne d’entrée ne contient pas d’informations sur le fuseau horaire, le fuseau horaire de la configuration SQL spark.sql.session.timeZone est utilisé. Dans Spark version 2.4 et les versions antérieures, la conversion est basée sur le fuseau horaire du système JVM. Les différentes sources du fuseau horaire par défaut peuvent modifier le comportement des littéraux typés TIMESTAMP et DATE.

Apache Hive

  • Dans Spark 3.0, nous avons mis à niveau la version intégrée de Hive pour passer la version 1.2 à la version 2.3, ce qui a les conséquences suivantes :
    • Vous devrez peut-être définir spark.sql.hive.metastore.version et spark.sql.hive.metastore.jars en fonction de la version du metastore Hive auquel vous souhaitez vous connecter. Par exemple : affectez à spark.sql.hive.metastore.version la valeur 1.2.1 et à spark.sql.hive.metastore.jars la valeur maven si votre version de metastore Hive est 1.2.1.
    • Vous devez migrer votre SerDes personnalisé vers Hive 2.3 ou créer votre propre Spark avec un profil hive-1.2. Pour plus d’informations, consultez HIVE-15167.
    • La représentation sous forme de chaîne décimale peut être différente entre Hive 1.2 et Hive 2.3 lors de l’utilisation de l’opérateur TRANSFORM dans SQL pour la transformation de script, qui dépend du comportement de Hive. Dans Hive 1.2, la représentation sous forme de chaîne omet les zéros de fin. Mais dans Hive 2.3,elle contient toujours 18 chiffres avec des zéros de fin, si nécessaire.
    • Dans Databricks Runtime 7. x, lors de la lecture d’une table Hive SerDe, par défaut, Spark interdit la lecture des fichiers dans un sous-répertoire qui n’est pas une partition de table. Pour l’activer, affectez la valeur true à la configuration spark.databricks.io.hive.scanNonpartitionedDirectory.enabled. Cela n’affecte pas les lecteurs de fichiers et les lecteurs de fichiers de table natifs Spark.

MLlib

  • OneHotEncoder, déconseillé dans la version 2.3, a été supprimé dans la version 3.0 et OneHotEncoderEstimator a été renommé OneHotEncoder.
  • org.apache.spark.ml.image.ImageSchema.readImages, déconseillé dans la version 2.3, a été supprimé dans la version 3.0. Utilisez spark.read.format('image') à la place.
  • org.apache.spark.mllib.clustering.KMeans.train avec param int runs, déconseillé dans la version 2.1, a été supprimé dans la version 3.0. Utilisez la méthode train sans exécutions à la place.
  • org.apache.spark.mllib.classification.LogisticRegressionWithSGD, déconseillé dans la version 2.0, a été supprimé dans la version 3.0, utilisez org.apache.spark.ml.classification.LogisticRegression ou spark.mllib.classification.LogisticRegressionWithLBFGS à la place.
  • org.apache.spark.mllib.feature.ChiSqSelectorModel.isSorted, déconseillé dans la version 2.1, a été supprimé dans la version 3.0. Cela n’est pas destiné aux sous-classes à utiliser.
  • org.apache.spark.mllib.regression.RidgeRegressionWithSGD, déconseillé dans la version 2.0, est supprimé dans la version 3.0. Utilisez org.apache.spark.ml.regression.LinearRegression avec elasticNetParam = 0.0. Remarquez que la valeur par défaut regParam est 0,01 pour RidgeRegressionWithSGD, mais est 0,0 pour LinearRegression.
  • org.apache.spark.mllib.regression.LassoWithSGD, déconseillé dans la version 2.0, a été supprimé dans la version 3.0. Utilisez org.apache.spark.ml.regression.LinearRegression avec elasticNetParam = 1.0. Remarquez que la valeur par défaut regParam est 0,01 pour LassoWithSGD, mais est 0,0 pour LinearRegression.
  • org.apache.spark.mllib.regression.LinearRegressionWithSGD, déconseillé dans la version 2.0, a été supprimé dans la version 3.0. Utilisez plutôt org.apache.spark.ml.regression.LinearRegression ou LBFGS.
  • org.apache.spark.mllib.clustering.KMeans.getRuns et setRuns, déconseillés dans la Version 2.1, ont été supprimés dans la version 3.0, et n’ont eu aucun effet depuis Spark 2.0.0.
  • org.apache.spark.ml.LinearSVCModel.setWeightCol, déconseillé dans la version 2.4 a été supprimé dans la version 3.0 et n’est pas destiné aux utilisateurs.
  • Dans la version 3.0, org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel étend MultilayerPerceptronParams pour exposer les paramètres d’apprentissage. Par conséquent, layers dans MultilayerPerceptronClassificationModel a été remplacé de Array[Int] vers IntArrayParam. Vous devez utiliser MultilayerPerceptronClassificationModel.getLayers au lieu de MultilayerPerceptronClassificationModel.layers pour récupérer la taille des couches.
  • org.apache.spark.ml.classification.GBTClassifier.numTrees, déconseillé dans la version 2.4.5 a été supprimé dans la version 3.0. Utilisez getNumTrees à la place.
  • org.apache.spark.ml.clustering.KMeansModel.computeCost, déconseillé dans la version 2.4, est supprimé dans la version 3.0, utilisez ClusteringEvaluator à la place.
  • La précision de la variable membre dans org.apache.spark.mllib.evaluation.MulticlassMetrics, qui est déconseillée dans la version 2.0, a été supprimée dans la Version 3.0. Utilisez l’exactitude à la place.
  • Le rappel de la variable membre dans org.apache.spark.mllib.evaluation.MulticlassMetrics, qui est déconseillée dans la version 2.0, a été supprimée dans la version 3.0. Utilisez accuracy à la place.
  • La variable membre fMeasure dans org.apache.spark.mllib.evaluation.MulticlassMetrics, déconseillée dans la version 2.0, a été supprimée dans la version 3.0. Utilisez accuracy à la place.
  • org.apache.spark.ml.util.GeneralMLWriter.context, déconseillé dans la version 2.0, est supprimé dans la version 3.0. Utilisez session à la place.
  • org.apache.spark.ml.util.MLWriter.context, déconseillé dans la version 2.0, est supprimé dans la version 3.0. Utilisez session à la place.
  • org.apache.spark.ml.util.MLReader.context, déconseillé dans la version 2.0, est supprimé dans la version 3.0. Utilisez session à la place.
  • abstract class UnaryTransformer[IN, OUT, T <: UnaryTransformer[IN, OUT, T]] est changé en abstract class UnaryTransformer[IN: TypeTag, OUT: TypeTag, T <: UnaryTransformer[IN, OUT, T]] dans la version 3.0.
  • Dans Spark 3.0, une régression logistique multiclasse dans Pyspark renverra désormais (correctement) LogisticRegressionSummary, et non pas la sous-classe BinaryLogisticRegressionSummary. Il existe encore tout de même certains cas pour lesquels les méthodes supplémentaires exposées par BinaryLogisticRegressionSummary ne fonctionneront pas. (SPARK-31681)
  • Dans Spark 3.0, Mixins pyspark.ml.param.shared.Has* ne fournit plus de méthode setter set*(self, value), utilisez plutôt le self.set(self.*, value) respectif à la place. Pour plus d’informations, consultez SPARK-29093. (SPARK-29093)

Autres changements de comportement

  • La mise à niveau vers Scala 2.12 implique les changements suivants :

    • La sérialisation des cellules du package est gérée différemment. L’exemple suivant illustre le changement de comportement et la façon de le gérer.

      L’exécution de foo.bar.MyObjectInPackageCell.run() telle que définie dans la cellule de package suivante déclenchera l’erreur 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)
        }
      }
      

      Pour contourner cette erreur, vous pouvez envelopper MyObjectInPackageCell dans une classe sérialisable.

    • Certains cas d’utilisation de DataStreamWriter.foreachBatch requièrent une mise à jour du code source. Cette modification est due au fait que Scala 2.12 convertit automatiquement les expressions lambda en types SAM et peut provoquer une ambiguïté.

      Par exemple, le code Scala suivant ne peut pas être compilé :

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

      Pour corriger l’erreur de compilation, remplacez foreachBatch { (df, id) => myFunc(df, id) } par foreachBatch(myFunc _) ou utilisez l’API Java explicitement : foreachBatch(new VoidFunction2 ...).

  • Étant donné que la version de Apache Hive utilisée pour gérer les fonctions Hive définies par l’utilisateur et Hive SerDes est mise à niveau vers la version 2.3, deux modifications sont requises :

    • L’interface SerDe de Hive est remplacée par la classe abstraite AbstractSerDe. Pour toute implémentation de SerDe de Hive personnalisée, la migration vers AbstractSerDe est nécessaire.
    • La définition de spark.sql.hive.metastore.jars vers la valeur builtin signifie que le client du metastore Hive 2.3 sera utilisé pour accéder à Databricks Runtime 7.x. Si vous avez besoin d’accéder aux metastores externes basés sur Hive 1.2, définissez spark.sql.hive.metastore.jars sur le dossier qui contient les fichiers JAR Hive 1.2.

Désapprobations et suppressions

  • Les données qui ignorent l’index ont été déconseillées dans Databricks Runtime 4.3 et supprimées dans Databricks Runtime 7.x. Nous vous recommandons d’utiliser des tables Delta à la place, qui offrent des capacités de saut de données améliorées.
  • Dans Databricks Runtime 7.x, la version sous-jacente de Apache Spark utilise Scala 2.12. Étant donné que les bibliothèques compilées avec Scala 2.11 peuvent désactiver les clusters Databricks Runtime 7.x de manière inattendue, les clusters exécutant Databricks Runtime 7.x n’installent pas les bibliothèques configurées pour être installées sur tous les clusters. L’onglet bibliothèques de clusters affiche un état Skipped et un message d’obsolescence qui explique les modifications apportées à la gestion de la bibliothèque. Toutefois, si vous avez un cluster qui a été créé sur une version antérieure de Databricks Runtime avant la sortie de la version de Azure Databricks plateforme 3.20 sur votre espace de travailet que vous modifiez maintenant ce cluster pour utiliser Databricks Runtime 7.x, toutes les bibliothèques qui étaient configurées pour être installées sur tous les clusters seront installées sur ce cluster. Dans ce cas, tous les fichiers JAR incompatibles dans les bibliothèques installées peuvent entraîner la désactivation du cluster. La solution de contournement consiste soit à cloner le cluster, soit à créer un nouveau cluster.

Problèmes connus

  • Le jour de l’analyse de l’année à l’aide de la lettre « d » renvoie un résultat incorrect si le champ Year est manquant. Cela peut se produire dans des fonctions SQL comme to_timestamp, qui analyse la chaîne DateHeure en valeurs DateHeure à l’aide d’une chaîne de modèle. (SPARK-31939)
  • Join/Window/Aggregate dans les sous-requêtes peut entraîner des résultats incorrects si les clés ont les valeurs -0.0 et 0.0. (SPARK-31958)
  • Une requête de fenêtre peut échouer avec une erreur de jointure réflexive ambiguë de manière inattendue. (SPARK-31956)
  • Les requêtes de diffusion en continu avec un opérateur dropDuplicates ne pourront peut-être pas redémarrer avec le point de contrôle écrit par Spark 2.x. (SPARK-31990)