2016-09-23 39 views
2

我做了一個測試來比較spark和mapreduce之間的性能。我有三個節點羣集,每個羣集都有128GB的內存。爲什麼行數計算作業在火花外殼中的運行速度比mapreduce作業慢

我運行一個作業來計算10GB文件中的行數。

我使用hadoop的默認配置使用mapreduce運行行數作業。它只需要我大約23秒。

當我在每個節點8GB內存的Spark shell中運行行計數作業時,我花了6分鐘以上,這真讓我感到吃驚。

以下是啓動spark-shell和spark作業代碼的命令。

spark-shell --master spark://10.8.12.16:7077 --executor-memory 8G 
val s= sc.textFile("hdfs://ns/alluxio/linecount/10G.txt") 
s.count() 

這裏來的火花我的配置文件:

spark-env.sh

export JAVA_HOME=/home/appadmin/jdk1.8.0_77 
export SPARK_HOME=/home/appadmin/spark-2.0.0-bin-without-hadoop 
export HADOOP_HOME=/home/appadmin/hadoop-2.7.2 
export SPARK_DIST_CLASSPATH=$(/home/appadmin/hadoop-2.7.2/bin/hadoop classpath) 
export YARN_CONF_DIR=$HADOOP_HOME/etc/hadoop 
export SPARK_LIBARY_PATH=.:$JAVA_HOME/lib:$JAVA_HOME/jre/lib:$HADOOP_HOME/lib/native 
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop 
SPARK_MASTER_HOST=10.8.12.16 
SPARK_MASTER_WEBUI_PORT=28686 
SPARK_LOCAL_DIRS=/home/appadmin/spark-2.0.0-bin-without-hadoop/sparkdata/local 
SPARK_WORKER_MEMORY=10g 


SPARK_WORKER_DIR=/home/appadmin/spark-2.0.0-bin-without-hadoop/sparkdata/work 
SPARK_LOG_DIR=/home/appadmin/spark-2.0.0-bin-without-hadoop/logs 

火花default.conf

spark.driver.memory    5g 
spark.eventLog.dir  hdfs://10.8.12.16:9000/spark-event-log 

回答

2

您可以通過分區的數量即defaultMinPartitions 調整

分區

的數量這樣

sc.textFile(file, numPartitions) 
    .count() 

你也可以嘗試repartition加載才能看到效果了。 此外,有通過打印

sc.getConf.getAll.mkString("\n") 

還可以得到執行人的數字,如下面的例子片斷看看how-to-tune-your-apache-spark-jobs

,可以進一步調試和調整設置。

/** Method that just returns the current active/registered executors 
     * excluding the driver. 
     * @param sc The spark context to retrieve registered executors. 
     * @return a list of executors each in the form of host:port. 
     */ 
     def currentActiveExecutors(sc: SparkContext): Seq[String] = { 
     val allExecutors = sc.getExecutorMemoryStatus.map(_._1) 
     val driverHost: String = sc.getConf.get("spark.driver.host") 
     allExecutors.filter(! _.split(":")(0).equals(driverHost)).toList 
     } 

sc.getConf.getInt("spark.executor.instances", 1) 

getExecutorStorageStatusgetExecutorMemoryStatus都返回執行人,包括驅動程序的數量。

+0

我遵循你的建議,並得到了更好的結果。火花作業需要1分鐘才能完成。不過,我的mapreduce作業只需要23秒。 mapreduce作業是否將數據保存在os緩存中,使其性能比啓動作業更好? spark工作可能不會使用緩存中的數據。那可能嗎? –

+0

更新了我的答案。你必須多調試一下,我已經完成了mapreduce和spark都是生產級代碼。但我的觀察是火花很慢,如果我們不能正確調整參數,我們覺得mapreduce在速度方面更好。經過多種方式來看待spark中的性能調優。我們能夠看到速度的巨大變化。最後,我們能夠證明相同邏輯的spark代碼運行速度更快。請通過深入瞭解它們來進一步微調參數。 :-) –

+0

任何其他調查結果。你能解決嗎? –

0

默認情況下,星火有一個運行遺囑執行人。我會更改我的設置爲:

爲每個機器留出8GB的OS和其他進程開銷。這會給你120GB。假設垃圾收集器開始降級,如果你的存儲容量大於32GB,那麼每臺機器有4個執行器,每個30GB。

所以,我會設置:

  • spark.executor.instances = 12
  • spark.executor.cores =(核數每臺機器都有 - 1)/ 4(留1 OS)
  • spark.executor.memory =30克

然後再次運行您的應用程序。

+0

它確實有效。但火花的工作仍然花費更多的時間,這需要我超過1分鐘。火花的工作仍然比MR低很多。當我使用命令「s.count()」運行spark工作時,需要花費大約1分鐘「[Stage 2:>(0 + 80)/ 80]」。當進度條移動時,花費約20秒完成。爲什麼會發生? –