为什么行计数作业在spark shell中的运行速度比mapreduce作业慢

时间:2016-09-23 15:03:22

标签: apache-spark

我做了一个测试来比较spark和mapreduce之间的性能。我有三个节点集群,每个集群有128GB内存。

我运行一个作业来计算10GB文件中的行数。

我使用mapreduce运行行计数作业,默认配置为hadoop。它只需要我大约23秒。

当我在每个节点使用8GB内存的spark shell中运行行计数作业时。我花了6分多钟才真的让我感到惊讶。

这是启动spark-shell的命令和spark job的代码。

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:

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 个答案:

答案 0 :(得分:2)

您可以传递分区数,即defaultMinPartitions 调整分区数

像这样

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

您也可以在加载后尝试repartition以查看效果。 另外,请查看how-to-tune-your-apache-spark-jobs

您可以通过打印进一步调试和调整设置

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

也可以获得多个执行程序,如下面的示例代码段。

/** 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都返回执行者的数量,包括驱动程序。

答案 1 :(得分:0)

默认情况下,Spark运行一个执行程序。我会将我的设置更改为:

在每台计算机上留下8GB的操作系统和其他进程开销。这将留下120GB。如果你有超过32GB的垃圾收集器开始降级,我每台机器有4个执行器,每个30GB。

所以,我会设置:

  • spark.executor.instances = 12
  • spark.executor.cores =(每台机器的核心数 - 1)/ 4(操作系统为1)
  • spark.executor.memory = 30g

然后再次运行您的应用程序。