1.长时间未stop关不掉hadoop
1.对于在进行集群搭建的过程中启动secondarynamenode出现port in use:node3:50090的问题
2.关不掉
找某个进程
ps -ef|grep secondarynamenode
lsof -i:50070
kill -9 杀死
删除相对应的pid文件(tmp或自定义的)
2.spark on yarn的unknown queue: thequeue
参考链接http://blog.chinaunix.net/uid-20682147-id-5611559.html#_Toc6891
运行:
./bin/spark-submit --class org.apache.spark.examples.SparkPi --master yarn --deploy-mode cluster --driver-memory 4g --executor-memory 2g --executor-cores 1 --queue thequeue lib/spark-examples*.jar 10
时报如下错误,只需要将“–queue thequeue”改成“–queue default”即可。
16/02/03 15:57:36 INFO yarn.Client: Application report for application_1454466109748_0004 (state: FAILED)
16/02/03 15:57:36 INFO yarn.Client:
client token: N/A
diagnostics: Application application_1454466109748_0004 submitted by user hadoop to unknown queue: thequeue
ApplicationMaster host: N/A
ApplicationMaster RPC port: -1
queue: thequeue
start time: 1454486255907
final status: FAILED
tracking URL: http://hadoop-168-254:8088/proxy/application_1454466109748_0004/
user: hadoop
16/02/03 15:57:36 INFO yarn.Client: Deleting staging directory .sparkStaging/application_1454466109748_0004
Exception in thread "main" org.apache.spark.SparkException: Application application_1454466109748_0004 finished with failed status
at org.apache.spark.deploy.yarn.Client.run(Client.scala:1029)
at org.apache.spark.deploy.yarn.Client$.main(Client.scala:1076)
at org.apache.spark.deploy.yarn.Client.main(Client.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.spark.deploy.SparkSubmit$.org$apache$spark$deploy$SparkSubmit$$runMain(SparkSubmit.scala:731)
at org.apache.spark.deploy.SparkSubmit$.doRunMain$1(SparkSubmit.scala:181)
at org.apache.spark.deploy.SparkSubmit$.submit(SparkSubmit.scala:206)
at org.apache.spark.deploy.SparkSubmit$.main(SparkSubmit.scala:121)
at org.apache.spark.deploy.SparkSubmit.main(SparkSubmit.scala)
16/02/03 15:57:36 INFO util.ShutdownHookManager: Shutdown hook called
16/02/03 15:57:36 INFO util.ShutdownHookManager: Deleting directory /tmp/spark-54531ae3-4d02-41be-8b9e-92f4b0f05807
3.centos更改权限
su - hadoop
chown hadoop:hadoop -R spark-2.2.0-bin-hadoop2.6
4.no resourcemanager to stop
参考链接.https://www.jianshu.com/p/994784f6c932
- 问题描述:
虚拟机环境下,使用stop-yarn.sh和stop-dfs.sh停止yarn和hdfs时出现no resourcemanager to stop、no nodemanager to stop、no namenode to stop、no datanode to stop,但是相关进程都真实存在,并且可用
- 出现这个问题的原因:
当初启动的时候没有指定pid的存放位置,hadoop(hbase也是这样)默认会放在Linux的/tmp目录下,进程名命名规则一般是框架名-用户名-角色名.pid,而默认情况下tmp里面的东西,一天会删除一次,由于pid不存在,当执行stop相关命令的时候找不到pid也就无法停止相关进程,所以报no xxx to stop
- 解决方式:
当然就是手动指定pid的存放位置,避免放在/tmp目录下,
1.修改hadoop-env.sh,如果没有相关配置,可用直接添加
export HADOOP_PID_DIR=/home/hadoop/pidDir export
HADOOP_SECURE_DN_PID_DIR=/home/hadoop/pidDir
上述配置,影响NameNode DataNode SecondaryNameNode进程pid存储
2.修改mapred-env.sh
export HADOOP_MAPRED_PID_DIR=/home/hadoop/pidDir
上述配置,影响JobHistoryServer进程pid存储
3.修改yarn-env.sh
export YARN_PID_DIR=/home/hadoop/pidDir
上述配置,影响 NodeManager ResourceManager 进程pid存储
4.以上配置好后,启动yarn和hdfs,启动成功后首先jps查看,ok,5个进程都在,然后cd /home/hadoop/pidDir目录下,有如下文件,完美
-rw-rw-r-- 1 hadoop hadoop 6 Mar 2 17:13 hadoop-hadoop-datanode.pid
-rw-rw-r-- 1 hadoop hadoop 6 Mar 2 17:13 hadoop-hadoop-namenode.pid
-rw-rw-r-- 1 hadoop hadoop 6 Mar 2 17:13 hadoop-hadoop-secondarynamenode.pid
-rw-rw-r-- 1 hadoop hadoop 6 Mar 2 17:13 yarn-hadoop-nodemanager.pid
-rw-rw-r-- 1 hadoop hadoop 6 Mar 2 17:13 yarn-hadoop-resourcemanager.pid
5.pid问题总结
参考链接https://www.cnblogs.com/weiyiming007/p/12018288.html
5.1、说明
当不修改PID文件位置时,系统默认会把PID文件生成到/tmp目录下,但是/tmp目录在一段时间后会被删除,所以以后当我们停止HADOOP/HBASE/SPARK时,会发现无法停止相应的进程
会警告说:no datanode to stop、no namenode to stop 等,
因为PID文件已经被删除,此时只能用kill命令先干掉,所以现在我们需要修改HADOOP/HBASE/SPARK的PID文件位置;
修改配置前,应先停止相关集群服务;
可以先修改一台的配置,然后分发到其他主机对应的目录中;
5.2、修改hadoop的pid文件位置
创建pid存放目录(集群所有主机):
mkdir –p /var/hadoop/pid
#如果是普通用户,注意权限问题,修改权限;
hadoop-env.sh 增加以下内容:
export HADOOP_PID_DIR=/var/hadoop/pid
yarn-env.sh 增加以下内容:
export YARN_PID_DIR=/var/hadoop/pid
hbase-env.sh 增加以下内容:
export HBASE_PID_DIR=/var/hadoop/pid
5.3、修改hbase的pid文件位置
创建pid存放目录(集群所有主机):
mkdir -p /var/hbase/pid
#同样需要注意权限问题;
hbase-env.sh 增加以下内容:
export HBASE_PID_DIR=/var/hbase/pid
5.4、修改spark的pid文件位置
创建pid存放目录(集群所有主机):
mkdir -p /var/spark/pid
#同样需要注意权限问题;
spark-env.sh 增加以下内容:
export SPARK_PID_DIR=/var/spark/pid
5.5、分发以上修改后的文件;
5.6、启动集群服务,观察是否在创建的目录中生成了pid文件;
[root@node1 ~]# ls /var/hadoop/pid/ hadoop-root-datanode.pid
hadoop-root-namenode.pid yarn-root-nodemanager.pid
yarn-root-resourcemanager.pid[root@node1 ~]# ls /var/hbase/pid/ hbase-root-master.pid
hbase-root-master.znode hbase-root-regionserver.pid
hbase-root-regionserver.znode
6.Spark启动与停止
7.hadoop+spark配置参考
参考链接1Ubuntu版https://www.jianshu.com/p/aa6f3a366727
参考链接2CentOS版https://www.linuxidc.com/Linux/2018-06/152795.htm
8.北风笔记
8.1 hadoop
第一步:配置hadoop-env.sh
export JAVA_HOME=/usr/local/jdk
export HADOOP_PID_DIR=/home/hadoop/bigdater/hadoop-2.5.0-cdh5.3.6/hdfs/tmp
第二步:配置mapred-env.sh
export HADOOP_MAPRED_PID_DIR=/home/hadoop/bigdater/hadoop-2.5.0-cdh5.3.6/hdfs/tmp
第三步:配置yarn-env.sh
export YARN_PID_DIR=/home/hadoop/bigdater/hadoop-2.5.0-cdh5.3.6/hdfs/tmp
第四步:配置core-site.xml文件
<property>
<name>fs.defaultFS</name>
<value>hdfs://hh:8020</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/home/hadoop/bigdater/hadoop-2.5.0-cdh5.3.6/hdfs/tmp</value>
</property>
第五步:配置hdfs-site.xml文件
<property>
<name>dfs.replication</name>
<value>1</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>/home/hadoop/bigdater/hadoop-2.5.0-cdh5.3.6/hdfs/name</value>
</property>
<property>
<name>dfs.namenode.data.dir</name>
<value>/home/hadoop/bigdater/hadoop-2.5.0-cdh5.3.6/hdfs/data</value>
</property>
<property>
<name>dfs.permissions.enabled</name>
<value>false</value>
</property>
第六步:创建mapred-site.xml文件,直接执行命令cp mapred-site.xml.templete mapred-site.xml
第七步:配置mapred-site.xml文件
<!--指定运行mapreduce的环境是yarn-->
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
第八步:配置yarn-site.xml文件
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
第九步:配置slaves指定datanode节点,将localhost改成主机名
第十步:修改环境变量文件".base_profile",并使其生效
###### hadoop 2.5.0
export HADOOP_HOME=/home/hadoop/bigdater/hadoop-2.5.0-cdh5.3.6/
export HADOOP_PREFIX=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_PREFIX
export HADOOP_CONF_DIR=$HADOOP_PREFIX/etc/hadoop
export HADOOP_HDFS_HOME=$HADOOP_PREFIX
export HADOOP_MAPRED_HOME=$HADOOP_PREFIX
export HADOOP_YARN_HOME=$HADOOP_PREFIX
export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
8.2 spark
SparkCore
===============================================
MapReduce: 分布式的计算框架
缺点:执行速度慢
IO瓶颈 ==> 磁盘IO 网络IO
shuffle机制:数据需要输出到磁盘,而且每次shuffle都需要进行排序操作
框架的机制:
只有Map和Reduce两个算子,对于比较复杂的任务,需要构建多个job来执行
当存在job依赖的时候,job之间的数据需要落盘(输出到HDFS上)
Spark:基于内存的分布式计算框架==>是一个执行引擎
起源于加州大学伯克利分校的AMPLib实验室
官网:http://spark.apache.org/
官方博客:https://databricks.com/blog
Spark编译
http://spark.apache.org/docs/1.6.1/building-spark.html
过程见ppt
./make-distribution.sh --tgz \
-Phadoop-2.4 \
-Dhadoop.version=2.5.0 \
-Pyarn \
-Phive -Phive-thriftserver
==============================================
Spark运行模式(Spark应用运行在哪儿)
local:本地运行
standalone:使用Spark自带的资源管理框架,运行spark的应用
yarn:将spark应用类似mr一样,提交到yarn上运行
mesos:类似yarn的一种资源管理框架
Spark Local环境配置
-1. 安装好jdk(JAVA_HOME\PATH)、scala(SCALA_HOME\PATH)、HDFS等依赖服务
-2. 解压编译好的压缩包
tar -zxvf spark-1.6.1-bin-2.5.0-cdh5.3.6.tgz -C /opt/cdh-5.3.6/
-3. 创建一个软连接
cd /opt/cdh-5.3.6
ln -s spark-1.6.1-bin-2.5.0-cdh5.3.6/ spark
-4. 修改相关参数
cd spark/conf
mv spark-env.sh.template spark-env.sh
vim spark-env.sh
JAVA_HOME=/opt/modules/java
SCALA_HOME=/opt/modules/scala
### 只需要指定HDFS连接配置文件存储的文件夹路径
HADOOP_CONF_DIR=/opt/cdh-5.3.6/hadoop/etc/hadoop
SPARK_LOCAL_IP=hadoop-senior01.ibeifeng.com
-5. 测试Linux上的本地环境
./bin/spark-shell
....
17/05/14 14:36:16 INFO ui.SparkUI: Started SparkUI at http://192.168.187.146:4040
...
Spark context available as sc.
....
SQL context available as sqlContext.
README.md上传到HDFS上对应文件夹中
val textFile = sc.textFile("/beifeng/spark/core/data/README.md")
textFile.count()
textFile.first()
val linesWithSpark = textFile.filter(line => line.contains("Spark"))
==============================================
WordCount编写
## 读取hdfs上的文件形成RDD
val lines = sc.textFile("/beifeng/spark/data/word.txt")
## 转换处理
val words = lines.flatMap(line => line.split(" "))
## 类似MR来做(性能不好,有可能出现OOM)
words.groupBy(word => word).map(t => (t._1,t._2.toList.size)).take(10)
## 使用reduceByKey API
val words2 = words.map(word => (word,1))
val wordCountRDD= words2.reduceByKey(_ + _)
## 结果保存(要求输出文件夹不存在)
wordCountRDD.saveAsTextFile("/beifeng/spark/core/resulut0")
## 获取Top10 word单词
wordCountRDD.sortBy(t => t._2 * -1).take(10)
wordCountRDD.map(t => (t._2 * -1, t)).sortByKey().map(t => t._2).take(10)
wordCountRDD.map(_.swap).top(10).map(_.swap)
wordCountRDD.top(10)(ord = new scala.math.Ordering[(String,Int)]{
override def compare(x: (String,Int), y: (String,Int)): Int = {
x._2.compare(y._2)
}
})
## 获取出现次数最少的10个单词
wordCountRDD.top(10)(ord = new scala.math.Ordering[(String,Int)]{
override def compare(x: (String,Int), y: (String,Int)): Int = {
y._2.compare(x._2)
}
})
### 回顾:MR中如何实现TopN的程序
-1. 所有数据排序,然后获取前多少个
分区器:分区 ==> 将所有数据分到一个区(一个ReduceTask中)
排序器:排序 ==> 数据按照降序排列
分组器:分组 ==> 将所有数据分到同一组
在reduce方法中获取前N个数据输出即可
-2. 优化
MapTask:
在当前jvm中维持一个集合,集合大小为N+1,存储的是当前task中数据排序后最大的前N+1个数据(优先级队列)
在cleanup方法中输出前N个数据
ReduceTask:
全部数据聚合到一个reducetask,然后进行和MapTask功能类似的操作,结果在cleanup进行输出即可得到最终数据
==============================================
Spark on Standalone
Spark应用运行在Standalone资源管理框架系统上
Standalone是spark自带的一种资源管理框架,类似yarn,分布式的
yarn的框架:
NodeManager:管理当前节点的资源以及启动container
ResourceManager:管理集群资源(监控、申请...)
资源:
CPU&内存
Standalone的框架:
Worker: 执行节点服务,管理当前节点的资源及启动executor
Master: 集群资源管理及申请
资源:
CPU&内存
Standalone的配置:
1. 要求:spark的local本地模式可以成功运行
2. 修改spark-env.sh文件
SPARK_MASTER_IP=hadoop-senior01.ibeifeng.com
SPARK_MASTER_PORT=7070
SPARK_MASTER_WEBUI_PORT=8080
SPARK_WORKER_CORES=2 ## 一个worker服务中具有多少核CPU
SPARK_WORKER_MEMORY=2g ## 一个worker服务中具有多少内存
SPARK_WORKER_PORT=7071
SPARK_WORKER_WEBUI_PORT=8081
SPARK_WORKER_INSTANCES=2 ### 给定一台机器上可以启动多少个worker服务
3. mv slaves.template slaves
vim slaves===> 一行一个worker服务所在机器的主机名
4. 启动服务
sbin/start-all.sh
Spark On Standalone测试:
--master MASTER_URL spark://host:port, mesos://host:port, yarn, or local.
给定spark应用运行的位置信息(在哪儿运行??)
1. 启动spark-shell应用
bin/spark-shell --master spark://hadoop-senior01.ibeifeng.com:7070
==================================================
standalone HA配置(master HA配置)
http://spark.apache.org/docs/1.6.1/spark-standalone.html#high-availability
-1. Single-Node Recovery with Local File System
基本本地文件系统的单个Master的恢复机制
SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=FILESYSTEM -Dspark.deploy.recoveryDirectory=/tmp"
-2. Standby Masters with ZooKeeper
基于zk的master HA配置(热备)
SPARK_DAEMON_JAVA_OPTS="-Dspark.deploy.recoveryMode=ZOOKEEPER -Dspark.deploy.zookeeper.url=hadoop1:2181,hadoop2:2181,hadoop3:2181 -Dspark.deploy.zookeeper.dir=/spark"
======================================================
应用监控
-1. 运维人员有专门的监控工具进行监控,比如:zabbix等
-2. 使用CM(CDH)、Ambari(Apache、HDP)大数据的专门的运维监控工具
-3. 可以通过软件自带的web界面进行监控
-4. oozie等调度工具监控job的运行情况
-5. Linux上进行好像是可以自动恢复的吧???
=====================================================
Spark应用的监控
http://spark.apache.org/docs/1.6.1/monitoring.html
-1. 针对正在运行的应用,可以通过webui来查看,端口号默认4040
-2. 对于已经执行完成的job,可以通过spark的job history服务来查看
MapReduce Job History服务:
-1. 配置日志上传的hdfs文件夹
-2. 开启日志聚集功能(将日志上传到HDFS上)
-3. 启动mr的job history服务(读hdfs上的文件内容,然后进行展示)
Spark Job History服务:
-1. 创建HDFS上存储spark应用执行日志的文件夹
hdfs dfs -mkdir -p /spark/history
-2. 修改配置文件(开启日志聚集功能)
mv spark-defaults.conf.template spark-defaults.conf
vim spark-defaults.conf
spark.eventLog.enabled true
spark.eventLog.dir hdfs://hadoop-senior01.ibeifeng.com:8020/spark/history
-3. 配置Spark job history的相关参数
vim spark-env.sh
SPARK_HISTORY_OPTS="-Dspark.history.fs.logDirectory=hdfs://hadoop-senior01.ibeifeng.com:8020/spark/history"
-4. 启动spark的jobhistory服务
sbin/start-history-server.sh
-5. 查看web界面
http://hadoop-senior01:18080/
Spark Job History Rest API:
http://hadoop-senior01:18080/api/v1/applications
http://hadoop-senior01:18080/api/v1/applications/local-1494752327417/jobs
http://hadoop-senior01:18080/api/v1/applications/local-1494752327417/jobs/logs
====================================================
MapReduce应用架构
一个应用就是一个Job
一个Job包含两个Stage,分别是Map阶段和Reduce阶段
每个阶段一个Task任务(MapTask/ReduceTask)
ApplicationMaster + Continear
Spark应用框架
一个应用可以包含多个Job
一个Job可以包含多个Stage
一个Stage可以包含多个Tasks
执行任务角色来讲:
Driver + Executors
Driver: 进行初始化操作的进程
Executor:真正运行Task任务的进程
=================================================
作业:
1. 搭建一个spark local的环境
2. 将spark的源码导入IDEA中
3. 实现一下wordcount和topn的程序
在这个过程中结合RDD、PairRDDFunctions、OrderedRDDFunctions中的RDD相关API进行代码执行以及理解
回顾:
Scala
环境怎么搭建
基本语法
函数
元组
集合:数组、List、Set、Map
面向对象
模式匹配
1. Spark的特性、和MR的比较
2. Spark的编译
3. Spark Local的模式
4. Spark Standalone的配置
类似yarn的资源管理框架
也支持分布式的,分布式配置和单机配置一样,多一个分发的过程,以及配置ssh免密码的过程
5. Spark on Standalone运行
bin/spark-shell --master spark://xxx:port
6. Spark StandaloneHA配置
worker:无状态的,宕机后,可以将宕机worker上的任务直接移动到其它正常的worker服务上继续执行
master:
1. 基于文件的单master恢复机制
2. 基于zk的多master热备机制
7. Spark应用的构成
==========================================================
Spark on windows local
异常信息:
1. 17/05/20 09:32:08 ERROR SparkContext: Error initializing SparkContext.
org.apache.spark.SparkException: A master URL must be set in your configuration ==> 设置一个master运行位置信息
2. 17/05/20 09:33:22 INFO SparkContext: Successfully stopped SparkContext
Exception in thread "main" org.apache.spark.SparkException: An application name must be set in your configuration ==> 给定一个应用的名称
3. null/bin/winutil.exe: windows环境没有配置hadoop的缘故的导致的
====> 只需要给定一个HADOOP_HOME的环境变量
4. 可能出现源码方面的异常,一般情况提示为NullPointException,解决方案:修改hadoop底层源码 --> 如果遇到了,自己不会找小刘
==================================================
Spark on yarn
http://spark.apache.org/docs/1.6.1/running-on-yarn.html
前提:yarn的配置信息(yarn-site.xml)在spark的classpath中
bin/spark-submit \
--master yarn \
--deploy-mode client \
--class com.ibeifeng.bigdata.spark.app.core.SparkWordCount \
/home/beifeng/o2o13/logs-analyzer.jar
bin/spark-submit \
--master yarn \
--deploy-mode cluster \
--class com.ibeifeng.bigdata.spark.app.core.SparkWordCount \
/home/beifeng/o2o13/logs-analyzer.jar
local执行:(如果我们不给定master的值,默认是本地)
bin/spark-submit \
--class com.ibeifeng.bigdata.spark.app.core.SparkWordCount \
/home/beifeng/o2o13/logs-analyzer.jar
Spark应用的构成:
Driver + Executors
Driver: main方法的运行的jvm的地方;主要功能是:SparkContext上下文创建、RDD构建、RDD调度、RDD运行资源调度
Executor:具体task执行的jvm地方
Spark应用启动配置信息可以在三个地方配置:
1. spark-defaults.conf
2. spark-submit脚本参数
3. spark应用中通过SparkConf对象指定参数
优先级:1 < 2 < 3
spark-submit脚本参数 ==> Spark资源调优
http://spark.apache.org/docs/1.6.1/configuration.html#available-properties
--master:给定运行spark应用的执行位置信息
--deploy-mode:给定driver在哪儿执行
client:driver在执行spark-submit的那台机器上运行
cluster:driver在集群中任选一台机器运行
--driver-memory MEM:指定driver运行的时候jvm的内存大小,默认1G,一般情况下要求比单个executor的内存要大
--executor-memory MEM:指定单个executor的内存大小,默认1G
--driver-cores NUM: 指定spark on standalone的时候,而且是cluster模式的请看看下,driver运行过程中使用的core数量,默认1
--supervise: 当运行环境为standalone/mesos + cluster,如果driver运行失败,会重新自动进行恢复操作
--total-executor-cores NUM :运行环境为standalone/mesos,给定应用需要的总的core的数目,默认所有
--executor-cores NUM:运行环境为standalon/yarn,给定应用运行过程中,每个executor包含的core数目,默认1个(yarn),默认all(standalone)
--driver-cores NUM:spark on yarn cluster, 给定driver运行需要多少个core,默认1个
--num-executors NUM: 申请多少个executor,默认2
=====================================================
Spark on yarn job history配置
-1. 启动spark的history server
sbin/start-history-server.sh
http://hadoop-senior01:18080/
-2. 配置在yarn页面可以通过链接直接点击进入history执行页面
--1. 修改yarn-site.xml文件,然后重启yarn
<property>
<name>yarn.log.server.url</name>
<value>http://hadoop-senior01.ibeifeng.com:19888/jobhistory/job/</value>
</property>
<property>
<name>yarn.log-aggregation-enable</name>
<value>true</value>
</property>
--2. 修改spark-defaults.conf
spark.yarn.historyServer.address http://hadoop-senior01.ibeifeng.com:18080
==================================================
Spark应用构建及提交流程:
-1. Driver中RDD的构建
-2. RDD Job被触发(需要将rdd的具体执行步骤提交到executor中执行)
-3. Driver中的DAGScheduler将RDD划分为Stage阶段
-4. Driver中的TaskScheduler将一个一个stage提交到executor上执行
Spark应用的执行过程
-1. client向资源管理服务(ResourceManager、Master等)申请运行的资源(driver资源),如果是client模式下,driver的资源不用进行申请操作
-2. 启动driver
-3. driver向资源管理服务(ResourceManager、Master等)申请运行的资源(executor资源)
-4. 启动executor
-5. rdd构建
-6. rdd执行
========================================
Spark内存管理机制:
http://spark.apache.org/docs/1.6.1/configuration.html#memory-management
优化建议:如果spark应用缓存比较多,shuffle比较少,调高缓存的内存占比;反之亦然
-1. Spark1.6之前
Spark应用中代码使用内存:你编写的程序中使用到的内存=>20%
Spark数据缓存的时候用到的内存:60% => spark.storage.memoryFraction
Spark shuffle过程中使用到的内存:20% => spark.shuffle.memoryFraction
-2. Spark1.6
Reserved Memory: 固定300M,不能进行修改,作用:加载class的相对比较固定的对象以及计算最小Spark的Executor内存=1.5 * Reserved Memory = 450M
User Memory: 用户代码中使用到的内存, 默认占比:1 - spark.memory.fraction
Spark Memory: Spark应用执行过程中进行数据缓存和shuffle操作使用到的内存
spark.memory.fraction:0.75
缓存(Storage Memory)和shuffle(Execution Memory)的内存分配是动态的
spark.memory.storageFraction:0.5 ==> Storage最少固定占用的内存大小比例
-a. 如果Storage Memory和Execution Memory都是空的(都有容量)
如果有数据需要缓存,storage会占用execution部分的空余内存,同理execution也会占用storage部分的空余内存
-b. 如果storage memory满了,execution memory有空余
如果有数据缓存操作,storage会占用execution部分的空余内存
如果有执行过程内存需要,execution操作会占用storage部分的内存,会将storage部分存储的数据进行删除操作
-c. 如果storage memory有空余,execution memory满了
如果数据有缓存操作,不能占用execution部分的内存
如果有执行过程内存需要,execution操作会占用storage部分的内存
备注:execution过程中使用到的内存是不允许进行删除操作的,storage的数据可以进行删除操作
eg: 默认1G
Reserved Memory:300M
Spark Memory: ( 1G - 300M) * 0.75 = 543M
storage memory最小: 271M
User Memory: 1G - 300M - 543M = 181M
==============================================================
Spark动态资源分配
含义:指Executor的数量可以根据job中需要的资源来进行申请
http://spark.apache.org/docs/1.6.1/configuration.html#dynamic-allocation
现阶段来讲:SparkStreaming中实现的不太好,SparkCore和SparkSQL都可以应用
spark.dynamicAllocation.enabled:false,开启动态资源分配(true)
spark.dynamicAllocation.initialExecutors:初始化的时候给定默认executor的数量
spark.dynamicAllocation.maxExecutors:infinity,动态资源分配最多允许分配多少资源
spark.dynamicAllocation.minExecutors:0,动态资源最少分配的executor数量
============================================================
RDD
Resilient Distributed Datasets=>弹性分布式数据集
Resilient:可以存在给定不同数目的分区、数据缓存的时候可以缓存一部分数据也可以缓存全部数据
Distributed:分区可以分布到不同的executor执行(也就是不同的worker/NM上执行)
Datasets:内部存储是数据
RDD中的数据是不可变的、是分区的;
RDD的五大特性:见ppt
RDD构建底层原理:
-1. RDD分区数量 == InputFormat的getsplilt方法返回的集合中split的数量
-2. RDD中不包含数据,只包含数据存储的位置信息,比如split
RDD的创建
-1. 外部数据(非内存数据):基于MapReduce的InputFormat进行创建
sc.textFile ==> 底层使用TextInputFormat读取数据形成RDD;使用旧API
sc.newAPIHadoopFile ==> 底层使用TextInputFormat读取数据形成RDD;使用新API
sc.newAPIHadoopRDD ==> API指定使用那个InputFormat读取数据
-2. 内存中数据:基于序列化进行创建
scala> val seq = List(1,2,3,4,5,6,7)
seq: List[Int] = List(1, 2, 3, 4, 5, 6, 7)
scala> val rdd2 = sc.parallelize(seq)
rdd2: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[4] at parallelize at <console>:29
====================================================
RDD的方法类型(API类型)
transformation(transformation算子):转换操作
功能:由一个RDD产生一个新的RDD,不会触发job的执行
在这些类型的API调用过程中,只会构建RDD的依赖,也称为构建RDD的执行逻辑图(DAG图)
action(action算子):动作/操作
功能:触发rdd的job执行提交操作,并将rdd对应的job提交到executor上执行
该类型的API调用的时候,会触发job的执行,并将job的具体执行过程提交到executor上执行,最终的执行结果要不输出到其它文件系统或者返回给driver
pesist:(RDD缓存/RDD持久化)
rdd将数据进行缓存操作或者清除缓存的rdd数据或者数据进行了checkpoint(只在streaming中使用)
rdd.cache() 数据缓存到内存中
rdd.persist(xxx) 数据缓存到指定级别的存储系统中(内存\内存+磁盘\磁盘)
rdd.unpersist() 清除缓存数据
==================================================
Spark优化
-1. 代码优化
--a. 如果一个RDD只使用一次,那么不赋值,直接转换操作==>链式编程
--b. 对于多次使用的RDD,需要对rdd进行cache操作 --> 记住使用完成后,需要释放
--c. 优先选择reduceByKey和aggregateByKey替代groupByKey,原因是:groupByKey可能导致OOM异常,性能没有前两个API好(前两个API存在combiner操作)
-2. 资源优化(上午讲过)
-3. 数据倾斜优化
导致原因:数据重复分配不均匀导致的,可能会导致某些task执行速度比较慢或者出现OOM异常
--a. 更改分区策略(机制<自定义数据分区器>+分区数)
--b. 两阶段聚合
==================================================
RDD依赖
窄依赖
子RDD的每个分区的数据来自常数个父RDD分区;父RDD的每个分区的数据到子RDD的时候在一个分区中进行处理
常用方法:map、flatmap、filter、union、join(要求两个父RDD具有相同的partitioner同时两个父rdd的分区数目和子rdd的分区数目一致)等
宽依赖
子RDD的每个分区的数据来自所有的父RDD分区;父RDD的每个分区的数据都有可能分配到所有的子RDD分区中
常用方法:xxxxByKey、join、reparation等
SparkCore的容错
-1. driver宕机:
client: 程序直接挂了
cluster:
spark on standalone/mesos: 通过spark-submit的参数--supervise可以指定当driver宕机的时候,在其他的节点上重新恢复
spark on yarn: 自动恢复四次
-2. executor宕机
直接自动在work或者NodeManager上重新启动一个executor重新执行任务
-3. task执行失败
自动进行恢复,最大失败次数四次
-4. 如果后续rdd执行过程中,出现数据丢失,容错的方式为:rdd lineage(生命线) ==> RDD的依赖
提供的一种容错机制,当子RDD执行失败的时候,可以直接从父RDD进行恢复操作;如果父RDD的执行结果进行了缓存操作,子RDD直接从缓存位置获取结果数据;如果cache的不是全部数据的话,那么部分数据从缓存中读取,其它数据从父RDD的数据来源读取(会存在父RDD的代码逻辑的执行);如果子RDD失败的是单个分区,那么如果父rdd和子rdd的关系是窄依赖,只需要恢复父rdd对应分区的数据即可,如果关系是宽依赖,需要将所有父rdd的数据都执行一遍
================================================
Spark应用的组成
Driver + Executors
Driver: SparkContext上下文的构建、RDD的构建、RDD的调度
Executor:具体task执行的位置
一个application ==> 多个jobs
一个job ==> 多个stage
一个stage ==> 多个task
Job的产生:由于调用了RDD的action类型的API,所以触发rdd对应的job提交到executors中执行
Stage:
当RDD的DAG图进行提交之前,Driver中的SparkContext中的DAGScheduler会DAG进行划分,形成Stage;划分规则:从DAG图的最后往前推,直到遇到一个宽依赖的API,那么就形成一个Stage,继续直到第一个RDD
Stage的执行是有依赖关系的,前一个Stage的数据结果是后一个Stage的数据的输入;只有上一个Stage中的所有task都执行完了下一个Stage才会执行
Task:
是Executor中执行的最小单位
task实质上就是分区,一个分区的数据的代码执行就是一个Task
分区:从数据的分布情况来讲
task:从数据的执行逻辑情况来讲
每个Task中的执行逻辑是一样的,只有处理的数据不一样,代码逻辑其实就是RDD的API组成的一个执行链
Spark提交流程:
-1. RDD调用transformation类型的API形成RDD的DAG执行图
-2. RDD调用action类型的API触发job执行的提交操作
-3. SparkContext中的DAGScheduler对RDD的DAG执行图进行Stage的划分
-4. SparkContext中的TaskScheduler对Stage进行task任务提交执行,将task提交到executor中执行(进行调度操作)
-5. 等待task执行完成,当一个stage的所有task均执行完成后,开始下一个stage的调度执行,直到job执行完成
Spark应用的执行过程
Driver + Executor
spark on yarn:
client:
driver: 负责applicationmaster的资源申请和任务调度
applicationMaster:Executor中的资源申请
Executor:Task执行
cluster:
dirver(ApplicationMaster): 资源申请和任务调度
Executor:Task执行
===============================================
Spark Shuffle
只存在于RDD的宽依赖中,有一个宽依赖就一个shuffle过程
由Spark Shuffle Manager进行管理,参数spark.shuffle.manager:sort
http://spark.apache.org/docs/1.6.1/configuration.html#shuffle-behavior
Shuffle优化:
-1. Spark Shuffle Manager:sort
当task的数量小于200的时候,会自动启动by_pass模式(没有数据排序的操作)
spark.shuffle.sort.bypassMergeThreshold:200
-2. Spark Shuffle Manager:hash
当应用中的数据不需要进行排序的时候,可以直接考虑使用hash shuffle manager;当使用hash shuffle manager的时候(当分区数比较多的),需要将参数:spark.shuffle.consolidateFiles设置为true,表示开启文件合并功能
================================================
Spark Scheduler
http://spark.apache.org/docs/1.6.1/configuration.html#scheduling
http://spark.apache.org/docs/1.6.1/job-scheduling.html
Spark的job调度分为FIFO(先进先出)和FAIR(公平调度)
FIFO: 按照提交的时间顺序执行job任务
FAIR:并行执行job任务,按照自愿的需求量进行分配
注意:在某些场景下,将调度策略改为FAIR有一定的执行效率的提升,如果一个job执行的时间比较长,但是资源没有得到充足的利用,而且还有后续没有依赖的job需要执行的情况; 一般建议为FIFO
================================================
共享变量
http://spark.apache.org/docs/1.6.1/programming-guide.html#shared-variables
broadcast variables and accumulators.
广播变量(broadcast variables)
http://spark.apache.org/docs/1.6.1/programming-guide.html#broadcast-variables
功能:减少driver到executor的数据传输量,可以通过广播变量实现map join
注意:
1. 广播变量一经广播,变量不允许被修改
2. 广播变量在executor中的存储在storage memory部分,如果task在运行的过程中发现storage memory中不存在对应的值,会重新从driver中获取
3. 如果广播变量不用了记住删除清空操作
累加器(accumulators)
注意:累加器是在executor中进行数据累加操作,在driver中进行数据读取操作(executor中不允许数据读取操作)
===================================================
SparkCore总结
起源
Spark的四种运行模式
local
standalone
yarn
mesos
Spark的应用组成
driver + Executors
application + job + Stage + Task(Partition)
driver的两种运行模式:
client
cluster
Spark Standalone的配置
spark的容错
RDD是什么??
RDD的三大类方法/API?
RDD的依赖 ==> lineage
宽依赖
存在shuffle以及stage的划分
窄依赖
Spark Shuffle:
sort:基于数据排序的shuffle
hash: 基于数据hash的shuffle
Spark的内存管理的机制+动态资源分配
Spark的Job调度
FIFO和FAIR
job的提交执行流程(结合wordcount介绍一下)
Spark应用的监控
4040
spark job history
重点的重点:Spark优化
-1. 代码优化
-2. 资源优化
-3. 数据倾斜优化
-4. shuffle优化
额外:相关代码的编写
-1. WordCount
-2. TopN(N比较大和N比较小)
-3. 分组排序TopN(类比MapReduce的二次排序)
====================================
作业:
-1. 源码熟悉
RDD
PairRDDFunctions
OrderedRDDFunctions
SparkContext
额外:DAGScheduler和TaskScheduler的代码实现策略
-2. 编写PPT后三页的作业
下次上课(周六)晚上讲
==================================
def map[U: ClassTag](f: T => U): RDD[U]
def flatMap[U: ClassTag](f: T => List[U]): RDD[U]
共同点:对于RDD中的所有数据,都执行一次给定的参数f进行数据转换操作
不同点:
map:f返回什么数据类型。RDD中的数据就是什么数据类型
flatMap: f必须返回一个集合数据类型,最终RDD的数据类型是f函数返回的集合数据类型中国的具体的数据类型;扁平化操作