文档首页/ 数据湖探索 DLI/ 版本规划/ Spark 2.4.x与Spark 3.3.x版本差异对比/ Spark 2.4.x与Spark 3.3.x版本在通用队列的差异对比
更新时间:2025-08-11 GMT+08:00
分享

Spark 2.4.x与Spark 3.3.x版本在通用队列的差异对比

DLI整理了Spark2.4.x与Spark 3.3.x版本在通用队列的差异,便于您了解Spark版本升级后通用队列上运行的作业在适配新版本引擎时的影响。

log4j依赖从1.x版本修改为2.x版本

  • 说明:

    log4j依赖从1.x版本修改为2.x版本

    • Spark2.4.x:log4j依赖1.x版本(社区不再支持)。
    • Spark 3.3.x:log4j依赖2.x版本。
  • 升级引擎版本后是否对作业有影响:

    有影响

Spark 3.3.x不支持v1表

  • 说明:

    Spark2.4.x支持datasourcev1、datasourcev2表。Spark 3.3.x不支持v1表。

    具体说明请参考DLI datasourceV1表和datasourceV2表

    • Spark2.4.x:支持datasourcev1、datasourcev2表。
    • Spark 3.3.x:不支持支持datasourcev1表。
  • 升级引擎版本后是否对作业有影响:

    有影响,建议在Spark 2.4.5版本整改到v2表后再升级Spark 3.3.1,具体操作指导可以参考DLI datasourceV1表和datasourceV2表的中的示例。

默认情况下空的input split不创建partition

  • 说明:
    • Spark2.4.x:默认情况下空的input split将创建partition。
    • Spark 3.3.x:默认情况下空的input split不创建partition。

      Spark 3.3.x时spark.hadoopRDD.ignoreEmptySplits=true。

  • 升级引擎版本后是否对作业有影响:

    有影响,需要判断是否使用分区名做业务判断。

eventlog的压缩格式设置为zstd

  • 说明:

    Spark 3.3.x版本中,spark.eventLog.compression.codec的默认值被设置为zstd,Spark在压缩事件日志时将不再支持使用spark.io.compression.codec的参数值。

    • Spark2.4.x:使用spark.io.compression.codec的参数值作为eventlog的压缩格式。
    • Spark 3.3.x:spark.eventLog.compression.codec默认设置为zstd。
  • 升级引擎版本后是否对作业有影响:

    有影响,eventlog的压缩格式发生变化。

spark.launcher.childConectionTimeout修改

  • 说明:
    • Spark2.4.x:配置名为spark.launcher.childConectionTimeout
    • Spark 3.3.x:配置名修改为spark.launcher.childConnectionTimeout
  • 升级引擎版本后是否对作业有影响:

    有影响,配置参数名称变化。

Spark 3.3.x不再支持将Apache Mesos作为资源管理器

  • 说明:
    • Spark2.4.x:Spark 2.4.x版本中使用Apache Mesos作为资源管理器。
    • Spark 3.3.x:Spark 3.3.x不再支持将Apache Mesos作为资源管理器。
  • 升级引擎版本后是否对作业有影响:

    功能增强,Spark 2.4.x版本中使用Mesos作为资源管理器,升级到Spark 3.3.x后,你需要考虑切换到其他资源管理器。

Spark 3.3.x会在应用程序自行终止时删除K8s driver

  • 说明:Spark 3.3.x会在应用程序自行终止时删除K8s driver。
  • 升级引擎版本后是否对作业有影响:

    功能增强,升级到Spark 3.3.x后,对于之前依赖于Kubernetes作为资源管理器的作业会有影响。Spark 3.3.x在应用程序终止时会自动删除driver pod可能会影响到作业的资源管理和清理流程。

Spark 3.3.x支持自定义k8s的调度器

  • 说明:
    • Spark2.4.x:不支持使用指定Kubernetes调度器来管理Spark作业的资源分配和调度。
    • Spark 3.3.x:Spark 3.3.x支持自定义k8s的调度器。
  • 升级引擎版本后是否对作业有影响:

    功能增强,支持自定义调度器管理资源的分配和调度。

