PySpark - Hive 上下文没有 Return 结果,但 SQL 上下文对类似查询有结果
PySpark - Hive Context Does Not Return Results but SQL Context Does for Similar Query
当我 运行 PySpark 中的 HiveContext 与 SQLContext 进行比较查询时,我注意到性能存在巨大差异
VERSIONS/CONFIGURATION
- Spark 1.3.1(也试过Spark 1.5.1)
- Hadoop 2.6(基于 CDH 5.4.0)
- pyspark --master yarn --num-executors 5 --executor-memory 10g --driver-memory 4g --driver-cores 4
TABLE 信息
- database.table 有超过 2k 个分区
- database.table 在 field1 上分区(在 where 子句中使用)
HIVECONTEXT 实现
from pyspark.sql import SQLContext
sqlContext = HiveContext(sc)
qry = "select count(*) from database.table a where a.field1 = 'ABCD'"
results = sqlContext.sql(qry).collect()
- 花费不确定的时间 - 我不得不停止执行查询,因为它很快就占用了我执行查询的边缘节点上超过 50% 的系统资源。
SQLCONTEXT 实现
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
df = sqlContext.parquetFile('hdfs_path_to_hive_table/field1=ABCD/')
df.select("field2").show()
- 执行需要 6.5 秒,returns 数据帧符合预期。
问题
- 有没有人注意到类似的事情?
- 后端发生了什么可能导致这种资源消耗,我可以做些什么来避免这种情况?
如有任何帮助,我们将不胜感激!
2015 年 10 月 16 日更新
我试过:
SET spark.sql.hive.metastorePartitionPruning=true
我还在运行陷入同样的问题。我让进程 运行 稍等一段时间,以测试 CPU 使用率会上升到多高,它达到了 2000% 以上!
我听说 parquet 格式的文件在 1.5 版之前可能是 spark 的一个问题,所以我在 spark 1.5.1 中使用这些附加设置进行的所有测试:
parquet.task.side.metadata=false
SET spark.sql.parquet.filterPushdown=true
SET spark.sql.parquet.cacheMetadata=false
但其中 none 似乎也有帮助。
在寻求答案的过程中,我遇到了这些不同的链接,这让我尝试了上述配置:
- Spark 阅读 Parquet 的 Metastore(parquet.task.side.metadata=false 和 SET spark.sql.parquet.filterPushdown=true):
- _https://issues.apache.org/jira/browse/SPARK-5346
- _
- Spark 1.5.1 Link 配置(SET spark.sql.parquet.cacheMetadata=false):
- _http://spark.apache.org/docs/latest/sql-programming-guide.html#configuration
- Link 之前的一个问题与我的非常相似:
- _https://mail-archives.apache.org/mod_mbox/spark-user/201509.mbox/%3CCAAswR-7C0Cfduj+iaVDb-XvrnCHScrh34Lo0BadWH6XPzUXePA@mail.gmail.com%3E
这可能不是 HiveContext/SQLContext 之间的区别,而是 table 元数据来自 HiveMetastore 与 SparkSQL 数据源 API 之间的区别。我猜想如果您以相同的方式创建 table,性能会相似。
在数据源中API我们花了相当多的时间来优化许多分区的发现和处理,总的来说我会说这个路径更容易使用/更快。
配置单元 table 的问题可能是从 Metastore 下载所有分区元数据并将其转换为我们的内部格式。我们对所有分区都这样做,即使在这种情况下您只需要前 ~20 行。
为了提高这种情况下的性能,我会尝试 运行:
SET spark.sql.hive.metastorePartitionPruning=true
.collect() 和 .show() 非常不同
您看到的性能差异可能是由于 collect(将整个结果数据帧拉入驱动程序)和 show(默认情况下仅显示结果数据帧的前 20 行)之间的差异。
您似乎没有在谱系中进行任何改组操作,所以可能是该节目只拉入了 20 行(而不是整个数据集,如 .collect() 情况)
collect() --->获取所有数据到边缘节点
show() ---> 将显示少量样本点,前 20 个数据点
当数据很大时,显然你会看到时间和内存上的巨大差异。
当我 运行 PySpark 中的 HiveContext 与 SQLContext 进行比较查询时,我注意到性能存在巨大差异
VERSIONS/CONFIGURATION
- Spark 1.3.1(也试过Spark 1.5.1)
- Hadoop 2.6(基于 CDH 5.4.0)
- pyspark --master yarn --num-executors 5 --executor-memory 10g --driver-memory 4g --driver-cores 4
TABLE 信息
- database.table 有超过 2k 个分区
- database.table 在 field1 上分区(在 where 子句中使用)
HIVECONTEXT 实现
from pyspark.sql import SQLContext
sqlContext = HiveContext(sc)
qry = "select count(*) from database.table a where a.field1 = 'ABCD'"
results = sqlContext.sql(qry).collect()
- 花费不确定的时间 - 我不得不停止执行查询,因为它很快就占用了我执行查询的边缘节点上超过 50% 的系统资源。
SQLCONTEXT 实现
from pyspark.sql import SQLContext
sqlContext = SQLContext(sc)
df = sqlContext.parquetFile('hdfs_path_to_hive_table/field1=ABCD/')
df.select("field2").show()
- 执行需要 6.5 秒,returns 数据帧符合预期。
问题
- 有没有人注意到类似的事情?
- 后端发生了什么可能导致这种资源消耗,我可以做些什么来避免这种情况?
如有任何帮助,我们将不胜感激!
2015 年 10 月 16 日更新
我试过:
SET spark.sql.hive.metastorePartitionPruning=true
我还在运行陷入同样的问题。我让进程 运行 稍等一段时间,以测试 CPU 使用率会上升到多高,它达到了 2000% 以上!
我听说 parquet 格式的文件在 1.5 版之前可能是 spark 的一个问题,所以我在 spark 1.5.1 中使用这些附加设置进行的所有测试:
parquet.task.side.metadata=false
SET spark.sql.parquet.filterPushdown=true
SET spark.sql.parquet.cacheMetadata=false
但其中 none 似乎也有帮助。
在寻求答案的过程中,我遇到了这些不同的链接,这让我尝试了上述配置:
- Spark 阅读 Parquet 的 Metastore(parquet.task.side.metadata=false 和 SET spark.sql.parquet.filterPushdown=true):
- _https://issues.apache.org/jira/browse/SPARK-5346
- _
- Spark 1.5.1 Link 配置(SET spark.sql.parquet.cacheMetadata=false):
- _http://spark.apache.org/docs/latest/sql-programming-guide.html#configuration
- Link 之前的一个问题与我的非常相似:
- _https://mail-archives.apache.org/mod_mbox/spark-user/201509.mbox/%3CCAAswR-7C0Cfduj+iaVDb-XvrnCHScrh34Lo0BadWH6XPzUXePA@mail.gmail.com%3E
这可能不是 HiveContext/SQLContext 之间的区别,而是 table 元数据来自 HiveMetastore 与 SparkSQL 数据源 API 之间的区别。我猜想如果您以相同的方式创建 table,性能会相似。
在数据源中API我们花了相当多的时间来优化许多分区的发现和处理,总的来说我会说这个路径更容易使用/更快。
配置单元 table 的问题可能是从 Metastore 下载所有分区元数据并将其转换为我们的内部格式。我们对所有分区都这样做,即使在这种情况下您只需要前 ~20 行。
为了提高这种情况下的性能,我会尝试 运行:
SET spark.sql.hive.metastorePartitionPruning=true
.collect() 和 .show() 非常不同
您看到的性能差异可能是由于 collect(将整个结果数据帧拉入驱动程序)和 show(默认情况下仅显示结果数据帧的前 20 行)之间的差异。
您似乎没有在谱系中进行任何改组操作,所以可能是该节目只拉入了 20 行(而不是整个数据集,如 .collect() 情况)
collect() --->获取所有数据到边缘节点
show() ---> 将显示少量样本点,前 20 个数据点
当数据很大时,显然你会看到时间和内存上的巨大差异。