我有一个非常复杂的查询,需要将一些'组加入9个或更多个表。表达。这些表中的大多数具有几乎相同的行数。这些表格还有一些列可用作'键'分区表。
以前,应用程序运行正常,但现在数据集的数据与以前一样是3~4倍。我的测试结果表明,如果每个表的行数小于4,000,000,那么应用程序仍可以很好地运行。但是,如果计数超过该值,则应用程序会写入数百TB的混洗并且应用程序会停止(无论我如何调整内存,分区,执行程序等)。实际数据可能只有几十Gs。
我认为如果分区工作正常,Spark不应该这么做,并且应该在每个节点上进行连接。令人费解的是,为什么Spark不是那么“聪明”。这样做。
我可以将数据集(使用上面提到的'键)拆分成许多数据集,这些数据集可以独立处理。但是负担将由我自己承担......它打破了使用Spark的原因。还有哪些方法可以提供帮助?
我使用Spark 2.0而不是Hadoop YARN。
答案 0 :(得分:0)
我的测试结果表明,如果每个表的行数小于4,000,000,应用程序仍可以很好地运行。但是,如果计数超过该计数,则应用程序会写入数百TB的混洗
当连接数据集时,如果一边的大小小于某个可配置的大小,spark会将整个表广播到每个执行程序,以便可以在任何地方本地执行连接。您的上述观察结果与此一致。您还可以明确地向spark提供广播提示,如df1.join(broadcast(df2))
除此之外,您能否提供有关您问题的更多细节?
[前段时间我也在努力解决加入和洗牌的问题,因为我们的一项工作必须处理几个TB。我们使用的是RDD(而不是数据集api)。我在[这里] 1写了我的发现。这些可能是有用的,你试图推理基础数据混乱。]
更新:根据documentation - spark.sql.autoBroadcastJoinThreshold
是可配置的属性键。 10 MB
是其默认值。它执行以下操作:
配置在执行连接时将广播到所有工作节点的表的最大大小(以字节为单位)。通过将此值设置为-1,可以禁用广播。请注意,目前只有运行命令ANALYZE TABLE COMPUTE STATISTICS noscan的Hive Metastore表支持统计信息。
显然,仅支持Hive表。