Spark将不可为null的模式转换为可空

  • 说明:

    在Spark 2.4.x版本中,当用户指定的schema包含不可为空的字段时,Spark会将这些不可为null的模式转换为可空的。

    但是在Spark 3.3.x版本中,Spark尊重用户指定的schema中的nullability,即如果字段被定义为不可为空,Spark会保持该配置要求,不会自动转换为可空的字段。

    • Spark2.4.x:在Spark 2.4.x版本中,当用户指定的schema包含不可为空的字段时,Spark会将这些不可为null的模式转换为可空的。
    • Spark 3.3.x:Spark不会自动转换为可空的字段。

      如果希望在Spark 3.3.x版本中恢复到Spark 2.4.x版本的执行方式,您可以通过将 spark.sql.legacy.respectNullabilityInTextDatasetConversion设置为true来实现。

  • 升级引擎版本后是否对作业有影响:

    有影响。

  • 示例代码

    执行sql:

    spark.read.schema(StructType(
    StructField("f1", LongType, nullable = false) ::
    StructField("f2", LongType, nullable = false) :: Nil)
    ).option("mode", "DROPMALFORMED").json(Seq("""{"f1": 1}""").toDS).show(false);
    • Spark 2.4.5
      |f1 |f2 |
      +---+---+
      |1  |0  |
    • Spark 3.3.1
      |f1 |f2  |
      +---+----+
      |1  |null|

Spark scala版本变更

  • 说明:

    Spark scala版本变更。

    • Spark2.4.x:Spark scala版本为2.11。
    • Spark 3.3.x:Spark scala版本升级到2.12。
  • 升级引擎版本后是否对作业有影响:

    有影响,jar需要升级scala版本编译。

PySpark支持python版本变更

  • 说明:

    PySpark支持python版本变更。

    • Spark2.4.x:PySpark支持python版本范围2.6+版本到3.7+版本。
    • Spark 3.3.x:PySpark支持Python版本范围3.6及以上版本。
  • 升级引擎版本后是否对作业有影响:

    依赖版本变化,有影响,需要排查是否涉及。

PySpark-pandas支持版本变更

  • 说明:
    • Spark2.4.x:在Spark 2.4.x版本中,PySpark并没有要求指定Pandas的版本。
    • Spark 3.3.x:从Spark 3.3.x版本开始,PySpark需要0.23.2或更高版本的pandas才能使用pandas相关功能,如toPandas、 createDataFrame from pandas DataFrame等。
  • 升级引擎版本后是否对作业有影响:

    依赖版本变化,有影响,需要排查是否涉及。

PySpark-PyArrow支持版本变更

  • 说明:
    • Spark2.4.x:在Spark 2.4.x版本中,PySpark并没有要求指定PyArrow的版本。
    • Spark 3.3.x:从Spark 3.3.x版本开始,PySpark需要0.12.1或更高版本的PyArrow才能使用PyArrow相关功能,如Pandas_udf、toPandas等。
  • 升级引擎版本后是否对作业有影响:

    依赖版本变化,有影响,需要排查是否涉及。

以command命名DataFrameWriter触发的查询

在Spark 3.2.x版本中,当DataFrameWriter触发的查询执行被发送给QueryExecutionListener时,这些查询的名称总是被设置为command。而在Spark 3.1及更早版本中,这些查询的名称可能是save、insertInto或saveAsTable之一,这取决于具体的操作。

  • 说明:

    DataFrameWriter触发的查询执行在发送到QueryExecutionListener时,始终以command命名

    • Spark2.4.x:名称为save、insertInto、saveAsTable中的一个
    • Spark 3.3.x:command命名
  • 升级引擎版本后是否对作业有影响:

    有影响

