单个记录查找的 Spark 性能
Posted
技术标签:
【中文标题】单个记录查找的 Spark 性能【英文标题】:Spark Performance On Individual Record Lookups 【发布时间】:2016-10-18 16:55:51 【问题描述】:我正在进行一项性能测试,比较 Spark SQL 和 Tez 上的 Hive 之间现有内部 Hive 表的查询。在整个测试过程中,Spark 显示的查询执行时间与 Tez 上的 Hive 相当或更快。这些结果与那里的许多示例一致。但是,在涉及单个记录级别的基于键的选择的查询中存在一个值得注意的例外。在这种情况下,Spark 比 Tez 上的 Hive 慢得多。
在互联网上研究了这个话题后,我找不到满意的答案,想把这个例子举给 SO 社区,看看这是与我们的环境或数据相关的个别一次性案例,还是更大的模式与火花有关。
火花 1.6.1 Spark Conf:Executors 2,Executory Memory 32G,Executor Cores 4。
数据位于内部 Hive 表中,该表存储为使用 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 文件交互,从而导致这种差距。
如果我可以就上面列出的任何谈话要点提供额外的说明,请告诉我。
【问题讨论】:
【参考方案1】:以下步骤可能有助于提高 Spark SQL 查询的性能。
一般来说,Hive 占用整个 Hadoop 集群的内存,明显大于执行器内存(这里 2* 32 = 64 GB)。节点的内存大小是多少?
此外,与 hive 查询生成的 map/reduce 作业的数量相比,执行器的数量似乎更少 (2)。以 2 的倍数增加执行器的数量可能有助于提高性能。
在 SparkSQL 和 Dataframe 中,现在默认启用使用手动管理的内存 (Tungsten) 优化执行以及代码生成 用于表达式评估。如果尚未启用,可以通过将 spark.sql.tungsten.enabled 设置为 true 来启用此功能。
sqlContext.setConf("spark.sql.tungsten.enabled", "true")
ORC 格式的列性质有助于避免读取不必要的列。但是,即使查询具有 WHERE 子句过滤器,我们仍然会读取不必要的行。ORC 谓词下推将通过其内置索引提高性能。这里,Spark SQL中ORC谓词下推默认是关闭的,需要显式开启。
sqlContext.setConf("spark.sql.orc.filterPushdown", "true")
我建议您进行更多研究,并找到潜在的性能障碍(如果有的话)。
【讨论】:
以上是关于单个记录查找的 Spark 性能的主要内容,如果未能解决你的问题,请参考以下文章