Migrationsleitfaden für Databricks Runtime 7.x (EoS)
Hinweis
Die Unterstützung für diese Databricks-Runtime-Version wurde beendet. Den End-of-Support-Termin finden Sie im Verlauf des Supportendes. Informationen zu allen unterstützten Databricks Runtime-Versionen finden Sie unter Versionshinweise, Versionen und Kompatibilität von Databricks Runtime.
Dieser Leitfaden unterstützt Sie bei der Migration Ihrer Azure Databricks-Workloads von Databricks Runtime 6.x, das auf Apache Spark 2.4 basiert, zu Databricks Runtime 7.3 LTS (EoS), das auf Spark 3.0 basiert.
In diesem Leitfaden werden die Änderungen hinsichtlich des Spark 3.0-Verhaltens aufgeführt, die eine Aktualisierung von Azure Databricks-Workloads erforderlich machen können. Zu diesen Änderungen gehören unter anderem die vollständige Abschaffung der Unterstützung für Python 2, das Upgrade auf Scala 2.12, die vollständige Unterstützung für JDK 11 und die Umstellung vom gregorianischen auf den proleptischen Kalender für Datumswerte und Zeitstempel.
Dieser Leitfaden ist eine Ergänzung zum Migrationsleitfaden zu Databricks Runtime 7.3 LTS (EoS).
Neue Features und Verbesserungen in Databricks Runtime 7.x
Eine Liste der neuen Features, Verbesserungen und Bibliotheksupgrades, die in Databricks Runtime 7.3 LTS enthalten sind, finden Sie in den Versionshinweisen der jeweiligen Databricks Runtime-Version, von der aus Sie migrieren. Zu den unterstützten Databricks Runtime 7.x-Versionen gehören folgende:
Nach dem Release bereitgestellte Wartungsupdates sind unter Wartungsupdates für Databricks Runtime (archiviert) aufgeführt.
Systemumgebung für Databricks Runtime 7.3 LTS
- Betriebssystem: 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
Wichtige Verhaltensänderungen in Apache Spark 3.0
Die folgenden Verhaltensänderungen zwischen Spark 2.4 und Spark 3.0 machen möglicherweise eine Aktualisierung von Azure Databricks-Workloads erforderlich, wenn Sie von Databricks Runtime 6.x zu Databricks Runtime 7.x migrieren.
Hinweis
Dieser Artikel enthält eine Liste der wichtigen Änderungen am Spark-Verhalten, die Sie bei der Migration zu Databricks Runtime 7.x berücksichtigen sollten.
Core
- In Spark 3.0 wird der veraltete Akkumulator v1 entfernt.
- Die Ereignisprotokolldatei wird als UTF-8-Codierung geschrieben, und der Spark-Verlaufsserver gibt Ereignisprotokolldateien als UTF-8-Codierung wieder. Zuvor verwendete Spark zum Schreiben der Ereignisprotokolldatei den Standardzeichensatz des Treiber-JVM-Prozesses. Aus diesem Grund wird der Spark-Verlaufsserver von Spark 2.x benötigt, um im Falle einer inkompatiblen Codierung die alten Ereignisprotokolldateien zu lesen.
- Es wird ein neues Protokoll zum Abrufen von Shuffleblöcken verwendet. Es wird empfohlen, externe Shuffledienste zu aktualisieren, wenn Spark 3.0-Anwendungen ausgeführt werden. Sie können weiterhin die alten externen Shuffledienste verwenden, indem Sie die Konfiguration
spark.shuffle.useOldFetchProtocol
auftrue
festlegen. Andernfalls kann es bei Spark zu Fehlermeldungen wieIllegalArgumentException: Unexpected message type: <number>
kommen.
PySpark
- In Spark 3.0 wurde
Column.getItem
korrigiert, sodassColumn.apply
nicht aufgerufen wird. Wenn alsoColumn
als Argument fürgetItem
verwendet wird, sollte der Indizierungsoperator verwendet werden. Zum Beispiel solltemap_col.getItem(col('id'))
durchmap_col[col('id')]
ersetzt werden. - Ab Spark 3.0 werden
Row
-Feldnamen bei der Konstruktion mit benannten Argumenten für Python-Version 3.6 und höher nicht mehr alphabetisch sortiert, und die Reihenfolge der Felder entspricht der eingegebenen Reihenfolge. Um (wie in Spark 2.4) standardmäßig sortierte Felder zu aktivieren, legen Sie die UmgebungsvariablePYSPARK_ROW_FIELD_SORTING_ENABLED
sowohl für Executors als auch für Treiber auftrue
fest. Diese Umgebungsvariable muss für alle Executors und Treiber gleich sein. Andernfalls kann es zu Fehlern oder falschen Antworten kommen. Bei Python-Versionen vor Version 3.6 sind die Feldnamen ausschließlich alphabetisch sortiert. - Die Unterstützung für Python 2 wurde eingestellt (SPARK-27884).
Strukturiertes Streaming
- In Spark 3.0 erzwingt das strukturierte Streaming die Umwandlung in ein Quellschema, das NULL-Werte zulässt, wenn dateibasierte Datenquellen wie Text, JSON, CSV, Parquet und ORC über
spark.readStream(...)
verwendet werden. Bisher wurde die NULL-Zulässigkeit im Quellschema berücksichtigt. Dies führte jedoch zu Problemen beim Debuggen mit NPE. Um das vorherige Verhalten wiederherzustellen, legen Siespark.sql.streaming.fileSource.schema.forceNullable
auffalse
fest. - Spark 3.0 behebt das Konsistenzproblem beim äußeren Stream-Stream-Join, der das Zustandsschema ändert. Weitere Informationen finden Sie unter SPARK-26154. Wenn Sie Ihre Abfrage von einem Prüfpunkt aus starten, der mit Spark 2.x erstellt wurde und einen äußeren Stream-Stream-Join verwendet, kommt es in Spark 3.0 zu einem Abfragefehler. Um die Ausgaben neu zu berechnen, verwerfen Sie den Prüfpunkt, und geben Sie die vorherigen Eingaben erneut wieder.
- In Spark 3.0 wurde die veraltete Klasse
org.apache.spark.sql.streaming.ProcessingTime
entfernt. Verwenden Sie stattdessenorg.apache.spark.sql.streaming.Trigger.ProcessingTime
. Ebenso wurdeorg.apache.spark.sql.execution.streaming.continuous.ContinuousTrigger
zugunsten vonTrigger.Continuous
entfernt undorg.apache.spark.sql.execution.streaming.OneTimeTrigger
wurde zugunsten vonTrigger.Once
ausgeblendet. Siehe SPARK-28199.
SQL, Datasets und DataFrame
- In Spark 3.0 wird beim Einfügen eines Werts in eine Tabellenspalte mit einem anderen Datentyp eine Typumwandlung gemäß ANSI SQL-Standard durchgeführt. Bestimmte unangemessene Typumwandlungen, beispielsweise die Konvertierung von
string
inint
unddouble
inboolean
, sind unzulässig. Es wird eine Laufzeitausnahme ausgelöst, wenn der Wert für den Datentyp der Spalte außerhalb des zulässigen Bereichs liegt. In Spark-Version 2.4 und Vorgängerversionen sind Typkonvertierungen während einer Tabelleneinfügung erlaubt, solange es sich um einen gültigenCast
handelt. Wenn ein Wert, der außerhalb des zulässigen Bereichs liegt, in ein integrales Feld eingefügt wird, werden die niederwertigen Bits des Werts eingefügt (wie bei einer numerischen Java/Scala-Typumwandlung). Wenn beispielsweise der Wert 257 in ein Feld vom Typ „Byte“ eingefügt wird, lautet das Ergebnis 1. Das Verhalten wird durch die Optionspark.sql.storeAssignmentPolicy
gesteuert, wobei der Standardwert „ANSI“ lautet. Durch Festlegen der Option auf „Legacy“ wird das vorherige Verhalten wiederhergestellt. - In Spark 3.0 werden bei der Umwandlung von Zeichenfolgenwerten in integrale Typen („tinyint“, „smallint“, „int“ und „bigint“), datetime-Typen (Datum, Zeitstempel und Intervall) und boolesche Typen die führenden und nachgestellten Leerzeichen (<= ACSII 32) vor der Umwandlung in diese Typenwerte abgeschnitten. Beispielsweise gibt
cast(' 1\t' as int)
den Wert1
,cast(' 1\t' as boolean)
den Werttrue
undcast('2019-10-10\t as date)
den Datumswert2019-10-10
zurück. In Spark werden bis zur Version 2.4 bei der Umwandlung von Zeichenfolgen in integrale und boolesche Werte die Leerzeichen auf beiden Seiten nicht abgeschnitten, sodass die obigen Ergebnissenull
lauten, während bei datetime-Werten nur die Leerzeichen am Ende (= ASCII 32) entfernt werden. Siehe https://databricks.com/blog/2020/07/22/a-comprehensive-look-at-dates-and-timestamps-in-apache-spark-3-0.html. - In Spark 3.0 wurden die veralteten Methoden
SQLContext.createExternalTable
undSparkSession.createExternalTable
zugunsten ihrer ErsetzungcreateTable
entfernt. - In Spark 3.0 wird die Konfiguration
spark.sql.crossJoin.enabled
zur internen Konfiguration und ist standardmäßig auf TRUE festgelegt, sodass Spark standardmäßig keine Ausnahme für SQL mit impliziten Kreuzverknüpfungen auslöst. - In Spark 3.0 wurde die Argumentreihenfolge der trim-Funktion von
TRIM(trimStr, str)
inTRIM(str, trimStr)
geändert, um mit anderen Datenbanken kompatibel zu sein. - In Spark wurden bis zur Version 2.4 unabsichtlich SQL-Abfragen wie
FROM <table>
oderFROM <table> UNION ALL FROM <table>
unterstützt. Im Hive-StilFROM <table> SELECT <expr>
darf dieSELECT
-Klausel nicht fehlen. Weder Hive noch Presto unterstützen diese Syntax. Daher werden diese Abfragen ab Spark 3.0 als ungültig betrachtet. - Ab Spark 3.0 wird die Dataset- und DataFrame-API
unionAll
nicht mehr als veraltet eingestuft. Sie ist ein Alias fürunion
. - Bis zur Spark-Version 2.4 behandelt der Parser der JSON-Datenquelle leere Zeichenfolgen für einige Datentypen wie
IntegerType
als NULL. FürFloatType
undDoubleType
kommt es bei leeren Zeichenfolgen zu einem Fehler, und es werden Ausnahmen ausgelöst. Seit Spark 3.0 sind leere Zeichenfolgen nicht mehr zulässig, und es werden Ausnahmen für alle Datentypen außerStringType
undBinaryType
ausgelöst. - Seit Spark 3.0 unterstützen die
from_json
-Funktionen zwei Modi:PERMISSIVE
undFAILFAST
. Die Modi können über die Optionmode
festgelegt werden. Der Standardmodus lautet jetztPERMISSIVE
. In früheren Versionen entsprach das Verhalten vonfrom_json
wederPERMISSIVE
nochFAILFAST,
, insbesondere bei der Verarbeitung von nicht wohlgeformten JSON-Datensätzen. Beispielsweise wurde die JSON-Zeichenfolge{"a" 1}
mit dem Schemaa INT
von früheren Versionen innull
konvertiert, während Spark 3.0 eine Konvertierung inRow(null)
durchführt.
DDL-Anweisungen
- In Spark 3.0 verwendet
CREATE TABLE
ohne einen bestimmten Anbieter den Wert vonspark.sql.sources.default
als Anbieter. In Spark Version 2.4 und niedrigeren Versionen war dies Hive. Um das Verhalten vor Spark 3.0 wiederherzustellen, können Siespark.sql.legacy.createHiveTableByDefault.enabled
auftrue
festlegen. - In Spark 3.0 wird beim Einfügen eines Werts in eine Tabellenspalte mit einem anderen Datentyp eine Typumwandlung gemäß ANSI SQL-Standard durchgeführt. Bestimmte unangemessene Typumwandlungen, beispielsweise die Konvertierung von
string
inint
unddouble
inboolean
, sind unzulässig. Es wird eine Laufzeitausnahme ausgelöst, wenn der Wert für den Datentyp der Spalte außerhalb des zulässigen Bereichs liegt. In Spark-Version 2.4 und Vorgängerversionen sind Typkonvertierungen während einer Tabelleneinfügung erlaubt, solange es sich um einen gültigenCast
handelt. Wenn ein Wert, der außerhalb des zulässigen Bereichs liegt, in ein integrales Feld eingefügt wird, werden die niederwertigen Bits des Werts eingefügt (wie bei einer numerischen Java/Scala-Typumwandlung). Wenn beispielsweise der Wert 257 in ein Feld vom Typ „Byte“ eingefügt wird, lautet das Ergebnis 1. Das Verhalten wird durch die Optionspark.sql.storeAssignmentPolicy
gesteuert, wobei der Standardwert „ANSI“ lautet. Durch Festlegen der Option auf „Legacy“ wird das vorherige Verhalten wiederhergestellt. - In Spark 3.0 gibt
SHOW CREATE TABLE
immer Spark-DDL zurück, auch wenn es sich bei der angegebenen Tabelle um eine Hive-SerDe-Tabelle handelt. Verwenden Sie zum Generieren von Hive-DDL stattdessen den BefehlSHOW CREATE TABLE AS SERDE
. - In Spark 3.0 ist eine Spalte des Typs
CHAR
in Nicht-Hive-SerDe-Tabellen unzulässig, undCREATE/ALTER TABLE
-Befehle führen zu einem Fehler, wenn derCHAR
-Typ erkannt wird. Verwenden Sie stattdessen den TypSTRING
. In Spark 2.4 und niedrigeren Versionen wird der TypCHAR
als TypSTRING
behandelt, und der length-Parameter wird einfach ignoriert.
Benutzerdefinierte und integrierte Funktionen
- In Spark 3.0 ist die Verwendung von
org.apache.spark.sql.functions.udf(AnyRef, DataType)
standardmäßig nicht erlaubt. Legen Siespark.sql.legacy.allowUntypedScalaUDF
auftrue
fest, um sie weiterhin zu verwenden. Wennorg.apache.spark.sql.functions.udf(AnyRef, DataType)
in Spark 2.4 und niedriger einen Scala-Funktionsabschluss mit einem Argument eines primitiven Typs abruft, gibt die zurückgegebene benutzerdefinierte Funktion NULL zurück, wenn der Eingabewert NULL lautet. In Spark 3.0 gibt die benutzerdefinierte Funktion dagegen den Standardwert des Java-Typs zurück, wenn der Eingabewert NULL ist. Beispielsweise gibtval f = udf((x: Int) => x, IntegerType), f($"x")
in Spark 2.4 und niedriger NULL zurück, wenn die Spalte x NULL ist, während in Spark 3.0 der Wert 0 zurückgegeben wird. Diese Verhaltensänderung wird eingeführt, da Spark 3.0 standardmäßig mit Scala 2.12 erstellt wird. - In Spark 2.4 und niedrigeren Versionen können Sie eine Zuordnung mit doppelten Schlüsseln über integrierte Funktionen wie
CreateMap
,StringToMap
usw. erstellen. Das Verhalten von „map“ mit doppelten Schlüsseln ist undefiniert, z. B. werden bei einer map-Suche die doppelten Schlüssel zuerst angezeigt, beiDataset.collect
werden die doppelten Schlüssel zuletzt angezeigt,MapKeys
gibt doppelte Schlüssel zurück usw. In Spark 3.0 wird eineRuntimeException
ausgelöst, wenn doppelte Schlüssel gefunden werden. Sie könnenspark.sql.mapKeyDedupPolicy
aufLAST_WIN
festlegen, um map-Schlüssel mit der „last wins“-Richtlinie zu deduplizieren. Benutzer können weiterhin map-Werte mit doppelten Schlüsseln aus Datenquellen lesen, die dies nicht erzwingen (z. B. Parquet), das Verhalten ist undefiniert.
Datenquellen
- In Spark 2.4 und niedrigeren Versionen wird der Wert einer Partitionsspalte in NULL konvertiert, wenn er nicht in ein entsprechendes vom Benutzer bereitgestelltes Schema umgewandelt werden kann. In Spark 3.0 wird der Wert der Partitionsspalte mit einem vom Benutzer angegebenen Schema validiert. Wenn die Validierung fehlschlägt, wird eine Ausnahme ausgelöst. Sie können diese Validierung deaktivieren, indem Sie
spark.sql.sources.validatePartitionColumns
auffalse
festlegen. - Bis zur Spark-Version 2.4 behandelt der Parser der JSON-Datenquelle leere Zeichenfolgen für einige Datentypen wie
IntegerType
als NULL. FürFloatType
,DoubleType
,DateType
undTimestampType
kommt es bei leeren Zeichenfolgen zu einem Fehler, und es werden Ausnahmen ausgelöst. In Spark 3.0 sind leere Zeichenfolgen nicht zulässig, und es werden Ausnahmen für alle Datentypen außerStringType
undBinaryType
ausgelöst. Das frühere Verhalten, eine leere Zeichenfolge zuzulassen, kann wiederhergestellt werden, indemspark.sql.legacy.json.allowEmptyString.enabled
auftrue
festgelegt wird. - Wenn in Spark 3.0 Dateien oder Unterverzeichnisse während der rekursiven Verzeichnisauflistung verschwinden (d. h. sie erscheinen in einer Zwischenauflistung, können jedoch in späteren Phasen der rekursiven Verzeichnisauflistung nicht mehr gelesen oder aufgelistet werden, entweder aufgrund gleichzeitiger Dateilöschungen oder aufgrund von Konsistenzproblemen im Objektspeicher), schlägt die Auflistung mit einer Ausnahme fehl – es sei denn,
spark.sql.files.ignoreMissingFiles
lautettrue
(Standardwert = FALSE). In früheren Versionen wurden diese fehlenden Dateien oder Unterverzeichnisse ignoriert. Beachten Sie, dass diese Verhaltensänderung nur während der anfänglichen Auflistung der Tabellendateien (oder währendREFRESH TABLE
) gilt, nicht während der Abfrageausführung: Die wesentliche Änderung ist, dassspark.sql.files.ignoreMissingFiles
nun während der Auflistung der Tabellendateien und der Abfrageplanung berücksichtigt wird, nicht nur bei der Abfrageausführung. - In Spark 2.4 und Vorgängerversionen konvertiert die CSV-Datenquelle eine falsch formatierte CSV-Zeichenfolge in eine Zeile mit allen NULL-Werten im PERMISSIVE-Modus. In Spark 3.0 kann die zurückgegebene Zeile Nicht-NULL-Felder enthalten, wenn einige der CSV-Spaltenwerte erfolgreich analysiert und in die gewünschten Typen konvertiert wurden.
- In Spark 3.0 wird der logische Parquet-Typ
TIMESTAMP_MICROS
standardmäßig zum Speichern vonTIMESTAMP
-Spalten verwendet. In Spark 2.4 und niedriger werdenTIMESTAMP
-Spalten alsINT96
in Parquet-Dateien gespeichert. Beachten Sie, dass einige SQL-Systeme wie Hive 1.x und Impala 2.x nur INT96-Zeitstempel lesen können. Sie könnenspark.sql.parquet.outputTimestampType
aufINT96
festlegen, um das vorherige Verhalten wiederherzustellen und die Interoperabilität zu erhalten. - Wenn in Spark 3.0 Avro-Dateien mit einem vom Benutzer bereitgestellten Schema geschrieben werden, werden die Felder anstelle von Positionen anhand von Feldnamen zwischen dem catalyst- und dem Avro-Schema abgeglichen.
Abfrage-Engine
- In Spark 3.0 schlägt eine Datasetabfrage fehl, wenn sie einen mehrdeutigen Spaltenverweis enthält, der durch eine Selbstverknüpfung verursacht wird. Ein typisches Beispiel:
val df1 = ...; val df2 = df1.filter(...);, then df1.join(df2, df1("a") > df2("a"))
liefert ein leeres Ergebnis, was ziemlich verwirrend ist. Das liegt daran, dass Spark keine Datasetspaltenverweise auflösen kann, die auf selbstverknüpfte Tabellen zeigen, unddf1("a")
ist in Spark exakt dasselbe wiedf2("a")
. Um das Verhalten vor Spark 3.0 wiederherzustellen, können Siespark.sql.analyzer.failAmbiguousSelfJoin
auffalse
festlegen. - In Spark 3.0 werden Zahlen in wissenschaftlicher Notation (z. B.
1E2
) alsDouble
analysiert. In Spark 2.4 und niedrigeren Versionen werden sie alsDecimal
analysiert. Um das Verhalten vor Spark 3.0 wiederherzustellen, können Siespark.sql.legacy.exponentLiteralAsDecimal.enabled
auftrue
festlegen. - In Spark 3.0 wird die Konfiguration
spark.sql.crossJoin.enabled
zu einer internen Konfiguration und ist standardmäßig auf TRUE festgelegt. Spark löst in der Standardeinstellung keine Ausnahmen für SQL mit impliziten Kreuzverknüpfungen aus. - In Spark 2.4 und niedrigeren Versionen entspricht „float/double -0.0“ semantisch 0.0, aber -0.0 und 0.0 werden als unterschiedliche Werte betrachtet, wenn sie in Aggregatgruppierungsschlüsseln, Fensterpartitionsschlüsseln und Joinschlüsseln verwendet werden. In Spark 3.0 wurde dieser Fehler behoben. Zum Beispiel gibt
Seq(-0.0, 0.0).toDF("d").groupBy("d").count()
in Spark 3.0[(0.0, 2)]
und in Spark 2.4 und niedrigeren Versionen[(0.0, 1), (-0.0, 1)]
zurück. - In Spark 3.0 werden
TIMESTAMP
-Literale unter Verwendung der SQL-Konfigurationspark.sql.session.timeZone
in Zeichenfolgen umgewandelt. In Spark 2.4 und Vorgängerversionen wird bei der Konvertierung die Standardzeitzone der Java-VM verwendet. - In Spark 3.0 wird in binären Vergleichen mit Datumswerten/Zeitstempeln
String
inDate/Timestamp
umgewandelt. Das vorherige Verhalten der Umwandlung vonDate/Timestamp
inString
kann wiederhergestellt werden, indem Siespark.sql.legacy.typeCoercion.datetimeToString.enabled
auftrue
festlegen. - In Spark 2.4 und niedriger werden ungültige Zeitzonen-IDs automatisch ignoriert und durch GMT-Zeitzone ersetzt, z. B. in der
from_utc_timestamp
-Funktion. In Spark 3.0 werden solche Zeitzonen-IDs abgelehnt, und Spark löst einejava.time.DateTimeException
aus. - In Spark 3.0 wird der proleptische gregorianische Kalender beim Analysieren, Formatieren und Konvertieren von Daten und Zeitstempeln sowie beim Extrahieren von Unterkomponenten wie Jahren, Tagen usw. verwendet. Spark 3.0 verwendet Java 8-API-Klassen aus den java.time-Paketen, die auf ISO-Chronologie basieren. In Spark 2.4 und Vorgängerversionen werden diese Vorgänge mithilfe des Hybridkalenders (Julianisch + Gregorianisch) ausgeführt. Die Änderungen wirken sich auf die Ergebnisse für Datumsangaben vor dem 15. Oktober 1582 (gregorianisch) aus und betreffen die folgende Spark 3.0-API:
- Analyse/Formatierung von Zeitstempeln/Datumszeichenfolgen. Dies wirkt sich auf CSV/JSON-Datenquellen und auf die Funktionen
unix_timestamp
,date_format
,to_unix_timestamp
,from_unixtime
,to_date
,to_timestamp
aus, wenn vom Benutzer angegebene Muster für Analyse und Formatierung verwendet werden. In Spark 3.0 werden eigene Musterzeichenfolgen insql-ref-datetime-pattern.md
definiert, die im Hintergrund überjava.time.format.DateTimeFormatter
implementiert werden. Die neue Implementierung führt eine strenge Überprüfung der zugehörigen Eingabe durch. Zum Beispiel kann der Zeitstempel2015-07-22 10:00:00
nicht analysiert werden, wenn das Musteryyyy-MM-dd
lautet, da der Parser nicht die gesamte Eingabe verarbeitet. Ein weiteres Beispiel: Die31/01/2015 00:00
-Eingabe kann nicht anhand des Mustersdd/MM/yyyy hh:mm
analysiert werden, weilhh
Stunden im Bereich 1–12 voraussetzt. In Spark 2.4 und Vorgängerversionen wirdjava.text.SimpleDateFormat
für die Konvertierung von Zeitstempeln/Datumszeichenfolgen verwendet, und die unterstützten Muster sind in simpleDateFormat beschrieben. Das vorherige Verhalten kann wiederhergestellt werden, indem Siespark.sql.legacy.timeParserPolicy
aufLEGACY
festlegen. - Die Funktionen
weekofyear
,weekday
,dayofweek
,date_trunc
,from_utc_timestamp
,to_utc_timestamp
undunix_timestamp
verwenden diejava.time
-API zur Berechnung der Wochennummer des Jahres, der Wochentagsnummer sowie zur Konvertierung aus bzw. inTimestampType
-Werte in der UTC-Zeitzone. - Die JDBC-Optionen
lowerBound
undupperBound
werden auf die gleiche Weise in TimestampType/DateType-Werte umgewandelt wie bei der Umwandlung von Zeichenfolgen in TimestampType/DateType-Werte. Die Konvertierung basiert auf dem proleptischen gregorianischen Kalender und der Zeitzone, die in der SQL-Konfigurationspark.sql.session.timeZone
definiert ist. In Spark 2.4 und Vorgängerversionen basiert die Konvertierung auf dem Hybridkalender (Julianisch + Gregorianisch) und auf der Standardzeitzone des Systems. - Formatierung von
TIMESTAMP
undDATE
-Literalen. - Erstellen von typisierten
TIMESTAMP
- undDATE
-Literalen aus Zeichenfolgen. In Spark 3.0 erfolgt die Zeichenfolgenkonvertierung in typisierteTIMESTAMP/DATE
-Literale durch eine Umwandlung inTIMESTAMP/DATE
-Werte. Zum Beispiel entsprichtTIMESTAMP '2019-12-23 12:59:30'
semantischCAST('2019-12-23 12:59:30' AS TIMESTAMP)
. Falls die Eingabezeichenfolge keine Informationen über die Zeitzone enthält, wird die Zeitzone aus der SQL-Konfigurationspark.sql.session.timeZone
verwendet. In Spark 2.4 und niedrigeren Versionen basiert die Konvertierung auf der JVM-Systemzeitzone. Die verschiedenen Quellen der Standardzeitzone können das Verhalten von typisiertenTIMESTAMP
- undDATE
-Literalen ändern.
- Analyse/Formatierung von Zeitstempeln/Datumszeichenfolgen. Dies wirkt sich auf CSV/JSON-Datenquellen und auf die Funktionen
Apache Hive
- In Spark 3.0 wurde die integrierte Hive-Version von 1.2 auf 2.3 aktualisiert, was sich wie folgt auswirkt:
- Möglicherweise müssen Sie
spark.sql.hive.metastore.version
undspark.sql.hive.metastore.jars
gemäß der Version des Hive-Metastores festlegen, mit dem Sie eine Verbindung herstellen möchten. Beispiel: Legen Siespark.sql.hive.metastore.version
auf1.2.1
undspark.sql.hive.metastore.jars
aufmaven
fest, wenn Ihre Hive-Metastore-Version 1.2.1 ist. - Sie müssen Ihre benutzerdefinierten SerDe-Implementierungen zu Hive 2.3 migrieren oder einen eigenen Spark mit Profil
hive-1.2
erstellen. Weitere Informationen finden Sie unter HIVE-15167. - Die dezimale Zeichenfolgendarstellung kann zwischen Hive 1.2 und Hive 2.3 unterschiedlich sein, wenn der
TRANSFORM
-Operator in SQL für die Skripttransformation verwendet wird, was vom Verhalten von Hive abhängt. In Hive 1.2 werden bei der Zeichenfolgendarstellung die Nullen am Ende weggelassen. In Hive 2.3 dagegen wird immer auf 18 Stellen aufgefüllt, gegebenenfalls mit nachgestellten Nullen. - In Databricks Runtime 7.x untersagt Spark beim Lesen einer Hive-SerDe-Tabelle standardmäßig das Lesen von Dateien unterhalb eines Unterverzeichnisses, das keine Tabellenpartition ist. Legen Sie zur Aktivierung die Konfiguration
spark.databricks.io.hive.scanNonpartitionedDirectory.enabled
auftrue
fest. Dies wirkt sich nicht auf native Spark-Tabellenleser und -Dateileser aus.
- Möglicherweise müssen Sie
MLlib
- Das in Version 2.3 als veraltet eingestufte
OneHotEncoder
wird in Version 3.0 entfernt, undOneHotEncoderEstimator
wird inOneHotEncoder
umbenannt. - Das in Version 2.3 als veraltet eingestufte
org.apache.spark.ml.image.ImageSchema.readImages
wird in Version 3.0 entfernt. Verwenden Sie stattdessenspark.read.format('image')
. org.apache.spark.mllib.clustering.KMeans.train
mit „param Intruns
“, das in Version 2.1 als veraltet eingestuft wurde, wird in Version 3.0 entfernt. Verwenden Sie stattdessen die train-Methode ohne „runs“.- Das in Version 2.0 als veraltet eingestufte
org.apache.spark.mllib.classification.LogisticRegressionWithSGD
wird in Version 3.0 entfernt. Verwenden Sie stattdessenorg.apache.spark.ml.classification.LogisticRegression
oderspark.mllib.classification.LogisticRegressionWithLBFGS
. - Das in Version 2.1 als veraltet eingestufte und in Version 3.0 entfernte
org.apache.spark.mllib.feature.ChiSqSelectorModel.isSorted
ist nicht für die Verwendung durch Unterklassen gedacht. - Das in Version 2.0 als veraltet eingestufte
org.apache.spark.mllib.regression.RidgeRegressionWithSGD
wird in Version 3.0 entfernt. Verwenden Sieorg.apache.spark.ml.regression.LinearRegression
mitelasticNetParam = 0.0
. Hinweis: DerregParam
-Standardwert fürRidgeRegressionWithSGD
lautet 0.01, aber 0.0 fürLinearRegression
. - Das in Version 2.0 als veraltet eingestufte
org.apache.spark.mllib.regression.LassoWithSGD
wird in Version 3.0 entfernt. Verwenden Sieorg.apache.spark.ml.regression.LinearRegression
mitelasticNetParam = 1.0
. Hinweis: DerregParam
-Standardwert fürLassoWithSGD
lautet 0.01, aber 0.0 fürLinearRegression
. - Das in Version 2.0 als veraltet eingestufte
org.apache.spark.mllib.regression.LinearRegressionWithSGD
wird in Version 3.0 entfernt. Verwenden Sie stattdessenorg.apache.spark.ml.regression.LinearRegression
oderLBFGS
. org.apache.spark.mllib.clustering.KMeans.getRuns
undsetRuns
, die in Version 2.1 als veraltet eingestuft und in Version 3.0 entfernt wurden, haben seit Spark 2.0.0 keine Auswirkungen mehr.- Das in Version 2.4 als veraltet eingestufte und in Version 3.0 entfernte
org.apache.spark.ml.LinearSVCModel.setWeightCol
ist nicht für Benutzer gedacht. - In Version 3.0 wird
org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel
aufMultilayerPerceptronParams
erweitert, um die Trainingsparameter verfügbar zu machen. Als Ergebnis wurdelayers
inMultilayerPerceptronClassificationModel
vonArray[Int]
inIntArrayParam
geändert. Verwenden SieMultilayerPerceptronClassificationModel.getLayers
anstelle vonMultilayerPerceptronClassificationModel.layers
, um die layer-Größe abzurufen. - Das in Version 2.4.5 als veraltet eingestufte
org.apache.spark.ml.classification.GBTClassifier.numTrees
wird in Version 3.0 entfernt. Verwenden Sie stattdessengetNumTrees
. - Das in Version 2.4 als veraltet eingestufte
org.apache.spark.ml.clustering.KMeansModel.computeCost
wird in Version 3.0 entfernt. Verwenden Sie stattdessenClusteringEvaluator
. - Die in Version 2.0 als veraltet eingestufte Membervariable „precision“ in
org.apache.spark.mllib.evaluation.MulticlassMetrics
wird in Version 3.0 entfernt. Verwenden Sie stattdessen „accuracy“. - Die in Version 2.0 als veraltet eingestufte Membervariable „recall“ in
org.apache.spark.mllib.evaluation.MulticlassMetrics
wird in Version 3.0 entfernt. Verwenden Sie stattdessenaccuracy
. - Die in Version 2.0 als veraltet eingestufte Membervariable
fMeasure
inorg.apache.spark.mllib.evaluation.MulticlassMetrics
wird in Version 3.0 entfernt. Verwenden Sie stattdessenaccuracy
. - Das in Version 2.0 als veraltet eingestufte
org.apache.spark.ml.util.GeneralMLWriter.context
wird in Version 3.0 entfernt. Verwenden Sie stattdessensession
. - Das in Version 2.0 als veraltet eingestufte
org.apache.spark.ml.util.MLWriter.context
wird in Version 3.0 entfernt. Verwenden Sie stattdessensession
. - Das in Version 2.0 als veraltet eingestufte
org.apache.spark.ml.util.MLReader.context
wird in Version 3.0 entfernt. Verwenden Sie stattdessensession
. abstract class UnaryTransformer[IN, OUT, T <: UnaryTransformer[IN, OUT, T]]
wird in Version 3.0 inabstract class UnaryTransformer[IN: TypeTag, OUT: TypeTag, T <: UnaryTransformer[IN, OUT, T]]
geändert.- In Spark 3.0 gibt eine logistische Regression mit mehreren Klassen in Pyspark jetzt (ordnungsgemäß)
LogisticRegressionSummary
und nicht die UnterklasseBinaryLogisticRegressionSummary
zurück. Die zusätzlichen Methoden, die überBinaryLogisticRegressionSummary
verfügbar gemacht werden, würden in diesem Fall ohnehin nicht funktionieren. (SPARK-31681) - In Spark 3.0 stellen
pyspark.ml.param.shared.Has*
-Mixins keineset*(self, value)
-Setter-Methoden mehr zur Verfügung, sondern verwenden stattdessen den jeweiligenself.set(self.*, value)
. Weitere Informationen finden Sie unter SPARK-29093. (SPARK-29093)
Andere Verhaltensänderungen
Das Upgrade auf Scala 2.12 umfasst die folgenden Änderungen:
Die Serialisierung von Paketzellen wird anders verarbeitet. Das folgende Beispiel veranschaulicht die Verhaltensänderung und deren Handhabung.
Die Ausführung von
foo.bar.MyObjectInPackageCell.run()
, wie in der folgenden Paketzelle definiert, löst den Fehlerjava.lang.NoClassDefFoundError: Could not initialize class foo.bar.MyObjectInPackageCell$
aus.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) } }
Um diesen Fehler zu umgehen, können Sie
MyObjectInPackageCell
in eine serialisierbare Klasse einschließen.In bestimmten Fällen, in denen
DataStreamWriter.foreachBatch
verwendet wird, ist eine Aktualisierung des Quellcodes erforderlich. Diese Änderung ist auf die Tatsache zurückzuführen, dass Scala 2.12 eine automatische Konvertierung von Lambda-Ausdrücken in SAM-Typen durchführt, was zu Mehrdeutigkeiten führen kann.Beispielsweise kann der folgende Scala-Code nicht kompiliert werden:
streams .writeStream .foreachBatch { (df, id) => myFunc(df, id) }
Um den Kompilierungsfehler zu beheben, ändern Sie
foreachBatch { (df, id) => myFunc(df, id) }
inforeachBatch(myFunc _)
, oder verwenden Sie explizit die Java-API:foreachBatch(new VoidFunction2 ...)
.
Da die Apache Hive-Version, die für die Verarbeitung von benutzerdefinierten Hive-Funktionen und Hive-SerDe-Implementierungen verwendet wird, auf 2.3 aktualisiert wurde, sind zwei Änderungen erforderlich:
- Die Hive-Schnittstelle
SerDe
wird durch eine abstrakte KlasseAbstractSerDe
ersetzt. Für jede benutzerdefinierte Hive-SerDe
-Implementierung ist eine Migration zuAbstractSerDe
erforderlich. - Die Festlegung von
spark.sql.hive.metastore.jars
aufbuiltin
bedeutet, dass der Hive 2.3-Metastore-Client für den Zugriff auf Metastores für Databricks Runtime 7.x verwendet wird. Wenn Sie auf Hive 1.2-basierte externe Metastores zugreifen müssen, legen Siespark.sql.hive.metastore.jars
auf den Ordner fest, der Hive 1.2-JARs enthält.
- Die Hive-Schnittstelle
Veraltete und entfernte Funktionen
- DATASKIPPING INDEX wurde in Databricks Runtime 4.3 als veraltet eingestuft und in Databricks Runtime 7.x entfernt. Es wird empfohlen, stattdessen Delta-Tabellen zu verwenden, die verbesserte Funktionen zum Überspringen von Daten bieten.
- In Databricks Runtime 7.x verwendet die zugrunde liegende Version Apache Spark Scala 2.12. Da mit Scala 2.11 kompilierte Bibliotheken Databricks Runtime 7.x-Cluster auf unerwartete Weise deaktivieren können, installieren Cluster, auf denen Databricks Runtime 7.x ausgeführt wird, keine Bibliotheken, die zur Installation in allen Clustern konfiguriert sind. Die Registerkarte „Bibliotheken“ für eine Clusters zeigt den Status
Skipped
und eine Meldung an, in der die Änderungen bezüglich der Handhabung von Bibliotheken erläutert werden. Wenn Sie jedoch über einen Cluster verfügen, der mit einer Vorgängerversion von Databricks Runtime erstellt wurde, bevor Version 3.20 der Azure Databricks-Plattform für Ihren Arbeitsbereich veröffentlicht wurde, und Sie diesen Cluster jetzt bearbeiten, um Databricks Runtime 7.x zu verwenden, werden alle Bibliotheken, die für die Installation in allen Clustern konfiguriert wurden, auf diesem Cluster installiert. In diesem Fall können inkompatible JARs in den installierten Bibliotheken dazu führen, dass der Cluster deaktiviert wird. Die Problemumgehung besteht darin, entweder den Cluster zu klonen oder einen neuen Cluster zu erstellen.
Bekannte Probleme
- Die Analyse des Tages des Jahres mit dem Buchstaben „D“ liefert ein falsches Ergebnis, wenn das Jahresfeld fehlt. Dies kann in SQL-Funktionen wie
to_timestamp
auftreten, die datetime-Zeichenfolgen mithilfe einer Musterzeichenfolge in datetime-Werte analysieren. (SPARK-31939) - Join-/Fenster-/Aggregatschlüssel innerhalb von Unterabfragen können zu falschen Ergebnissen führen, wenn die Schlüssel die Werte -0.0 und 0.0 aufweisen. (SPARK-31958)
- Eine Fensterabfrage kann mit einem mehrdeutigen Selbstverknüpfungsfehler unerwartet fehlschlagen. (SPARK-31956)
- Streamingabfragen mit
dropDuplicates
-Operator können möglicherweise nicht mit dem von Spark 2.x geschriebenen Prüfpunkt neu gestartet werden. (SPARK-31990)