DATE、TIMESTAMP类型字段读取差异

  • 说明:
    DATE、TIMESTAMP类型字段读取差异,对于Asia/Shanghai时区,时间在1900-01-01 08:05:43之前的值,Spark 2.4.5版本写入后Spark 3.3.1版本读取值与Spark 2.4.5版本读取值不同。
    • Spark2.4.x

      以Asia/Shanghai时区的 1900-01-01 00:00:00 为例,通过Spark 2.4.5版本队列写入,Spark 2.4.5版本读取后得到的值为 1900-01-01 00:00:00。

    • Spark 3.3.x:

      以Asia/Shanghai时区的 1900-01-01 00:00:00 为例,通过Spark 2.4.5版本队列写入,Spark 3.3.1版本配置spark.sql.parquet.int96RebaseModeInRead=LEGACY,读取后得到的值为 1900-01-01 00:00:00,但是配置spark.sql.parquet.int96RebaseModeInRead=CORRECTED时,读取后得到的值为1900-01-01 00:05:43。

  • 升级引擎版本后是否对作业有影响:

    有影响,需要评估DATE、TIMESTAMP类型字段的使用方式。

  • 示例代码:

    在作业中配置:

    spark.sql.session.timeZone=Asia/Shanghai
    • Spark 2.4.5
      spark.sql("create table parquet_timestamp_test (id int, col0 string, col1 timestamp) using parquet");
      spark.sql("insert into parquet_timestamp_test values (1, '245', '1900-01-01 00:00:00')");

      执行SQL读取数据:

      spark.sql("select * from parquet_timestamp_test").show();

      查询结果:

      +---+----+-------------------+
      | id|col0|               col1|
      +---+----+-------------------+
      |  1| 245|1900-01-01 00:00:00|
      +---+----+-------------------+
    • Spark 3.3.1
      spark.sql.parquet.int96RebaseModeInRead=LEGACY

      执行作业读取数据:

      spark.sql("select * from parquet_timestamp_test").show();

      查询结果

      +---+----+-------------------+
      | id|col0|               col1|
      +---+----+-------------------+
      |  1| 245|1900-01-01 00:00:00|
      +---+----+-------------------+

      可以再更换配置:

      spark.sql.parquet.int96RebaseModeInRead=CORRECTED

      并重新执行SQL进行读取:

      spark.sql("select * from parquet_timestamp_test").show();

      查询结果:

      +---+----+-------------------+
      | id|col0|               col1|
      +---+----+-------------------+
      |  1| 245|1900-01-01 00:05:43|
      +---+----+-------------------+
  • 配置项说明

    这些配置项提供了Spark如何处理DATE, TIMESTAMP类型字段中特定的时间(在外推格里历和儒略历之间有争议的时间),例如:对于Asia/Shanghai时区,指的是在1900-01-01 08:05:43之前的值的处理方式。

    有歧义的时间:

    1. 在特定时间之前。例如,对于Asia/Shanghai时区,指的是在1900-01-01 08:05:43之前的值;
    2. 且数据文件的元数据中未明确标注使用何种历法进行存储的情况。例如,Spark 3.3.x 版本部分情况写入时会在数据文件中记录使用的历法,此时该时间不属于有歧义的时间。
    • Datasource parquet表配置项说明
      表1 Spark 3.3.1 Datasource parquet表配置项

      配置项

      默认值

      描述

      spark.sql.parquet.int96RebaseModeInRead

      EXCEPTION (Spark作业默认配置)

      读取Parquet文件中INT96类型的TIMESTAMP字段时生效。

      • EXCEPTION: 遇到有歧义的时间会抛出报错,读取操作将失败。
      • CORRECTED: Spark 不会进行重新调整,而是按照原样读取日期/时间戳。
      • LEGACY: Spark 会将日期/时间戳从传统的混合模式(儒略历 + 格里历)日历重新调整到外推格里历。

      该配置项仅在 Parquet 文件的写入信息(如 Spark、Hive)未知时才生效。

      spark.sql.parquet.int96RebaseModeInWrite

      EXCEPTION (Spark作业默认配置)

      写入Parquet文件中INT96类型的TIMESTAMP字段时生效。

      • EXCEPTION: 遇到有歧义的时间会抛出报错,写入操作将失败
      • CORRECTED: Spark 不会进行重新调整,而是按照原样写入日期/时间戳
      • LEGACY: 当写入 Parquet 文件时,Spark 会将日期/时间戳从外推格里历重新调整到传统的混合模式(儒略历 + 格里历)。

      spark.sql.parquet.datetimeRebaseModeInRead

      EXCEPTION (Spark作业默认配置)

      读取DATE、TIMESTAMP_MILLIS、TIMESTAMP_MICROS逻辑类型的字段生效。

      • EXCEPTION: 遇到有歧义的时间会抛出报错,读取操作将失败。
      • CORRECTED: Spark 不会进行重新调整,而是按照原样读取日期/时间戳。
      • LEGACY: Spark 会将日期/时间戳从传统的混合模式(儒略历 + 格里历)日历重新调整到外推格里历。

      该配置项仅在 Parquet 文件的写入信息(如 Spark、Hive)未知时才生效。

      spark.sql.parquet.datetimeRebaseModeInWrite

      EXCEPTION (Spark作业默认配置)

      写入DATE、TIMESTAMP_MILLIS、TIMESTAMP_MICROS逻辑类型的字段生效。

      • EXCEPTION: 遇到有歧义的时间会抛出报错,写入操作将失败
      • CORRECTED: Spark 不会进行重新调整,而是按照原样写入日期/时间戳
      • LEGACY: 当写入 Parquet 文件时,Spark 会将日期/时间戳从外推格里历重新调整到传统的混合模式(儒略历 + 格里历)。
    • Datasource avro表配置项说明
      表2 Spark 3.3.1 Datasource avro表配置项

      配置项

      默认值

      描述

      spark.sql.avro.datetimeRebaseModeInRead

      EXCEPTION (Spark作业默认配置)

      读取DATE、TIMESTAMP_MILLIS、TIMESTAMP_MICROS逻辑类型的字段生效。

      • EXCEPTION: 遇到有歧义的时间会抛出报错,读取操作将失败。
      • CORRECTED: Spark 不会进行重新调整,而是按照原样读取日期/时间戳。
      • LEGACY: Spark 会将日期/时间戳从传统的混合模式(儒略历 + 格里历)日历重新调整到外推格里历。

      该配置项仅在 Avro 文件的写入信息(如 Spark、Hive)未知时才生效。

      spark.sql.avro.datetimeRebaseModeInWrite

      EXCEPTION (Spark作业默认配置)

      写入DATE、TIMESTAMP_MILLIS、TIMESTAMP_MICROS逻辑类型的字段生效。

      • EXCEPTION: 遇到有歧义的时间会抛出报错,写入操作将失败
      • CORRECTED: Spark 不会进行重新调整,而是按照原样写入日期/时间戳
      • LEGACY: 当写入 Avro 文件时,Spark 会将日期/时间戳从外推格里历重新调整到传统的混合模式(儒略历 + 格里历)。

