sparksql连接多表设计

carvr3hs  于 2021-05-27  发布在  Spark
关注(0)|答案(2)|浏览(535)

我正在使用一组表开发spark sql分析解决方案。假设有5个表我需要建立我的解决方案,最后我创建一个输出表。这是我的流程

dataframe1 = table1 join table2
dataframe2 = dataframe1 join table3
dataframe3 = datamframe2 + filter + agg
dataframe4 = dataframe3 join table4 join table 5 
// finally 
dataframe4.saveAsTable

当我保存最后一个Dataframe时,也就是对上面所有的Dataframe求值的时候。我的方法好吗?还是需要缓存/持久化中间Dataframe?

7xllpg7q

7xllpg7q1#

在您的情况下,原则上并不需要缓存或持久化为什么?
由于没有明显的重用路径(对于同一个操作中的其他操作或其他转换),所以都是顺序的。
还有,惰性评价和催化剂。
试试这个。解释一下,看看Spark是怎么形成的。
但是,由于集群上存在内存逐出的可能性,可能需要在工作进程上重新计算。您可以通过.cache和.persist应用各种设置,但是spark在没有显式.cache或.persist的情况下处理内存和磁盘溢出。看到了吗https://sparkbyexamples.com/spark/spark-difference-between-cache-and-persist/
另外,使用.cache也会影响性能。所以用。解释。这里有一篇很好的帖子:spark:显式缓存会干扰catalystoptimizer优化某些查询的能力吗?
所以,每个案子都不一样,但你的案子似乎和我一样可以回答。总而言之:每次对rdd或df调用操作时,或者在当前操作中重新访问并且不应用跳过的阶段情况时,都会重新计算未缓存或未选中的rdd或df。对你来说没有问题。否则实际上会减慢应用程序的速度。

fruv7luv

fruv7luv2#

这是一个非常普遍的问题,很难给出明确的答案。
根据表的大小,您可能希望对任何相对较小的表执行广播提示。你可以通过

table_i.join(broadcast(table_j), ....)

此行为取决于:now broadcast hint中的值,仅当spark能够计算表的值时,才会执行此提示,因此您可能需要 cache() . 另一个选择是通过spark检查点,它可以帮助截断本地优化计划(这也允许您从检查点位置恢复作业,这类似于写入hdfs,但有一些开销)。
在广播少量mb表的情况下,可能需要增加kryo缓冲区:

--conf spark.kryoserializer.buffer.max=1g

这还取决于您将使用哪种联接类型。您可能希望尽早进行筛选和聚合,因为这将减少连接曲面。
为了适当地优化这一点,还需要考虑许多其他因素。在任何联接中联接键的幂律分布的情况下,都需要对较小的表进行盐析和分解。

相关问题