我在集群(独立模式)上使用Spark 1.4,跨3台机器,用于类似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一个jvm)远远小于总查询时间)。在监视作业进度时,我意识到虽然Worker内存为2.5GB,但执行器(每个Worker一个)的最大内存为512MB(这是默认值)。我在应用程序中将这个值放大为:
conf.set("spark.executor.memory", "2.5g");
尝试在每个worker上为其唯一的执行器提供最大可用内存,但我观察到我的查询运行速度比前一种情况(默认512MB)慢。将2.5g更改为1g改善了性能时间,接近但仍然不如512MB的情况。我想我在这里缺少的是"WORKER_MEMORY"one_answers"executor.memory"之间的关系。
是不是WORKER试图在其执行器(在我的情况下,它的唯一执行器)之间分割此内存?或者还有其他工作需要内存来完成?
为了从我的硬件中获得最佳响应时间,我还需要查看和调整哪些其他重要参数?(我读过关于Kryo序列化器的文章,我想尝试一下——我主要关心与内存相关的设置,以及与我的工作并行性相关的旋钮)。举个例子,对于一个简单的只扫描查询,Spark比Hive差(几乎慢了3倍),而两者都在扫描完全相同的表&文件格式。这就是为什么我相信我错过了一些参数,让他们作为默认值。
Spark_worker_cores是跨实例共享的。将内核数增加到8,那么您应该会看到您所期望的行为(和性能)。