【发布时间】:2015-11-08 05:17:19
【问题描述】:
我在跨 3 台机器的集群(独立模式)上使用 Spark 1.4,用于类似于 TPCH 的工作负载(具有多路/多路大连接和聚合的分析查询)。每台机器有 12GB 的内存和 4 个核心。我的总数据大小为 150GB,存储在 HDFS(存储为 Hive 表)中,我正在使用 Hive 上下文通过 Spark SQL 运行我的查询。 在查看了 spark 页面上的性能调整文档和最新 spark 峰会的一些剪辑后,我决定在我的 spark-env 中设置以下配置:
SPARK_WORKER_INSTANCES=4
SPARK_WORKER_CORES=1
SPARK_WORKER_MEMORY=2500M
(由于我的任务往往很长,因此启动多个 JVM 的开销,每个 worker 一个比总查询时间少得多)。当我监控工作进度时,我意识到虽然 Worker 内存为 2.5GB,但执行器(每个 Worker 一个)的最大内存为 512MB(这是默认值)。我在我的应用程序中将此值放大为:
conf.set("spark.executor.memory", "2.5g");
尝试将每个工作人员的最大可用内存分配给其唯一的执行程序,但我观察到我的查询运行速度比前一种情况慢(默认为 512MB)。将 2.5g 更改为 1g 提高了性能时间,接近但仍比 512MB 的情况差。我想我在这里缺少的是“WORKER_MEMORY”和“executor.memory”之间的关系。
难道不是 WORKER 试图在其执行者(在我的情况下是它唯一的执行者)之间分割此内存吗?或者还有其他需要记忆的工作正在完成?
此时我还需要研究和调整哪些其他重要参数才能从我的硬件中获得最佳响应时间? (我已经阅读了有关 Kryo 序列化程序的信息,并且正在尝试这样做 - 我主要关心与内存相关的设置以及与我的工作并行性相关的旋钮)。例如,对于一个简单的仅扫描查询,Spark 比 Hive 差(几乎慢 3 倍),而两者都在扫描完全相同的表和文件格式。这就是为什么我相信我通过将它们保留为默认值而遗漏了一些参数。
任何提示/建议将不胜感激。
【问题讨论】:
-
附加评论:我检查了 3 个节点上的磁盘使用情况(使用 iostat),似乎从 HDFS 分区读取数据是逐个节点进行的。在任何给定时间,只有一个节点显示活动 IO(已读取),而其他两个节点在 IO 方面处于空闲状态。我不确定为什么要以这种方式安排任务,因为这是一项仅限地图的工作,并且读取可以并行发生。
标签: performance memory apache-spark apache-spark-sql