如何在 Spark SQL 中加入大数据帧? (最佳实践、稳定性、性能)
How to join big dataframes in Spark SQL? (best practices, stability, performance)
在 Spark SQL 中加入大数据帧时,我遇到了与 相同的错误。那里的建议是设置MEMORY_AND_DISKand/orspark.shuffle.memoryFraction0。但是,spark.shuffle.memoryFraction 在 Spark >= 1.6.0 中被弃用,如果我不缓存任何 RDD 或 Dataframe,设置 MEMORY_AND_DISK 应该没有帮助,对吧?此外,我还收到许多其他 WARN 日志和任务重试,这让我认为工作不稳定。
因此,我的问题是:
- 在 Spark SQL >= 1.6.0 中加入大型数据帧的最佳实践是什么?
更具体的问题是:
- 如何调整执行者数量和spark.sql.shuffle.partitions以获得更好的stability/performance?
- 如何在并行级别(executors/cores 的数量)和分区数量 之间找到适当的平衡点?我发现增加执行程序的数量并不总是解决方案,因为它可能会由于网络流量而产生 I/O 读取超时 异常。
- 是否有任何其他相关参数需要为此目的进行调整?
- 我的理解是,连接存储为 ORC 或 Parquet 的数据在连接操作方面比文本或 Avro 提供更好的性能。 Parquet 和 ORC 之间有显着差异吗?
- SQLContext 与 HiveContext 相比 stability/performance 对于连接操作是否有优势?
- 当连接中涉及的数据帧以前是 registerTempTable() 或 saveAsTable()[=46= 时,performance/stability 是否存在差异]?
到目前为止,我使用 this is answer and this chapter 作为起点。还有一些与此主题相关的 Whosebug 页面。然而我还没有找到这个热门问题的全面答案。
提前致谢。
问题太多了。请允许我一一回答:
您的执行者数量在生产环境中大部分时间都是可变的。这取决于可用资源。执行随机播放时,分区数很重要。假设您的数据现在是倾斜的,您可以通过增加分区数来降低每个任务的负载。
理想情况下,一项任务应该减去几个。如果任务花费的时间太长,您的容器可能会被抢占并且工作会丢失。如果任务只需要几毫秒,启动任务的开销就会占主导地位。
并行度和调整执行器大小,我想参考 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。这可能会为您提供一些见解。
干杯,Fokko
在 Spark SQL 中加入大数据帧时,我遇到了与
因此,我的问题是:
- 在 Spark SQL >= 1.6.0 中加入大型数据帧的最佳实践是什么?
更具体的问题是:
- 如何调整执行者数量和spark.sql.shuffle.partitions以获得更好的stability/performance?
- 如何在并行级别(executors/cores 的数量)和分区数量 之间找到适当的平衡点?我发现增加执行程序的数量并不总是解决方案,因为它可能会由于网络流量而产生 I/O 读取超时 异常。
- 是否有任何其他相关参数需要为此目的进行调整?
- 我的理解是,连接存储为 ORC 或 Parquet 的数据在连接操作方面比文本或 Avro 提供更好的性能。 Parquet 和 ORC 之间有显着差异吗?
- SQLContext 与 HiveContext 相比 stability/performance 对于连接操作是否有优势?
- 当连接中涉及的数据帧以前是 registerTempTable() 或 saveAsTable()[=46= 时,performance/stability 是否存在差异]?
到目前为止,我使用 this is answer and this chapter 作为起点。还有一些与此主题相关的 Whosebug 页面。然而我还没有找到这个热门问题的全面答案。
提前致谢。
问题太多了。请允许我一一回答:
您的执行者数量在生产环境中大部分时间都是可变的。这取决于可用资源。执行随机播放时,分区数很重要。假设您的数据现在是倾斜的,您可以通过增加分区数来降低每个任务的负载。 理想情况下,一项任务应该减去几个。如果任务花费的时间太长,您的容器可能会被抢占并且工作会丢失。如果任务只需要几毫秒,启动任务的开销就会占主导地位。
并行度和调整执行器大小,我想参考 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。这可能会为您提供一些见解。
干杯,Fokko