from_unixtime函数差异

  • 说明:
    • Spark2.4.x

      以Asia/Shanghai时区的 -2209017600 为例,返回值为1900-01-01 00:00:00。

    • Spark 3.3.x:

      以Asia/Shanghai时区的 -2209017943 为例,返回值为 1900-01-01 00:00:00。

  • 升级引擎版本后是否对作业有影响:

    有影响,需要检查使用该函数的场景。

  • 示例代码:

    在作业中配置:

    spark.sql.session.timeZone=Asia/Shanghai
    • Spark 2.4.5

      执行以下语句读取数据:

      select from_unixtime(-2209017600);
      查询结果:
      +-----------------------------------------------+
      |from_unixtime(-2209017600, yyyy-MM-dd HH:mm:ss)|
      +-----------------------------------------------+
      |                            1900-01-01 00:00:00|
      +-----------------------------------------------+
    • Spark 3.3.1

      执行以下语句读取数据:

      select from_unixtime(-2209017600);

      查询结果

      +-----------------------------------------------+
      |from_unixtime(-2209017600, yyyy-MM-dd HH:mm:ss)|
      +-----------------------------------------------+
      |                            1900-01-01 00:05:43|
      +-----------------------------------------------+

unix_timestamp函数差异

  • 说明:
    对于Asia/Shanghai时区,小于1900-01-01 08:05:43的值。
    • Spark2.4.x

      以Asia/Shanghai时区的 1900-01-01 00:00:00 为例,返回值为 -2209017600。

    • Spark 3.3.x:

      以Asia/Shanghai时区的 1900-01-01 00:00:00 为例,返回值为 -2209017943。

  • 升级引擎版本后是否对作业有影响:

    有影响,需要检查使用该函数的场景。

  • 示例代码:

    在作业中配置:

    spark.sql.session.timeZone=Asia/Shanghai
    • Spark 2.4.5

      执行以下语句读取数据:

      select unix_timestamp('1900-01-01 00:00:00');
      查询结果:
      +--------------------------------------------------------+
      |unix_timestamp(1900-01-01 00:00:00, yyyy-MM-dd HH:mm:ss)|
      +--------------------------------------------------------+
      |                                             -2209017600|
      +--------------------------------------------------------+
    • Spark 3.3.1

      执行以下语句读取数据:

      select unix_timestamp('1900-01-01 00:00:00');

      查询结果

      +--------------------------------------------------------+
      |unix_timestamp(1900-01-01 00:00:00, yyyy-MM-dd HH:mm:ss)|
      +--------------------------------------------------------+
      |                                             -2209017943|
      +--------------------------------------------------------+

相关文档