如何使用配置单元上下文有效地查询 Spark 中的配置单元表?
Posted
技术标签:
【中文标题】如何使用配置单元上下文有效地查询 Spark 中的配置单元表?【英文标题】:How to efficiently query a hive table in spark using hive context? 【发布时间】:2017-08-25 16:54:17 【问题描述】:我有一个包含时间序列数据的 1.6T Hive 表。我正在使用Hive 1.2.1
和Spark 1.6.1
在scala
。
以下是我在代码中的查询。但我总是得到Java out of memory error
。
val sid_data_df = hiveContext.sql(s"SELECT time, total_field, sid, year, date FROM tablename WHERE sid = '$stationId' ORDER BY time LIMIT 4320000 ")
通过从 hive 表中一次迭代地选择几条记录,我试图在结果 dataframe
上做一个滑动窗口
我有一个包含 4 个节点、122 GB 内存、44 个 vCore 的集群。我正在使用 488 GB 可用内存中的 425 GB 内存。我正在使用以下参数提交 spark-submit
--num-executors 16 --driver-memory 4g --executor-memory 22G --executor-cores 10 \
--conf "spark.sql.shuffle.partitions=1800" \
--conf "spark.shuffle.memory.fraction=0.6" \
--conf "spark.storage.memoryFraction=0.4" \
--conf "spark.yarn.executor.memoryOverhead=2600" \
--conf "spark.yarn.nodemanager.resource.memory-mb=123880" \
--conf "spark.yarn.nodemanager.resource.cpu-vcores=43"
请给我一些关于如何优化它并成功从 hive 表中获取数据的建议。
谢谢
【问题讨论】:
您的配置相当不错。您正在运行我们的内存,因为您没有重新分区数据(或者如果它被重新分区然后......它不是一个最佳的好数字我猜它可能像 16 * 43 * 2 = 1376 或 16 * 43 * 3 = 2064)。查看执行程序日志并查看每个执行程序有多少条记录。 我已重新分区。但作业在重新分区步骤之前失败。我觉得选择查询效率不高。选择查询上的limit
是否像这样工作,它会获取所有记录然后对其应用限制?
下面有答案你去掉限制试过了吗?
每次迭代的记录数约为 855360000,这就是我对其应用限制的原因。但是,我会尝试无限制地运行并在此处更新帖子..
@Ram Ghadiyaram:通过取消限制,工作运行良好。所以我明白我不应该使用限制。它能够查询如此大量的记录。但它没有成功运行。它在大约 30 次迭代后停止运行。我得到了Java HotSpot(TM) 64-Bit Server VM warning: INFO: os::commit_memory(0x00007f04e8e50000, 12288, 0) failed; error='Cannot allocate memory' (errno=12) # # There is insufficient memory for the Java Runtime Environment to continue
【参考方案1】:
问题可能出在这里:
LIMIT 4320000
您应该避免使用LIMIT
对大量记录进行子集化。在 Spark 中,LIMIT
将所有行移动到单个分区,可能会导致严重的性能和稳定性问题。
参见例如How to optimize below spark code (scala)?
我试图通过一次选择几条记录来迭代地在这个结果数据帧上做一个滑动窗口。
这听起来不对。滑动窗口操作通常可以通过窗口函数和基于时间戳的window
buckets的某种组合来实现。
【讨论】:
以上是关于如何使用配置单元上下文有效地查询 Spark 中的配置单元表?的主要内容,如果未能解决你的问题,请参考以下文章
保存从配置单元表中的 oracle 查询创建的 Spark DataFrame?
Spark2 中的 SQLContext 没有获取更新的配置单元表记录
Hive 查询在 spark 中失败,但在直线 Hive 中有效