繁体   English   中英

用 Apache Spark 连接两个大表

[英]Join two big tables with Apache Spark

我想使用 Spark 通过特定的互键加入 2 个非常大的表,我试图了解这样做的最佳方法是什么。

比方说,例如:

  • 表 1 包含 900M 行和 ~100 列
  • 表 2 包含 6 亿行和约 200 列。
  • 我们不能使用“广播连接”,表很大,不能广播。

我想使用两个表中都存在的相互“id”列来加入(内连接)表,此外,我知道 id 列在两个表中包含相同的值,不存在 id 值在一个中,但在另一个中不存在。

我能想到的理想方法是将我的每个表“划分”为包含相同“id”值的分区/存储桶,并将它们发送到同一个执行程序,该执行程序将在集群中以最少的数据混洗计算连接结果.

我的问题是:

  1. 如果我为每个表使用 example.repartition(5, 'id') - 5 个分区中的每一个都将包含相同的 '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 一定是一样的吗?

  1. 如果我以相同的方式使用“bucketBy”,我会在表的存储桶中获得相同的“id”值吗?

  2. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM