[英]Join two big tables with Apache Spark
我想使用 Spark 通过特定的互键加入 2 个非常大的表,我试图了解这样做的最佳方法是什么。
比方说,例如:
我想使用两个表中都存在的相互“id”列来加入(内连接)表,此外,我知道 id 列在两个表中包含相同的值,不存在 id 值在一个中,但在另一个中不存在。
我能想到的理想方法是将我的每个表“划分”为包含相同“id”值的分区/存储桶,并将它们发送到同一个执行程序,该执行程序将在集群中以最少的数据混洗计算连接结果.
我的问题是:
例如:
df1
+---+---+------+
|age| id| name|
+---+---+------+
| 5| 1| David|
| 50| 2| Lily|
| 10| 3| Dan|
| 15| 4|Nicole|
| 16| 5| Dana|
| 19| 6| Ron|
| 20| 7| Alice|
| 22| 8| Nora|
| 45| 9| Sara|
| 70| 10| Aaron|
+---+---+------+
df2
+---+-----+
| id|price|
+---+-----+
| 1| 30.8|
| 1| 40.3|
| 2|100.0|
| 2| 30.1|
| 3| 99.0|
| 3|102.0|
| 4| 81.2|
| 4| 91.2|
| 5| 73.4|
| 6| 22.2|
| 7|374.4|
| 8|669.7|
| 9| 4.8|
| 10|35.38|
+---+-----+
df1.repartition(5,'id')
df2.repartition(5,'id')
如果 df1 分区是:[id=1,id=2],[id=3,id=4],[id=5,id=6],[id=7,id=8],[id=9, id=10]
df2 一定是一样的吗?
如果我以相同的方式使用“bucketBy”,我会在表的存储桶中获得相同的“id”值吗?
spark 会将正确的分区发送到同一个执行程序吗? 我的意思是,包含表 1 的 [id=1,id=2] 的分区和包含表 2 的 [id=1,id=2] 的分区将被发送到同一个执行器进行连接。
如果我错过了什么,或者您可以根据我提到的假设推荐另一种方法来加入 2 个大表,这将非常有帮助。
看看这个答案。
TLDR:如果你想加入他们一次并且它的唯一目的是重新分区,只需简单地加入他们。
是的,它必须是这样的,否则整个 JOINing 范式将不可靠。
你的意思实际上是 Worker - 带有 Executor(s) 的机器。
不建议单独进行重新分区作为循环。
范围分区也有效。 检查以确保,但假设分区值的分布与附带条件相同。
这一切都在惰性评估的前提下工作。
可以使用 bucketBy - 但更多的是用于持久化到磁盘并在下一个应用程序中使用。
同样,您不必担心协助,因为惰性评估意味着优化器有机会将其全部解决 - 分配给哪个 Worker。 但那是在较低的细节层次上,抽象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.