Bootstrap

Spark 2 迁移 Spark 3 参考手册

Apache Spark是一个广泛应用于大规模数据处理的开源统一分析引擎。自发布以来,它已经成为大数据处理的事实标准。2020年发布的Spark 3.0带来了许多新特性和改进,极大地提升了性能和易用性。如果你习惯使用Spark 2,那么了解新版本的变化将非常有帮助。
本文将重点介绍Spark 2和Spark 3在语法上的主要差异,帮助开发者顺利过渡到新版本。希望这篇文章能为你在Spark 3上的开发提供一些有用的参考。


1. 依赖项更新

从 Spark 2.x 迁移到 Spark 3.x 时,首先需要更新项目的依赖项,以确保项目能够使用 Spark 3.x 的新特性和 API。以下是详细步骤:

1.1 确定构建工具

常见的构建工具包括 Maven 和 SBT。根据你当前项目使用的构建工具,更新相应的依赖项。

1.2 更新 Maven 依赖项

如果你的项目使用 Maven 作为构建工具,需要在 pom.xml 文件中更新 Spark 依赖项的版本。

步骤:

  1. 打开 pom.xml 文件。
  2. 找到 Spark 相关的依赖项部分。
  3. 将 Spark 依赖项版本更新为 3.4.2。

示例:

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.12</artifactId>
    <version>3.4.2</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-sql_2.12</artifactId>
    <version>3.4.2</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-mllib_2.12</artifactId>
    <version>3.4.2</version>
</dependency>
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-streaming_2.12</artifactId>
    <version>3.4.2</version>
</dependency>

确保所有的 Spark 相关依赖都使用相同的 Scala 版本(这里是 2.12)。

1.3 更新 SBT 依赖项

如果你的项目使用 SBT 作为构建工具,需要在 build.sbt 文件中更新 Spark 依赖项的版本。

步骤:

  1. 打开 build.sbt 文件。
  2. 找到 Spark 相关的依赖项部分。
  3. 将 Spark 依赖项版本更新为 3.4.2。

示例:

libraryDependencies += "org.apache.spark" %% "spark-core" % "3.4.2"
libraryDependencies += "org.apache.spark" %% "spark-sql" % "3.4.2"
libraryDependencies += "org.apache.spark" %% "spark-mllib" % "3.4.2"
libraryDependencies += "org.apache.spark" %% "spark-streaming" % "3.4.2"

同样,确保所有的 Spark 相关依赖都使用相同的 Scala 版本(这里是 2.12)。

1.4 验证和构建

完成依赖项更新后,需要验证项目的构建是否成功。

步骤:

  1. 在项目根目录下,运行以下命令以清理并重新构建项目:

Maven:

mvn clean install

SBT:

sbt clean compile
  1. 检查构建输出,确保没有错误。如果出现错误,检查依赖项的版本和配置是否正确。
1.5 依赖项冲突解决

在更新依赖项过程中,可能会遇到依赖项冲突问题。常见的冲突问题及解决方案如下:

  1. 版本冲突:某些依赖项可能同时依赖于不同版本的同一个库。可以使用 Maven 的 dependencyManagement 或 SBT 的 exclude 来解决冲突。

Maven 解决版本冲突:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.example</groupId>
            <artifactId>example-lib</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>
</dependencyManagement>

SBT 解决版本冲突:

libraryDependencies += "com.example" %% "example-lib" % "1.2.3" exclude("org.other", "conflict-lib")

2 依赖项排除:在某些情况下,可能需要排除某些传递依赖项。

Maven 排除依赖项:

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-core_2.12</artifactId>
    <version>3.4.2</version>
    <exclusions>
        <exclusion>
            <groupId>com.example</groupId>
            <artifactId>conflict-lib</artifactId>
        </exclusion>
    </exclusions>
</dependency>

SBT 排除依赖项:

libraryDependencies += "org.apache.spark" %% "spark-core" % "3.4.2" exclude("com.example", "conflict-lib")
1.6 测试构建

在完成依赖项更新并解决冲突后,需要运行项目中的单元测试和集成测试,以确保更新后的依赖项没有引入新问题。

步骤:

  1. 在项目根目录下,运行以下命令以执行测试:

Maven:

mvn test

SBT:

sbt test
  1. 检查测试结果,确保所有测试用例都通过。

2. API 变化和废弃的 API

从 Spark 2.x 迁移到 Spark 3.x 时,需要注意 API 的变化和一些已废弃的 API。以下是一些关键的 API 变化和如何处理它们的详细说明:

2.1 DataFrame API 变化
  1. 创建 DataFrame

在 Spark 3.x 中,createDataFrame 方法的行为发生了一些变化。需要确保创建 DataFrame 时指定 schema,特别是从 RDD 创建 DataFrame 时。

示例:

Spark 2.x:

val rdd = spark.sparkContext.parallelize(Seq(Row(1, "Alice")))
val schema = StructType(Array(StructField("id", IntegerType, nullable = true), StructField("name", StringType, nullable = true)))
val df = spark.createDataFrame(rdd, schema)

Spark 3.x:

val rdd = spark.sparkContext.parallelize(Seq(Row(1, "Alice")))
val schema = StructType(Array(StructField("id", IntegerType, nullable = true), Struct
;