单个记录查找的 Spark 性能

Spark Performance On Individual Record Lookups

我正在进行一项性能测试,比较 Spark SQL 和 Tez 上的 Hive 之间现有内部 Hive 表的查询。在整个测试过程中,Spark 显示的查询执行时间与 Tez 上的 Hive 相当或更快。这些结果与那里的许多例子是一致的。但是,有一个值得注意的例外情况,即在单个记录级别涉及基于键的选择的查询。在这种情况下,Spark 在 Tez 上比 Hive 慢得多。

网上查了这个话题,没找到满意的答案,想把这个例子发给SO社区,看看是不是我们环境或数据相关的个别一次性案例,或者与 Spark 相关的更大模式。

Spark 1.6.1 Spark Conf: Executors 2, Executory Memory 32G, Executor Cores 4.

数据位于内部 Hive Table 中,存储为使用 zlib 压缩的 ORC 文件类型。压缩文件的总大小约为 2.2 GB。

这是查询代码。

#Python API    
#orc with zlib key based select
dforczslt = sqlContext.sql("SELECT * FROM dev.perf_test_orc_zlib WHERE test_id= 12345678987654321")
dforczslt.show()

完成此查询的总时间超过 400 秒,而使用 Tez 上的 Hive 大约需要 6 秒。我还尝试通过 SQL 上下文配置使用谓词下推,但这并没有显着提高性能。此外,当使用 Parquet 进行相同的测试时,查询时间也与 Hive 相当。我确信还有其他解决方案可以提高查询的性能,例如使用 RDDS v. Dataframes 等。但我真的很想了解 Spark 如何与 ORC 文件交互,从而导致这种差距。

如果我可以就上面列出的任何谈话要点提供额外的说明,请告诉我。

以下步骤可能有助于提高 Spark SQL 查询的性能。

一般来说,Hive占用的是整个Hadoop集群的内存,明显大于执行器内存(这里2*32=64GB)。节点的内存大小是多少?

此外,与配置单元查询生成的 map/reduce 作业数相比,执行者的数量似乎更少 (2)。以 2 的倍数增加执行器的数量可能有助于提高性能。

在 SparkSQL 和 Dataframe 中,现在默认启用使用手动管理内存 (Tungsten) 的优化执行以及代码生成 用于表达式评估。如果尚未启用此功能,可以通过将 spark.sql.tungsten.enabled 设置为 true 来启用。

sqlContext.setConf("spark.sql.tungsten.enabled", "true")

ORC 格式的分栏性质有助于避免读取不必要的列。但是,但是,即使查询具有 WHERE 子句 filter.ORC 谓词下推会提高其内置索引的性能,我们仍然会读取不必要的行。这里,ORC 谓词下推在 Spark SQL 中默认是禁用的,需要显式启用。

sqlContext.setConf("spark.sql.orc.filterPushdown", "true")

我建议您做更多的研究,找出潜在的性能障碍(如果有的话)。