优化广播联接的数据集建议大小是多少?

时间:2017-07-05 21:31:16

标签: apache-spark apache-spark-sql

我在JSON文本文件中提供了一个大型数据集,每行一个JSON对象。我需要解析/转换的字段之一是纪元时间戳(到可读日期)。

因此,处理数据的第一步是加载并解析它。如果我执行rdd.map操作,我可以:

  • 在地图中创建一个简单的日期格式对象(每个记录都会发生)。
  • 创建一个简单的日期格式对象并进行广播,只创建一次。

我不太明白这对于这样大小的对象哪个更好(我通常使用广播来计算在驱动程序上计算的相当大的集合)。

任何人都可以帮助我了解哪个选项更好,为什么?

2 个答案:

答案 0 :(得分:0)

您的问题似乎建议您要使用数据集(您想知道它是否适合广播)将其与其他数据集连接起来。

如果是这样,我想你可能想要阅读我的关于Broadcast Joins (aka Map-Side Joins)的掌握Apache Spark 2 gitbook:

  

当一方数据的大小低于spark.sql.autoBroadcastJoinThreshold时,Spark SQL使用广播连接(又名广播哈希连接)而不是哈希连接来优化连接查询

因此,您可以使用默认为spark.sql.autoBroadcastJoinThreshold的{​​{1}}属性微调广播联接。

引用Broadcast Variables

  

广播变量允许程序员在每台机器上保留一个只读变量,而不是随副本一起发送它的副本。例如,它们可用于以有效的方式为每个节点提供大输入数据集的副本。 Spark还尝试使用高效的广播算法来分发广播变量,以降低通信成本。

这并没有说明您的数据集应该有多大才能实现有效广播。它确实取决于Spark应用程序的内存量。如果你有一个拥有足够内存的强大的集群,那么任何规模都可以。它是网络带宽和可用RAM之间的权衡。

我的建议是计算Spark应用程序所需的内存,并查看广播变量(每个执行程序)剩余多少。然后,我计算广播数据集的大小,看看它是否合适。如果是这样,我会播放一个镜头并监控性能。如果它工作正常,我就会上线。

答案 1 :(得分:0)

Jacek Laskowski(强调我的)提供的答案相反:

  

如果你有一个拥有足够内存的强大集群,任何规模都可以使用。它是网络带宽和可用RAM之间的权衡。

它比可用RAM的数量复杂得多。对于N个工作人员,广播的数据集必须通过网络传输两次N + 1次:

  • 一旦向驱动程序收集数据(在广播联接中透明地完成)。
  • 从司机到工人N次。

如果广播数据集大于其他数据集的50%,则网络流量将大于对两个数据集进行混洗。

在实践中,由驱动程序网络创建的瓶颈和一些次要成本(最明显的是序列化和GC)使得广播无用得快得多。