Compartilhar via


Guia de migração para o Databricks Runtime 7.x (EoS)

Observação

O suporte para esta versão do Databricks Runtime foi encerrado. Para obter a data de fim do suporte, consulte o Histórico de fim do suporte. Para ver todas as versões compatíveis do Databricks Runtime, consulte Versões de notas de versão do Databricks Runtime e compatibilidade.

Este guia fornece orientação para ajudá-lo a migrar suas cargas de trabalho do Azure Databricks do Databricks Runtime 6.x, criado no Apache Spark 2.4, para o Databricks Runtime 7.3 LTS (EoS), ambos criados no Spark 3.0.

Este guia lista as alterações de comportamento do Spark 3.0 que podem exigir que você atualize as cargas de trabalho do Azure Databricks. Algumas dessas alterações incluem a remoção completa do suporte ao Python 2, a atualização para o Scala 2.12, o suporte completo ao JDK 11 e a mudança do calendário gregoriano para o proléptico em datas e carimbos de data/hora.

Este guia é um complemento do guia de migração do Databricks Runtime 7.3 LTS (EoS).

Novos recursos e aprimoramentos disponíveis no Databricks Runtime 7.x

Para obter uma lista de novos recursos, melhorias e atualizações de biblioteca incluídos no Databricks Runtime 7.3 LTS, consulte as notas sobre a versão de cada versão do Databricks Runtime acima daquela da qual você está migrando. As versões do Databricks Runtime 7.x com suporte incluem:

As atualizações de manutenção pós-lançamento são listadas nas Atualizações de Manutenção do Databricks Runtime (arquivado).

Ambiente do sistema Databricks Runtime 7.3 LTS

  • Sistema operacional: 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

Principais alterações de comportamento do Apache Spark 3.0

As alterações de comportamento a seguir do Spark 2.4 para o Spark 3.0 podem exigir que você atualize cargas de trabalho do Azure Databricks na migração do Databricks Runtime 6.x para o Databricks Runtime 7.x.

Observação

Este artigo fornece uma lista das alterações de comportamento do Spark importantes que você deve considerar ao migrar para o Databricks Runtime 7.x.

Núcleo

  • No Spark 3.0, o acumulador v1 preterido foi removido.
  • O arquivo de log de eventos será gravado como codificação UTF-8 e o Servidor de Histórico do Spark repetirá os arquivos de log de eventos como codificação UTF-8. Anteriormente, o Spark gravava o arquivo de log de eventos como um conjunto de caracteres padrão do processo de JVM do driver e, portanto, o Servidor de Histórico do Spark 2.x é necessário para ler os arquivos de log de eventos antigos em caso de codificação incompatível.
  • Um novo protocolo para buscar blocos de ordem aleatória é usado. É recomendável que os serviços de embaralhamento externos sejam atualizados na execução de aplicativos Spark 3.0. Você ainda pode usar serviços de embaralhamento externos antigos quando define a configuração spark.shuffle.useOldFetchProtocol como true. Caso contrário, o Spark poderá ter erros com mensagens como IllegalArgumentException: Unexpected message type: <number>.

PySpark

  • No Spark 3.0, Column.getItem corrigido de forma a não chamar Column.apply. Consequentemente, se Column for usado como um argumento para getItem, o operador de indexação deverá ser usado. Por exemplo, map_col.getItem(col('id')) deve ser substituído por map_col[col('id')].
  • A partir do Spark 3.0, os nomes de campo de Row não são mais classificados por ordem alfabética na construção com argumentos nomeados para as versões 3.6 e superiores do Python, e a ordem dos campos corresponderá à que foi inserida. Para habilitar campos classificados por padrão, como no Spark 2.4, defina a variável de ambiente PYSPARK_ROW_FIELD_SORTING_ENABLED como true para executores e driver. Essa variável de ambiente precisa ser consistente para todos os executores e driver. Caso contrário, poderá causar falhas ou respostas incorretas. Para versões do Python inferiores à 3.6, os nomes de campo são classificados em ordem alfabética como a única opção.
  • Suporte ao Python 2 preterido (SPARK-27884).

Streaming estruturado

  • No Spark 3.0, o Streaming Estruturado força a anulabilidade do esquema de origem quando fontes de dados baseadas em arquivos como texto, json, csv, parquet e orc são usadas por meio de spark.readStream(...). Anteriormente, ele respeitava a nulidade no esquema de origem; no entanto, isso causou problemas complicados na depuração com o NPE. Para restaurar o comportamento anterior, defina spark.sql.streaming.fileSource.schema.forceNullable como false.
  • O Spark 3.0 corrige o problema de exatidão na junção externa stream-stream, o que altera o esquema do estado. Confira SPARK-26154 para obter mais detalhes. Se você iniciar a consulta do ponto de verificação construído pelo Spark 2.x que usa a junção externa stream-stream, o Spark 3.0 falhará na consulta. Para recalcular saídas, descarte o ponto de verificação e reproduza as entradas anteriores.
  • No Spark 3.0, a classe preterida org.apache.spark.sql.streaming.ProcessingTime foi removida. Use org.apache.spark.sql.streaming.Trigger.ProcessingTime em vez disso. Da mesma forma, org.apache.spark.sql.execution.streaming.continuous.ContinuousTrigger foi removido em favor de Trigger.Continuous e org.apache.spark.sql.execution.streaming.OneTimeTrigger foi ocultado em favor de Trigger.Once. Confira SPARK-28199.

