本页面解释了 Spark Connect 的架构、Spark Connect 的优点以及如何升级到 Spark Connect。

让我们从探索 Spark Connect 的高级架构开始。

Spark Connect 的高级架构

Spark Connect 是一种协议,它规定了客户端应用程序如何与远程 Spark 服务器通信。实现 Spark Connect 协议的客户端可以连接到远程 Spark 服务器并向其发出请求,这与客户端应用程序使用 JDBC 驱动程序连接到数据库非常相似 - 查询 spark.table("some_table").limit(5) 应该直接返回结果。这种架构为最终用户提供了出色的开发者体验。

以下是 Spark Connect 的高级工作原理

  1. 客户端和 Spark 服务器之间建立连接
  2. 客户端将 DataFrame 查询转换为未解析的逻辑计划,该计划描述了操作的意图,而不是如何执行
  3. 未解析的逻辑计划被编码并发送到 Spark 服务器
  4. Spark 服务器优化并运行查询
  5. Spark 服务器将结果发回客户端

让我们更详细地了解这些步骤,以便更好地理解 Spark Connect 的内部工作原理。

在客户端和 Spark 服务器之间建立连接

Spark Connect 的网络通信使用 gRPC 框架

gRPC 性能高且与语言无关,这使得 Spark Connect 具有可移植性。

将 DataFrame 查询转换为未解析的逻辑计划

客户端解析 DataFrame 查询并将其转换为未解析的逻辑计划。

假设您有以下 DataFrame 查询:spark.table("some_table").limit(5)

以下是查询的未解析逻辑计划

== Parsed Logical Plan ==
GlobalLimit 5
+- LocalLimit 5
   +- SubqueryAlias spark_catalog.default.some_table
      +- UnresolvedRelation spark_catalog.default.some_table

客户端负责创建未解析的逻辑计划并将其传递给 Spark 服务器以执行。

将未解析的逻辑计划发送到 Spark 服务器

必须序列化未解析的逻辑计划,以便可以通过网络发送。Spark Connect 使用 Protocol Buffers,它是“一种与语言无关、平台无关的可扩展的结构化数据序列化机制”。

客户端和 Spark 服务器必须能够使用像 Protocol Buffers 这样与语言无关的格式进行通信,因为它们可能使用不同的编程语言或不同的软件版本。

现在让我们看看 Spark 服务器如何执行查询。

在 Spark 服务器上执行查询

Spark 服务器接收未解析的逻辑计划(一旦 Protocol Buffer 被反序列化),并像任何其他查询一样分析、优化和执行它。

在执行查询之前,Spark 会对未解析的逻辑计划执行许多优化。所有这些优化都发生在 Spark 服务器上,并且独立于客户端应用程序。

Spark Connect 允许您利用 Spark 强大的查询优化功能,即使客户端不依赖于 Spark 或 JVM。

将结果发回客户端

Spark 服务器在执行查询后将结果发回客户端。

结果作为 Apache Arrow 记录批次发送到客户端。单个记录批次包含许多行数据。

完整的结果以记录批次的部分块的形式流式传输到客户端,而不是一次性全部发送。将结果从 Spark 服务器流式传输到客户端可以防止因过大的请求而导致的内存问题。

以下是 Spark Connect 工作原理的图片形式的回顾

Spark Connect 的优点

现在让我们把注意力转向 Spark Connect 架构的优点。

Spark Connect 工作负载更容易维护

当您不使用 Spark Connect 时,客户端和 Spark Driver 必须运行相同的软件版本。它们需要相同的 Java、Scala 和其他依赖项版本。假设您在本地机器上开发一个 Spark 项目,将其打包为 JAR 文件,并将其部署到云中以在生产数据集上运行。您需要在本地机器上构建 JAR 文件,并使用与云中使用的相同的依赖项。如果使用 Scala 2.13 编译 JAR 文件,则还必须使用 Scala 2.13 编译的 Spark JAR 来配置集群。

假设您使用 Scala 2.12 构建 JAR,并且您的云提供商发布了一个使用 Scala 2.13 构建的新运行时。当您不使用 Spark Connect 时,您需要在本地更新您的项目,这可能具有挑战性。例如,当您将项目更新到 Scala 2.13 时,您还必须将所有项目依赖项(和传递依赖项)升级到 Scala 2.13。如果其中一些 JAR 文件不存在,您将无法升级。

