Spark笔记(二)-Spark安装使用

By timebusker on June 25, 2018

安装基础

  • JDK安装成功(必须,Spark使用scala语言编写,运行在JVM上)

  • zookeeper安装成功(非必须,基于ZK配置Spark高可用)

  • hadoop2.7.5 HA安装成功(非必须,启动spark服务,sc变量可直接读取到HDFS文件,Spark可以运行在YARN资源管理器上)

  • Scala安装成功(非必须,Spark内部已经打包包含)

spark 安装

  • 修改spark-env.sh
export JAVA_HOME=/usr/local/jdk1.8.0_73
export HADOOP_HOME=/home/hadoop/apps/hadoop-2.7.5
export HADOOP_CONF_DIR=/home/hadoop/apps/hadoop-2.7.5/etc/hadoop

# 指定每个worker节点可以注册的计算资源
export SPARK_WORKER_MEMORY=5G
export SPARK_WORKER_CORES=5

# 指定master节点IP,有单点故障
# export SPARK_MASTER_IP=hadoop1

# 指定使用ZK进行master节点选举(每个节点执行启动master服务时连接到ZK参与主节点选举)
export SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=hadoop1:2181,hadoop2:2181,hadoop3:2181,hadoop4:2181 -Dspark.deploy.zookeeper.dir=/spark-ha"
  • 修改slaves
# 指定worker节点(./sbin/start-all.sh脚本远端到指worker节点启动worker)
hadoop1
hadoop2
hadoop3
hadoop4
  • 将包分发到每个spark节点

for i in {2..4}; do scp -r spark/ root@hadoop$i:/home/hadoop/apps/; done

  • 配置环境变量
#Spark
export SPARK_HOME=/home/hadoop/apps/spark
export PATH=$PATH:$SPARK_HOME/bin

启动服务

  • 启动ZK集群(基础服务)

  • 启动hadoop集群

  • 启动Spark集群

# 在任意一个master节点
./sbin/start-all.sh

# 其他master节点
./sbin/start-master.sh

启动spark服务

  • standalone模式(默认模式)
# 
/home/hadoop/apps/spark/bin/spark-submit \
  --class org.apache.spark.examples.SparkPi \
  --master spark://hadoop1:7077,hadoop2:7077 \
  --executor-memory 1g \
  --total-executor-cores 5 \
  /home/hadoop/apps/spark/examples/jars/spark-examples_2.11-2.3.0.jar \
  100000
  
/home/hadoop/apps/spark/bin/spark-shell \
  --master spark://hadoop1:7077,hadoop2:7077 \
  # 每个worker可用内存
  --executor-memory 1g \
  # executor可使用集群cpu的核数(总的)
  --total-executor-cores 5 
  • YARN模式
# YARN指定队列
spark-shell --master yarn --deploy-mode client --queuen QueuenB

可能遇到的问题:

XXXX is running beyond virtual memory limits. Current usage: 173.8 MB of 1 GB physical memory used;
 2.2 GB of 2.1 GB virtual memory used. Killing container.

大致意思:application运行超出了虚拟内存限制(可用物理内存1G,实际使用173M;可用虚拟内存2.1G,实际使用2.2G)

解决方案:
1.调整虚拟内存率yarn.nodemanager.vmem-pmem-ratio (这个hadoop默认是2.1<倍率>)

2.调整map与reduce的在AM中的大小,使其大于yarn里RM可分配的最小值yarn.scheduler.minimum-allocation-mb。
因为在Container中计算使用的虚拟内存大小计算如下:
map虚拟内大小=max(yarn.scheduler.minimum-allocation-mb,mapreduce.map.memory.mb)*(yarn.nodemanager.vmem-pmem-ratio)


###############################################################################################################################################
###############################################################################################################################################

在使用spark过程中,有时会因为数据增大,而出现下面两种错误:
java.lang.OutOfMemoryError: Java heap space   
java.lang.OutOfMemoryError:GC overhead limit exceeded  

这两种错误之前我一直认为是executor的内存给的不够,但是仔细分析发现其实并不是executor内存给的不足,而是driver的内存给的不足。
在standalone client模式下用spark-submit提交任务时(standalone模式部署时,默认使用的就是standalone client模式提交任务),
我们自己写的程序(main)被称为driver,在不指定给driver分配内存时,默认分配的是512M。在这种情况下,如果处理的数据或者加载的数据很大(我是从hive中加载数据),
driver就可能会爆内存,出现上面的OOM错误。

方法一:在spark-submit中指定 --driver-memory memSize参数来设定driver的jvm内存大小
./spark-submit \
  --master spark://7070 \
  --class $MAIN_CLASS \
  --executor-memory 3G \
  --total-executor-cores 10 \
  --driver-memory 2g \
  --name $APP_NAME \
  --conf "spark.executor.extraJavaOptions=-XX:+PrintGCDetails -XX:+PrintGCTimeStamps" \
  "$SPARK_APP_JAR" 
  
 
方法二:在spark_home/conf/目录中,将spark-defaults.conf.template模板文件拷贝一份到/spark_home/conf目录下,命名为spark-defaults.conf,然后在里面设置spark.driver.memory  memSize属性来改变driver内存大小。

 spark.master                       spark://master:7077
 spark.default.parallelism          10
 spark.driver.memory                2g
 spark.serializer                   org.apache.spark.serializer.KryoSerializer
 spark.sql.shuffle.partitions       50


###############################################################################################################################################
###############################################################################################################################################

ERROR TaskSetManager: Total size of serialized results of 1408992 tasks (1131.3 MB) is bigger than spark.driver.maxResultSize (1024.0 MB)

spark.driver.maxResultSize默认为1024.0 MB,增大设置:

方法一:set by SparkConf: conf.set("spark.driver.maxResultSize", "3g")

方法二:set by spark-defaults.conf: spark.driver.maxResultSize 3g

方法三:set when calling spark-submit: --conf spark.driver.maxResultSize=3g