SQL, conjuntos de dados e DataFrame

  • No Spark 3.0, ao inserir um valor em uma coluna de tabela com um tipo de dados diferente, a coerção de tipo será executada de acordo com o padrão de SQL ANSI. Algumas conversões de tipo inaceitável, como a conversão string de int e double para boolean, não são permitidas. Uma exceção de runtime será lançada se o valor estiver fora do intervalo para o tipo de dados da coluna. No Spark versão 2.4 e anteriores, as conversões de tipo durante a inserção da tabela são permitidas, desde que sejam Cast válidas. Ao inserir um valor fora do intervalo em um campo integral, os bits de ordem inferior do valor serão inseridos (igual à conversão de tipo numérico Java/Scala). Por exemplo, se 257 for inserido em um campo de tipo de byte, o resultado será 1. O comportamento é controlado pela opção spark.sql.storeAssignmentPolicy, com um valor padrão como “ANSI”. A configuração da opção como “Herdada” restaura o comportamento anterior.
  • No Spark 3.0, ao converter o valor da cadeia de caracteres em tipos integrais (tinyint, smallint, int e bigint), tipos datetime (date, timestamp e interval) e tipo booliano, os espaços em branco à frente e à direita (<= ACSII 32) serão cortados antes de serem convertidos nesses valores de tipo, por exemplo, cast(' 1\t' as int) retorna 1, cast(' 1\t' as boolean) retorna true, cast('2019-10-10\t as date) retorna o valor de data 2019-10-10. No Spark versão 2.4 e anteriores, ao fazer a transmissão de cadeia de caracteres para integrais e boolianos, ele não cortará os espaços em branco de ambas as extremidades. Os resultados anteriores serão null; já para datetimes, somente os espaços à direita (= ASCII 32) serão removidos. Consulte https://databricks.com/blog/2020/07/22/a-comprehensive-look-at-dates-and-timestamps-in-apache-spark-3-0.html.
  • No Spark 3.0, os métodos preteridos SQLContext.createExternalTable e SparkSession.createExternalTable foram preteridos em favor de sua substituição, createTable.
  • No Spark 3.0, spark.sql.crossJoin.enabled de configuração se torna configuração interna e isso é verdadeiro por padrão, ou seja, por padrão, o Spark não lançará uma exceção no SQL com uniões cruzadas implícitas.
  • No Spark 3.0, invertemos a ordem do argumento da função trim de TRIM(trimStr, str) para TRIM(str, trimStr) a fim de deixá-lo compatível com outros bancos de dados.
  • No Spark versão 2.4 e anteriores, as consultas SQL, por exemplo, FROM <table> ou FROM <table> UNION ALL FROM <table>, têm suporte acidentalmente. No estilo do FROM <table> SELECT <expr> do Hive, a cláusula SELECT não é insignificante. O Hive e o Presto não dão suporte a essa sintaxe. Portanto, trataremos essas consultas como inválidas a partir do Spark 3.0.
  • Desde o Spark 3.0, o Conjunto de dados e a API DataFrame unionAll não foram mais preteridos. É um alias para union.
  • No Spark versão 2.4 e anteriores, o analisador da fonte de dados JSON trata cadeias de caracteres vazias como nulas para alguns tipos de dados, como IntegerType. Para FloatType e DoubleType, ele falha em cadeias de caracteres vazias e lança exceções. Desde o Spark 3.0, não podemos permitir cadeias de caracteres vazias e lançamos exceções para tipos de dados que não sejam StringType e BinaryType.
  • Desde o Spark 3.0, as funções from_json dão suporte a dois modos: PERMISSIVE e FAILFAST. Os modos podem ser definidos por meio da opção mode. O modo padrão se tornou PERMISSIVE. Nas versões anteriores, o comportamento de from_json não estava em conformidade com PERMISSIVE nem com FAILFAST,, especialmente no processamento de registros JSON malformados. Por exemplo, a cadeia de caracteres JSON {"a" 1} com o esquema a INT é convertida em null por versões anteriores, mas o Spark 3.0 a converte em Row(null).

Instruções DDL

  • No Spark 3.0, CREATE TABLE sem um provedor específico usa o valor de spark.sql.sources.default como seu provedor. No Spark versão 2.4 e inferior, era o Hive. Para restaurar o comportamento antes do Spark 3.0, você pode definir spark.sql.legacy.createHiveTableByDefault.enabled como true.
  • No Spark 3.0, ao inserir um valor em uma coluna de tabela com um tipo de dados diferente, a coerção de tipo será executada de acordo com o padrão de SQL ANSI. Algumas conversões de tipo inaceitável, como a conversão string de int e double para boolean, não são permitidas. Uma exceção de runtime é lançada se o valor está fora do intervalo para o tipo de dados da coluna. No Spark versão 2.4 e inferiores, as conversões de tipo durante a inserção da tabela são permitidas, desde que sejam Cast válidas. Ao inserir um valor fora do intervalo em um campo integral, os bits de ordem inferior do valor serão inseridos (igual à conversão de tipo numérico Java/Scala). Por exemplo, se 257 for inserido em um campo de tipo de byte, o resultado será 1. O comportamento é controlado pela opção spark.sql.storeAssignmentPolicy, com um valor padrão como “ANSI”. A configuração da opção como “Herdada” restaura o comportamento anterior.
  • No Spark 3.0, SHOW CREATE TABLE sempre retorna a DDL do Spark, mesmo quando a tabela fornecida é uma tabela SerDe do Hive. Para gerar o DDL do Hive, use o comando SHOW CREATE TABLE AS SERDE.
  • No Spark 3,0, a coluna do tipo CHAR não é permitida em tabelas non-Hive-Serde, e os comandos CREATE/ALTER TABLE falharão se o tipo CHAR for detectado. Use o tipo STRING. No Spark versão 2.4 e inferiores, o tipo CHAR é tratado como o tipo STRING e o parâmetro de comprimento é simplesmente ignorado.

UDFs e funções internas

  • No Spark 3.0, o uso de org.apache.spark.sql.functions.udf(AnyRef, DataType) não é permitido por padrão. Defina spark.sql.legacy.allowUntypedScalaUDF como true para continuar a usá-lo. No Spark versão 2.4 e inferior, se org.apache.spark.sql.functions.udf(AnyRef, DataType) obtiver um fechamento Scala com um argumento de tipo primitivo, o UDF retornado retornará nulo se os valores de entrada forem nulos. No entanto, no Spark 3.0, o UDF retornará o valor padrão do tipo Java se o valor de entrada for nulo. Por exemplo, val f = udf((x: Int) => x, IntegerType), f($"x") retorna NULL no Spark 2.4 e versões inferiores se a coluna x é nula e retorna 0 no Spark 3.0. Essa alteração de comportamento foi introduzida porque o Spark 3.0 foi criado com Scala 2.12 por padrão.
  • No Spark versão 2.4 e inferiores, você pode criar um mapa com chaves duplicadas por meio de funções internas, por exemplo, CreateMap, StringToMap, etc. O comportamento do mapa com chaves duplicadas é indefinido, por exemplo, a pesquisa de mapa respeita que a chave duplicada aparecerá primeiro, Dataset.collect mantém apenas a chave duplicada exibida por último, MapKeys retorna chaves duplicadas, etc. No Spark 3.0, o Spark lança RuntimeException quando são encontradas chaves duplicadas. Você pode definir spark.sql.mapKeyDedupPolicy como LAST_WIN para eliminar a duplicação de chaves de mapa com a última política do WINS. Os usuários ainda podem ler valores de mapa com chaves duplicadas de fontes de dados que não a impõem (por exemplo, Parquet); o comportamento é indefinido.

Fontes de dados

  • No Spark versão 2.4 e inferiores, o valor da coluna de partição será convertido como null se não puder ser convertido em um esquema fornecido pelo usuário correspondente. No 3.0, o valor da coluna de partição é validado com um esquema fornecido pelo usuário. Uma exceção será gerada se a validação falhar. Você pode desabilitar essa validação definindo spark.sql.sources.validatePartitionColumns como false.
  • No Spark versão 2.4 e inferiores, o analisador da fonte de dados JSON trata cadeias de caracteres vazias como nulas para alguns tipos de dados, como IntegerType. Para FloatType, DoubleType, DateType e TimestampType, ele falha em cadeias de caracteres vazias e lança exceções. O Spark 3.0 não permite cadeias de caracteres vazias e gerará uma exceção para tipos de dados, exceto para StringType e BinaryType. O comportamento anterior de permitir uma cadeia de caracteres vazia pode ser restaurado com a definição de spark.sql.legacy.json.allowEmptyString.enabled como true.
  • No Spark 3.0, se os arquivos ou subdiretórios desaparecerem durante a listagem de diretório recursivo (ou seja, eles aparecerem em uma listagem intermediária, mas não puderem ser lidos ou listados durante as fases posteriores da listagem de diretório recursivo devido a exclusões de arquivo simultâneas ou a problemas de consistência de repositório de objetos), a listagem falhará com uma exceção, a menos que spark.sql.files.ignoreMissingFiles seja true (o padrão é falso). Em versões anteriores, esses arquivos ou subdiretórios ausentes seriam ignorados. Observe que essa alteração de comportamento só se aplica durante a listagem inicial do arquivo de tabela (ou durante REFRESH TABLE), não durante a execução da consulta: a alteração real é que spark.sql.files.ignoreMissingFiles agora é obedecido durante a listagem de arquivos de tabela e o planejamento de consultas, não apenas no tempo de execução da consulta.
  • No Spark versão 2.4 e inferiores, a fonte de dados CSV converte uma cadeia de caracteres CSV malformada em uma linha com todos os valores nulos no modo PERMISSIVO. No Spark 3.0, a linha retornada pode conter campos não nulos se alguns valores de coluna CSV foram analisados e convertidos em tipos desejados com êxito.
  • No Spark 3.0, o tipo lógico do Parquet TIMESTAMP_MICROS é usado por padrão ao salvar colunas TIMESTAMP. No Spark versão 2.4 e inferiores, as colunas TIMESTAMP são salvas como INT96 em arquivos Parquet. Observe que alguns sistemas SQL, como o Hive 1.x e o Impala 2.x, só podem ler carimbos de data/hora INT96. Você pode definir spark.sql.parquet.outputTimestampType como INT96 para restaurar o comportamento anterior e manter a interoperabilidade.
  • No Spark 3.0, quando os arquivos Avro são gravados com o esquema fornecido pelo usuário, os campos fazem correspondência pelos nomes de campo entre o esquema Catalyst e o esquema Avro em vez de posições.

Mecanismo de consulta

  • No Spark 3.0, a consulta de conjunto de dados falha se contém referência de coluna ambígua causada por autojunção. Um exemplo típico: val df1 = ...; val df2 = df1.filter(...);, then df1.join(df2, df1("a") > df2("a")) retorna um resultado vazio, o que é bastante confuso. Isso ocorre porque o Spark não pode resolver referências de coluna de conjunto de dados que apontam para tabelas que estão sendo unidas automaticamente, e df1("a") é exatamente o mesmo que df2("a") no Spark. Para restaurar o comportamento antes do Spark 3.0, você pode definir spark.sql.analyzer.failAmbiguousSelfJoin como false.
  • No Spark 3.0, os números escritos em notação científica (por exemplo, 1E2) são analisados como Double. No Spark versão 2.4 e inferiores, eles são analisados como Decimal. Para restaurar o comportamento antes do Spark 3.0, você pode definir spark.sql.legacy.exponentLiteralAsDecimal.enabled como true.
  • No Spark 3.0, a configuração spark.sql.crossJoin.enabled se torna uma configuração interna e é verdadeira por padrão. Por padrão, o Spark não lançará exceções no SQL com uniões cruzadas implícitas.
  • No Spark versão 2.4 e inferior, float/double -0,0 é semanticamente igual a 0,0, mas -0,0 e 0,0 são considerados valores diferentes quando usados em chaves de agrupamento agregado, chaves de partição de janela e chaves de junção. No Spark 3.0, esse bug foi corrigido. Por exemplo, Seq(-0.0, 0.0).toDF("d").groupBy("d").count() retorna [(0.0, 2)] no Spark 3.0 e [(0.0, 1), (-0.0, 1)] no Spark 2.4 e versões inferiores.
  • No Spark 3.0, os literais TIMESTAMP são convertidos em cadeias de caracteres usando a configuração SQL spark.sql.session.timeZone. No Spark versão 2.4 e versões inferiores, a conversão usa o fuso horário padrão da máquina virtual Java.
  • No Spark 3.0, o Spark converte String em Date/Timestamp em comparações binárias com datas/carimbos de data/hora. O comportamento anterior de converter Date/Timestamp em String pode ser restaurado pela definição de spark.sql.legacy.typeCoercion.datetimeToString.enabled como true.
  • No Spark versão 2.4 e inferiores, os IDs de fuso horário inválidos são silenciosamente ignorados e substituídos pelo fuso horário GMT, por exemplo, na função from_utc_timestamp. No Spark 3.0, esses IDs de fuso horário são rejeitados e o Spark lança java.time.DateTimeException.
  • No Spark 3.0, o calendário gregoriano proléptico é usado na análise, na formatação e na conversão de datas e carimbos de data/hora, bem como na extração de subcomponentes, como anos, dias e assim por diante. O Spark 3.0 usa classes de API Java 8 de pacotes java.time baseados na cronologia ISO. No Spark versão 2.4 e inferiores, essas operações são executadas usando o calendário híbrido (juliano + gregoriano). As alterações afetam os resultados de datas antes de 15 de outubro de 1582 (gregoriano) e afetam a seguinte API do Spark 3.0:
    • Análise/formatação de cadeias de caracteres de data/carimbo de data/hora. Esses efeitos em fontes de dados CSV/JSON e nas funções unix_timestamp, date_format, to_unix_timestamp, from_unixtime, to_date, to_timestamp quando os padrões especificados por usuários são usados para análise e formatação. No Spark 3.0, definimos nossas próprias cadeias de caracteres de padrão em sql-ref-datetime-pattern.md, que é implementada por meio de java.time.format.DateTimeFormatter nos bastidores. A nova implementação executa uma verificação estrita da sua entrada. Por exemplo, o carimbo de data/hora 2015-07-22 10:00:00 não poderá ser analisado se o padrão for yyyy-MM-dd porque o analisador não consome uma entrada inteira. Outro exemplo é que a entrada de 31/01/2015 00:00 não pode ser analisada pelo padrão dd/MM/yyyy hh:mm porque hh pressupõe horas no intervalo de 1 a 12. No Spark versão 2.4 e inferiores, java.text.SimpleDateFormat é usado para conversões de cadeia de caracteres de data/carimbo de data/hora, e os padrões com suporte são descritos em simpleDateFormat. O comportamento antigo pode ser restaurado pela definição de spark.sql.legacy.timeParserPolicy como LEGACY.
    • As funções weekofyear, weekday, dayofweek, date_trunc, from_utc_timestamp, to_utc_timestamp e unix_timestamp usam a API java.time para calcular o número da semana do ano, o número do dia da semana, bem como para a conversão entre valores TimestampType no fuso horário UTC.
    • As opções JDBC lowerBound e upperBound são convertidas em valores TimestampType/DataType da mesma maneira que a conversão de cadeias de caracteres em valores TimestampType/DataType. A conversão é baseada no calendário gregoriano proléptico e no fuso horário definido pela configuração SQL spark.sql.session.timeZone. No Spark versão 2.4 e inferior, a conversão é baseada no calendário híbrido (juliano + gregoriano) e no fuso horário padrão do sistema.
    • Formatação de literais TIMESTAMP e DATE.
    • Criação de literais TIMESTAMP e DATE tipados de cadeias de caracteres. No Spark 3.0, a conversão de cadeia de caracteres em literais TIMESTAMP/DATE tipados é executada por meio da conversão em valores TIMESTAMP/DATE. Por exemplo, TIMESTAMP '2019-12-23 12:59:30' é semanticamente igual a CAST('2019-12-23 12:59:30' AS TIMESTAMP). Quando a cadeia de caracteres de entrada não contém informações sobre o fuso horário, o fuso horário da configuração SQL spark.sql.session.timeZone é usado nesse caso. No Spark versão 2.4 e inferiores, a conversão é baseada no fuso horário do sistema JVM. As diferentes fontes do fuso horário padrão podem alterar o comportamento dos literais TIMESTAMP e DATE tipados.

Apache Hive

  • No Spark 3.0, atualizamos a versão interna do Hive de 1.2 para 2.3, o que traz os seguintes impactos:
    • Talvez seja necessário definir spark.sql.hive.metastore.version e spark.sql.hive.metastore.jars de acordo com a versão do metastore do Hive ao qual você deseja se conectar. Por exemplo: defina spark.sql.hive.metastore.version como 1.2.1 e spark.sql.hive.metastore.jars como maven se sua versão de metastore do Hive for 1.2.1.
    • Você precisa migrar seu SerDes personalizado para o Hive 2.3 ou criar seu próprio Spark com o perfil hive-1.2. Confira o HIVE-15167 para obter mais detalhes.
    • A representação da cadeia de caracteres pode ser diferente entre Hive 1.2 e Hive 2.3 ao usar o operador TRANSFORM no SQL para transformação de script, que depende do comportamento do Hive. No Hive 1.2, a representação da cadeia de caracteres omite zeros à direita. Mas no Hive 2.3, ele sempre é preenchido até 18 dígitos com zeros à direita, se necessário.
    • No Databricks Runtime 7.x, ao ler uma tabela SerDe do Hive, por padrão, o Spark não permite a leitura de arquivos em um subdiretório que não seja uma partição de tabela. Para habilitá-lo, defina a configuração spark.databricks.io.hive.scanNonpartitionedDirectory.enabled como true. Isso não afeta os leitores da tabela nativa do Spark e os leitores de arquivo.

MLlib

  • OneHotEncoder, que é preterido na versão 2.3, foi removido no 3.0 e OneHotEncoderEstimator agora é renomeado como OneHotEncoder.
  • org.apache.spark.ml.image.ImageSchema.readImages, que foi preterido na versão 2.3, foi removido na versão 3.0. Use spark.read.format('image') em vez disso.
  • org.apache.spark.mllib.clustering.KMeans.train com o parâmetro Int runs, que foi preterido na versão 2.1, foi removido na versão 3.0. Use o método train sem execuções.
  • org.apache.spark.mllib.classification.LogisticRegressionWithSGD, que foi preterido na versão 2.0, foi removido na 3.0, use org.apache.spark.ml.classification.LogisticRegression ou spark.mllib.classification.LogisticRegressionWithLBFGS.
  • org.apache.spark.mllib.feature.ChiSqSelectorModel.isSorted, que foi preterida na versão 2.1, foi removida na versão 3.0 e não se destina a uso de subclasses.
  • org.apache.spark.mllib.regression.RidgeRegressionWithSGD, que foi preterido na versão 2.0, foi removido na versão 3.0. Use org.apache.spark.ml.regression.LinearRegression com elasticNetParam = 0.0. Observe que o regParam padrão é 0,01 para RidgeRegressionWithSGD, mas é 0,0 para LinearRegression.
  • org.apache.spark.mllib.regression.LassoWithSGD, que foi preterido na versão 2.0, foi removido na versão 3.0. Use org.apache.spark.ml.regression.LinearRegression com elasticNetParam = 1.0. Observe que o regParam padrão é 0,01 para LassoWithSGD, mas é 0,0 para LinearRegression.
  • org.apache.spark.mllib.regression.LinearRegressionWithSGD, que foi preterido na versão 2.0, foi removido na versão 3.0. Em vez disso, use org.apache.spark.ml.regression.LinearRegression ou LBFGS.
  • org.apache.spark.mllib.clustering.KMeans.getRuns e setRuns, que foram preteridos na versão 2.1, foram removidos na versão 3.0 e não produzem efeitos desde o Spark 2.0.0.
  • org.apache.spark.ml.LinearSVCModel.setWeightCol, que foi preterido na versão 2.4, foi removido na versão 3.0 e não se destina a usuários.
  • Na versão 3.0, org.apache.spark.ml.classification.MultilayerPerceptronClassificationModel estende MultilayerPerceptronParams para expor os parâmetros de treinamento. Como resultado, layers no MultilayerPerceptronClassificationModel foi alterado de Array[Int] para IntArrayParam. Você deve usar MultilayerPerceptronClassificationModel.getLayers em vez de MultilayerPerceptronClassificationModel.layers para recuperar o tamanho das camadas.
  • org.apache.spark.ml.classification.GBTClassifier.numTrees, que foi preterido na versão 2.4.5, foi removido na versão 3.0. Use getNumTrees em vez disso.
  • org.apache.spark.ml.clustering.KMeansModel.computeCost, que foi preterido na versão 2.4, foi removido na 3.0; use ClusteringEvaluator.
  • A precisão da variável de membro em org.apache.spark.mllib.evaluation.MulticlassMetrics, que foi preterida na versão 2.0, foi removida na versão 3.0. Use a precisão.
  • O recall da variável de membro em org.apache.spark.mllib.evaluation.MulticlassMetrics, que foi preterida na versão 2.0, foi removida na versão 3.0. Use accuracy em vez disso.
  • A variável de membro fMeasure em org.apache.spark.mllib.evaluation.MulticlassMetrics, que foi preterida na versão 2.0, foi removida na versão 3.0. Use accuracy em vez disso.
  • org.apache.spark.ml.util.GeneralMLWriter.context, que foi preterido na versão 2.0, foi removido na versão 3.0. Use session em vez disso.
  • org.apache.spark.ml.util.MLWriter.context, que foi preterido na versão 2.0, foi removido na versão 3.0. Use session em vez disso.
  • org.apache.spark.ml.util.MLReader.context, que foi preterido na versão 2.0, foi removido na versão 3.0. Use session em vez disso.
  • abstract class UnaryTransformer[IN, OUT, T <: UnaryTransformer[IN, OUT, T]] foi alterado para abstract class UnaryTransformer[IN: TypeTag, OUT: TypeTag, T <: UnaryTransformer[IN, OUT, T]] na versão 3.0.
  • No Spark 3.0, uma regressão logística de multiclasse no Pyspark agora retornará (corretamente) LogisticRegressionSummary, não a subclasse BinaryLogisticRegressionSummary. Os métodos adicionais expostos pelo BinaryLogisticRegressionSummary não funcionariam nesse caso, de qualquer forma. (SPARK-31681)
  • No Spark 3.0, pyspark.ml.param.shared.Has* os mixins não fornecem mais nenhum método setter set*(self, value); use o respectivo self.set(self.*, value). Confira o SPARK-29093 para obter detalhes. (SPARK-29093)

Outras alterações de comportamento

  • A atualização para o Scala 2.12 envolve as seguintes alterações:

    • A serialização de célula do pacote é tratada de forma diferente. O exemplo a seguir ilustra a alteração de comportamento e como tratá-la.

      A execução de foo.bar.MyObjectInPackageCell.run() conforme definido na célula do pacote a seguir disparará o erro 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 contornar esse erro, você pode encapsular MyObjectInPackageCell dentro de uma classe serializável.

    • Determinados casos que usam DataStreamWriter.foreachBatch exigirão uma atualização do código-fonte. Essa alteração ocorre devido ao fato de que o Scala 2.12 tem conversão automática de expressões lambda em tipos SAM e pode causar ambiguidade.

      Por exemplo, o seguinte código Scala não pode ser compilado:

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

      Para corrigir o erro de compilação, altere foreachBatch { (df, id) => myFunc(df, id) } para foreachBatch(myFunc _) ou use a API Java explicitamente: foreachBatch(new VoidFunction2 ...).

  • Como a versão do Apache Hive usada para lidar com funções definidas pelo usuário do Hive e SerDes do Hive é atualizada para 2.3, duas alterações são necessárias:

    • A interface SerDe do Hive é substituída por uma classe abstrata AbstractSerDe. Para qualquer implementação SerDe personalizada do Hive, a migração para AbstractSerDe é obrigatória.
    • A definição de spark.sql.hive.metastore.jars como builtin significa que o cliente de metastore do Hive 2.3 será usado para acessar metastores para o Databricks Runtime 7.x. Se você precisar acessar metastores externos baseados no Hive 1.2, defina spark.sql.hive.metastore.jars como a pasta que contém jars do Hive 1.2.

Desativações e remoções

  • O índice que ignora dados foi preterido no Databricks Runtime 4.3 e removido no Databricks Runtime 7.x. Recomendamos usar tabelas Delta no lugar, pois oferecem recursos aprimorados de omissão de dados.
  • No Databricks Runtime 7, a versão subjacente do Apache Spark usa o Scala 2.12. Como as bibliotecas compiladas no Scala 2.11 podem desabilitar os clusters do Databricks Runtime 7.x de maneiras inesperadas, os clusters que executam o Databricks Runtime 7.x não instalam bibliotecas configuradas para serem instaladas em todos os clusters. A guia Bibliotecas do cluster mostra um status Skipped e uma mensagem de obsolescência que explica as alterações no tratamento da biblioteca. No entanto, se você tiver um cluster criado em uma versão anterior do Databricks Runtime antes da versão da plataforma do Azure Databricks 3.20 ser lançada em seu espaço de trabalho, e agora editar esse cluster para usar o Databricks Runtime 7.x, todas as bibliotecas que foram configuradas para serem instaladas em todos os clusters serão instaladas naquele cluster. Nesse caso, quaisquer JARs incompatíveis nas bibliotecas instaladas podem fazer com que o cluster seja desabilitado. A solução alternativa é clonar o cluster ou criar um novo cluster.

Problemas conhecidos

  • A análise do dia do ano com o uso da letra do padrão “D” retorna o resultado errado quando o campo “ano” está ausente. Isso pode acontecer em funções SQL, como to_timestamp, que analisa a cadeia de caracteres datetime como valores datetime usando uma cadeia de caracteres de padrão. (SPARK-31939)
  • Junção/janela/agregação dentro de subconsultas pode levar a resultados incorretos se as chaves tiverem valores -0,0 e 0,0. (SPARK-31958)
  • Uma consulta de janela pode falhar com um erro de autojunção ambíguo inesperadamente. (SPARK-31956)
  • As consultas de streaming com operador dropDuplicates podem não conseguir reiniciar com o ponto de verificação gravado pelo Spark 2.x. (SPARK-31990)