相反,Spark Connect 将客户端和 Spark Driver 解耦,因此您可以更新 Spark Driver,包括服务器端依赖项,而无需更新客户端。这使得 Spark 项目更容易维护。特别是,对于纯 Python 工作负载,将 Python 与客户端上的 Java 依赖项分离可以改善 Apache Spark 的整体用户体验。

Spark Connect 允许您使用非 JVM 语言构建 Spark Connect 客户端

Spark Connect 将客户端和 Spark Driver 解耦,因此您可以使用任何语言编写 Spark Connect 客户端。以下是一些不依赖 Java/Scala 的 Spark Connect 客户端

例如,Golang 的 Apache Spark Connect 客户端 spark-connect-go 实现了 Spark Connect 协议,并且不依赖于 Java。您可以使用此 Spark Connect 客户端使用 Go 开发 Spark 应用程序,而无需安装 Java 或 Spark。

以下是如何使用 spark-connect-go 使用 Go 编程语言执行查询

spark, _ := sql.SparkSession.Builder.Remote(remote).Build()
df, _ := spark.Sql("select * from my_cool_table where age > 42")
df.Show(100, false)

当调用 df.Show() 时,spark-connect-go 将查询处理为未解析的逻辑计划,并将其发送到 Spark Driver 以执行。

spark-connect-go 是 Spark Connect 的解耦性质如何实现更好的最终用户体验的一个极好的例子。

Go 并不是唯一将从此架构中受益的语言。

Spark Connect 允许更好的远程开发和测试

Spark Connect 还使您能够在没有 SSH 的情况下将 Spark 嵌入到远程集群上的文本编辑器中(“远程开发”)。

当您不使用 Spark Connect 时,使用 Spark 将 Spark 嵌入到文本编辑器中需要本地运行的 Spark 会话或到远程 Spark Driver 的 SSH 连接。

Spark Connect 允许您连接到完全嵌入在文本编辑器中而无需 SSH 的远程 Spark Driver。这为用户在远程 Spark 集群上的 VS Code 等文本编辑器中开发代码时提供了更好的体验。

使用 Spark Connect,从本地 Spark 会话切换到远程 Spark 会话很容易 - 只需更改连接字符串即可。

Spark Connect 使调试更容易

Spark Connect 允许您将 IntelliJ 等文本编辑器连接到远程 Spark 集群,并使用调试器逐步执行您的代码。您可以调试在生产数据集上运行的应用程序,就像在本地机器上调试测试数据集一样。这为您提供了出色的开发者体验,尤其是在您想要利用 IDE 中内置的高质量调试工具时。

Spark JVM 不允许这种调试体验,因为它没有完全与文本编辑器集成。Spark Connect 允许您在文本编辑器中构建紧密的集成,并为远程 Spark 工作流程提供出色的调试体验。通过简单地切换 Spark Connect 会话的连接字符串,可以轻松配置客户端以在不同的执行环境中运行测试,而无需部署复杂的 Spark 应用程序。

Spark Connect 更稳定

由于利用 Spark Connect 的客户端应用程序的解耦性质,客户端的故障现在与 Spark Driver 解耦。这意味着当客户端应用程序失败时,其故障模式完全独立于其他应用程序,并且不会影响可能继续为其他客户端应用程序提供服务的正在运行的 Spark Driver。

升级到 Spark Connect

Spark Connect 不支持所有 Spark JVM API。例如,Spark JVM 有一些私有方法,一些用户利用这些方法在 Spark 集群上执行任意 Java 代码。Spark Connect 显然无法支持这些方法,因为 Spark Connect 客户端不一定运行 Java!

查看从 Spark JVM 迁移到 Spark Connect 的指南,了解更多关于如何编写与 Spark Connect 配合使用的代码。此外,请查看如何构建 Spark Connect 自定义扩展,以了解如何使用专用逻辑。

结论

Spark Connect 是在生产环境中运行 Spark 的更好架构。它更灵活、更易于维护,并提供更好的开发者体验。

将一些 Spark JVM 代码库迁移到 Spark Connect 很容易,但对于其他代码库,迁移具有挑战性。利用 RDD API 或使用私有 Spark JVM 函数的代码库更难迁移。

但是,从 Spark JVM 迁移到 Spark Connect 是一次性成本,因此一旦迁移,您将享受所有好处。

最新消息

存档