如何在Spark SQL中加入大数据帧? (最佳实践,稳定性,性能)

时间:2016-06-23 09:34:10

标签: performance join apache-spark apache-spark-sql spark-dataframe

在Spark SQL中加入大数据帧时,我得到的错误与Missing an output location for shuffle相同。建议设置 MEMORY_AND_DISK 和/或 spark.shuffle.memoryFraction 0 。但是,在Spark> = 1.6.0中不推荐使用spark.shuffle.memoryFraction,如果我没有缓存任何RDD或Dataframe,设置MEMORY_AND_DISK应该没有帮助,对吧?此外,我正在获得许多其他WARN日志和任务重试,这使我认为工作不稳定。

因此,我的问题是:

  • 在Spark SQL> = 1.6.0中加入大型数据框的最佳做法是什么?

更具体的问题是:

  • 如何调整执行者数量 spark.sql.shuffle.partitions 以获得更好的稳定性/性能?
  • 如何在并行级别(执行者/核心数量)和分区数量之间找到适当的平衡点?我发现增加执行数量并不总是解决方案,因为它可能会因网络流量而产生 I / O读取超时异常。
  • 是否还有其他相关参数需要针对此目的进行调整?
  • 我的理解是,加入存储为 ORC Parquet 的数据可提供比文本或Avro更好的连接操作性能。 Parquet和ORC之间有显着差异吗?
  • SQLContext HiveContext 相比,是否有关于加入操作的稳定性/性能的优势?
  • 当联接中涉及的数据框先前 registerTempTable() saveAsTable()时,性能/稳定性是否存在差异?

到目前为止,我使用this is answerthis chapter作为起点。还有一些与此主题相关的stackoverflow页面。然而,我还没有找到这个热门问题的全面答案。

提前致谢。

1 个答案:

答案 0 :(得分:6)

这是很多问题。请允许我逐一回答:

执行者的数量是生产环境中大部分时间变量。这取决于可用资源。执行shuffle时,分区数很重要。假设您的数据现在已经扭曲,您可以通过增加分区数来降低每个任务的负载。 理想情况下,任务应该减去一些。如果任务花费的时间太长,则容器可能会被抢占并且工作丢失。如果任务只需几毫秒,则启动任务的开销占主导地位。

并行度和调整执行者大小的水平,我想参考Cloudera的优秀指南:https://blog.cloudera.com/blog/2015/03/how-to-tune-your-apache-spark-jobs-part-2/

ORC和Parquet仅对静止的数据进行编码。在进行实际连接时,数据采用Spark的内存格式。自从Netflix和Facebook采用它并在其中付出了很多努力以来,Parquet越来越受欢迎。 Parquet允许您更有效地存储数据,并具有Spark使用的一些优化(谓词下推)。

您应该使用SQLContext而不是HiveContext,因为不推荐使用HiveContext。 SQLContext更通用,不仅适用于Hive。

执行registerTempTable时,数据存储在SparkSession中。这不会影响连接的执行。它存储的只是执行操作时调用的执行计划(例如saveAsTable)。在执行saveAsTable时,数据会存储在分布式文件系统中。

希望这会有所帮助。我还建议观看Spark峰会上有关加入的话题:https://www.youtube.com/watch?v=6zg7NTw-kTQ。这可能会为您提供一些见解。

干杯,福科