【问题标题】:PySaprk- Perform Merge in Synapse using Databricks SparkPySpark- 使用 Databricks Spark 在 Synapse 中执行合并
【发布时间】:2020-12-26 12:38:44
【问题描述】:
我们在使用 Databricks Spark 执行 ACID 操作时遇到了一个棘手的情况。
我们希望使用 PySpark 通过 JDBC 连接对 Azure Synapse 表执行 UPSERT。我们知道 Spark 只提供了 2 种数据写入模式。 APPEND 和 OVERWRITE(在我们的例子中只有这两个使用 full)。所以基于这两种模式我们想到了以下选项:
-
我们将整个数据帧写入一个阶段表。我们将使用这个阶段表执行与最终表的合并操作(~UPSERT)。阶段表将被截断/删除。
-
我们也会将目标表数据引入 Spark。在 Spark 内部,我们将使用 Delta Lake 执行 MERGE,并生成最终的 Dataframe 。此 DataFrame 将以 OVERWRITE 模式写回 Target 表。
考虑到缺点。双方..
在选项 1 中,我们必须使用两个表来写入最终数据。如果 Stage 和 target 表都很大,那么在 Synapse 中执行 MERGE 操作是另一项艰巨的任务,可能需要时间。
在选项 2 中,我们必须将 Target 表放入 Spark 内存中。尽管网络 IO 不是我们关心的问题,因为 Databricks 和 Synpse 都在同一个 Azure AZ 中,但它可能会导致 Spark 端的内存问题。
还有其他可行的选择吗?或者有什么推荐吗??
【问题讨论】:
标签:
pyspark
databricks
azure-databricks
azure-synapse
spark3
【解决方案1】:
您是否尝试创建校验和以仅对具有实际数据更改的行进行合并更新?
【解决方案2】:
答案取决于您的问题中未列出的许多因素。这是一个非常开放的问题。
(鉴于您的问题表述方式,我假设您使用的是专用 SQL 池而不是按需 Synapse)
以下是一些想法:
- 您将在选项 1 中使用 spark 集群的计算,在选项 2 中使用 Synapse 的计算。比较成本。
- 使用他们的驱动程序使用 Datalake 作为阶段读取和写入 Spark 到/从 Synapse 读取和写入。 IE。在将表从 Synapse 读取到 Spark 中的 datafrmae 时,驱动程序将首先使 Synapse 将数据导出到 Datalake(作为 parquet IIRC),然后读取 Datalake 中的文件以创建 Dataframe。如果您谈论的是 10 或 10 万或数十亿行,这可以很好地扩展。但是,如果行数很少(10-100 千),开销可能会变成性能开销。
- 请记住,Synapse 不像传统的 MySQL 或 SQL-Server。这是一个 MPP 数据库。
-
"performing MERGE operation inside Synapse is another herculean task and May take time" 是错误的说法。它可以像 Spark 集群一样扩展。
-
It may leads to memory issue in Spark side,是和不是。一方面,所有数据都不会加载到单个工作节点中。 OTOH 是的,每个节点都需要足够的内存来完成它自己的部分。
- 虽然 Synapse 可以动态地放大和缩小,但我发现完成放大最多需要 40 分钟。另一方面,Databricks 是完全按需的,您可以通过打开集群、执行 upsert、关闭集群来摆脱困境。使用 Synapse,您可能会有其他客户端使用它,因此可能无法将其关闭。
- 因此,使用 Synapse 时,您必须忍受每次 upsert(放大、upsert、缩小)的 40-80 分钟停机时间,或者
- 始终为高 DWU 统一费率付费,虽然只有在您更新插入时您的使用率很高,但在其他情况下则非常低。
- 最后,请记住
MERGE 在撰写本文时处于预览状态。如果您的产品因使用 MERGE 而中断,则意味着没有 Sev-A 支持案例/立即支持。
- 您始终可以改用
DELETE + INSERT。假设您收到的增量包含目标表中的所有列,而不仅仅是更新的列。