这是我的乱七八糟的代码Spark的结果。
这桶是半满还是半空的?其实它是满的……
真是每次我在Spark写连接操作时哭完都泪眼汪汪 🥲
别担心陛下!我来帮你弄清楚在Spark里实现连接时怎样去掉洗牌操作 👨🦳。不,我说的不是那种简单的广播连接方法。(我什么时候写过这么简单的博客啊,开玩笑! 😏)
首先,你需要了解Spark中简单的排序合并连接操作是如何工作的,然后我再透露更多信息。在我们的情况下,我们尝试合并两个非常大的表格。🤔
排序合并连接(S M连接)当你写 df1.join(df2)
时,Spark 会执行一个排序合并联接。这是 Spark 中最基本的联接操作,比如说,这也是最耗资源且可能最慢的操作之一。
第一步:分区表根据连接键列进行排序
根据连接键将分区的合并步骤:分区的合并
就是这样!但是……😶
这里需要注意的一个重要点:
在步骤1之前是步骤0,此时Spark会对所有分区进行洗牌,使得具有相同键的记录位于同一个分区。这意味着所有具有相同键的行最终都会被分配到同一个分区。
想象有成千上万个分区,在每个分区里有成千上万个连接键。把这些分区和键打乱它们、排序它们和合并它们对 Spark 来说真是做得很辛苦 🤕。也就是说,它确实完成了工作,但做完这一切后它肯定需要休息休息 🚬🚬🚬
以下是优雅地解释的 SM 加入:🤓分区1和2的ID现在一样了,还没排好序。
经过洗牌后,spark 进行排序
现在分区内的ID已经排序了
最后,Spark只需要整合个分区。
那就是说,火花是如何完成SM连接的。
排序-归并-桶连接所以,在排序合并连接中,我们创建了分区,然后重新组织和排序这些分区。最后,我们将这些分区连接起来 🤨
现在,假如……你来创建这些桶并进行分类,然后把这些桶交给Spark合并คณะกรรม?我意思是,Spark为你做了那么多,你就不能为Spark做这点小事吗? �🤫
一旦你把这些不给报酬的工作也做了😉,合并到spark时就不用再做任何调整了。😉
你在实现 SMB 加入时的任务我们有两个表,表一和表二,它们有一个共同的字段叫做join_key。我们需要根据这个共同的字段将这两个表连接起来。
首先,你需要根据 join_key 对两个表进行分桶,确保它们的分桶数量一致。
将表table1和table2根据join_key字段进行分桶操作,每个桶的数目为8。
2. 然后,按 join_key 对桶进行排序
table1_bucketed_sorted = table1_bucketted.sortBy("join_key") # 对table1_bucketted按join_key进行排序
table2_bucketed_sorted = table2_bucketted.sortBy("join_key") # 对table2_bucketted按join_key进行排序
3. 保存这两个表。完整的代码如下:
# 原代码内容
table1.write.bucketBy(8, "join_key").sortBy("join_key").saveAsTable("bucketed_table1")
table2.write.bucketBy(8, "join_key").sortBy("join_key").saveAsTable("bucketed_table2")
4. 最后,读取保存的表格,然后使用Spark将它们连接起来。
SPARK 在执行 SMB join 时的工作只是为了合并两个表的数据 😅。由于两个表每个都有8个排序桶,Spark只需要把这些桶合并起来生成输出就行了!😉
图片可能帮助你理解得更清楚
主要收获:- SMB连接操作 是一种基于已经 分桶 并且 排序 的表的排序合并连接的变体。
- 在普通的连接操作中,Spark 往往需要执行 重分区 操作来对齐来自两个表的键,这涉及在分区之间移动数据。SMB连接操作则避免了这一步重分区操作。
- 它通过设定表拥有相同的桶数并按照相同的连接键分区来实现这一点。这样,Spark可以直接合并对应桶中的排序数据,从而减少计算成本。
就这样!我特别喜欢我们这些数据工程师和Apache Spark之间互相帮助,让生活更美好的生态圈中。😇
要是你喜欢这篇博客,请给点掌声👏,让更多工程师能看到。
谢谢你的阅读! 😁
共同学习,写下你的评论
评论加载中...
作者其他优质文章