Spark 集群配置(standalone)
此为纯干货
喊话橙子精:我放弃那篇论文总结了。。。寒假前在离开实验室的那天系统抽风了,来学校这两天基本花在重新装系统配环境上了
铺垫一下
在Spark中除了在单机上运行的local模式以外,共有三种分布式部署方法:
local
运行在单机上,一般用于测试和开发standalone
需要构建由Master+Slave构成的Spark集群。因此为独立模式,自带完整的服务,可单独部署到一个集群中,无需依赖任何其他资源管理系统Spark on Mesos
Spark客户端直接连接Mesos,不需要额外构建Spark集群。这是很多公司采用的模式,官方推荐这种模式,比运行在Yarn上更加灵活。有两种调度模式供用户选择使用:
须知: 每个应用程序的运行环境由一个Dirver和若干个Executor组成,其中,每个Executor占用若干资源,内部可运行多个Task(与“slot”数对应)(各个节点上的资源被抽象成粗粒度的slot)
1) 粗粒度模式(Coarse-grained Mode):“独占式”,应用程序的各个Task正式运行之前,需要将运行环境中的资源全部申请好,且运行过程中要一直占用这些资源,即使不用,最后程序运行结束后,才可回收这些资源。一定程度上可以认为,每个应用程序利用mesos搭建了一个虚拟集群自己使用。 缺点很明显,会造成资源浪费
2) 细粒度模式(Fine-grained Mode):“共享式”,按需分配。也需要在程序启动时先启动Executor,但是每个Executor占用的资源仅供自己运行,不需要考虑即将要运行的Task。之后,mesos会为每个executor动态分配资源,每分配一些,便可以运行一个新任务,单个Task运行完之后可以马上释放对应的资源。每个Task完全独立,优点是便于资源控制和隔离,但缺点也很明显,短作业运行延迟大。Spark on Yarn
Spark客户端直接连接Yarn,不需要额外构建Spark集群。目前仅支持粗粒度模式(Coarse-grained Mode)1,支持两种模式:
1) yarn-cluster:适用于生产环境
2) yarn-client:适用于交互、调试,立即看到app的输出
进入正题–Standalone部署
本人使用两台机器做配置,这两台设备连在同一个局域网中,均为Linux,部署Standalone的前提是已经安装好JDK/Hadoop/Spark,如未安装请参考Spark安装(仅需在Master上安装Hadoop和Spark即可,可以直接scp -r
将配置好的hadoop和Spark传过去)
所有机器统一创建一个非root用户测试比较好,本人目前使用的还是root,若选择创建新用户不要忘记为其添加管理员权限
1.修改主机名(每台)
1)将/etc/hostsname内容修改为Master或Slaver-n,使用gedit编辑文档命令如下(若使用的是root用户,则无需加上sudo)(需reboot系统才可生效):
sudo gedit /etc/hostname
2)在/etc/hosts中修改各个节点的IP与主机名的对应:
sudo gedit /etc/hosts
修改如下:
172.31.72.111 Master
172.31.72.115 Slave1
2.安装SSH(每台)
原理:在Master上生成一个**对,包括一个公钥和一个私钥,而后将公钥复制到所有的Slave上。当Master通过SSH连接Salve时,Salve就会生成一个随机数并用Master的公钥对随机数进行加密,并发送给Master。Master收到加密数之后再用私钥解密,并将解密数回传给Slave,Slave确认解密数无误之后就允许Master进行连接了。这就是一个公钥认证过程,其间不需要用户手工输入密码,保证了集群中的数据传输。
先切换至root,直接su回车输入密码即可
1)安装:
sudo apt-get install ssh
*卸载:
apt-get purge openssh-server
2)查看SSH进程:
ps -e|grep ssh
3)生成**对:
ssh-****** -t rsa -P "" //-t 指定生成RSA类型的**以及管理**
一直回车,会在/root/.ssh/文件夹下生成id_rsa id_rsa.pub
id_rsa – 私有**
id_rsa.pub — 公有**
4)把id_rsa.pub追加到authorized_key里面去,因为authorized_keys可以用来保存所有允许当前用户登录到SSH客户端用户的公钥内容,从而实现无**通信:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
5)使用gedit修改/etc/ssh/sshd_config 文件,使得本机允许远程连接,做如下修改:
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile %h/.ssh/authorized_keys
PermitRootLogin yes
6)重启ssh服务
service ssh restart
5)给权限:
chmod 600 authorized_keys
chmod 700 ~/.ssh
7) 把master里的pub复制到slave1(若有多台机器不要遗漏):
scp /root/.ssh/id_rsa.pub root@slave1:/root/.ssh/id_rsa.pub_sl
8)切换到slave1,把传输过来的公钥追加到authorized_keys里面(若有多台机器不要遗漏):
cat id_rsa.pub_sl >> authorized_keys
9)验证,在Master上输入:
ssh slave1
!!!!!!!!!!!!!!!!
很重要:每台机器上都要配置SSH
!!!!!!!!!!!!!!!!
3.Hadoop配置
1)修改 /etc/profile(每台!)添加如下内容,使得hadoop命令在当前终端立即生效:
export HADOOP_HOME=/usr/hadoop/hadoop-2.7.5
export PATH=$PATH:$HADOOP_HOME/bin
export HADOOP_HOME_WARN_SUPPRESS=1
2)修改~/.bashrc(Master即可),把Hadoop 安装目录加入 PATH 变量中,这样就可以在任意目录中直接使用 hadoo、hdfs 等命令:
export JAVA_HOME=/usr/java/jdk1.8.0_151
export PATH=$PATH:/usr/hadoop/hadoop-2.7.5/bin:/usr/hadoop/hadoop-2.7.5/sbin
使配置文件立即生效:
Source ~/.bashrc
以下是在Haoop/ 文件下的做的配置,可以在Master上统一配置完成后发送给各个salve
3) 在本地文件系统创建以下文件夹:./hadoop/tmp、./dfs/data、./dfs/name (mkdir
)
4) 在hadoop-env.sh配置文件中指定JDK环境
gedit /usr/hadoop/hadoop-2.7.5/etc/hadoop/hadoop-env.sh
添加:
export JAVA_HOME=/usr/java/jdk1.8.0_151
export HADOOP_CONF_DIR=usr/hadoop/hadoop-2.7.5/etc/hadoop
使得配置生效:
source hadoop-env.sh
测试是否配置成功:
hadoop version
sour
5) 配置yarn-env.sh
添加:
export JAVA_HOME=/usr/java/jdk1.8.0_151
使得配置生效:
source yarn-env.sh
6)修改Hadoop核心配置文件etc/hadoop/core-site.xml,通过fs.default.name指定 NameNode 的 IP 地址和端口号,通过hadoop.tmp.dir指定hadoop数据存储的临时文件夹:
特别注意:如没有配置hadoop.tmp.dir参数,会指向系统默认的临时目录,而这个目录在每次重启后都会被删除,必须重新执行format才行,否则会出错
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://Master:9000</value> 端口是否打开,因为所有的DataNode都要通过这个端口连接NameNode
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://Master:9000</value> <!--端口是否打开,因为所有的DataNode都要通过这个端口连接NameNode-->
</property>
<property>
<name>io.file.buffer.size</name>
<value>131072</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>file:/usr/hadoop/hadoop-2.7.5/tmp</value>
<description>Abasefor other temporary directories.</description>
</property>
<property>
<name>hadoop.proxyuser.spark.hosts</name>
<value>*</value>
</property>
<property>
<name>hadoop.proxyuser.spark.groups</name>
<value>*</value>
</property>
</configuration>
7)修改HDFS核心配置文件etc/hdfs-site.xml,通过dfs.replication指定HDFS的备份因子(节点个数),通过dfs.name.dir指定namenode节点的文件存储目录,通过dfs.data.dir指定datanode节点的文件存储目录:
<configuration>
<!-- 设置namenode的http通讯地址 -->
<property>
<name>dfs.namenode.http-address</name>
<value>master:50070</value>
</property>
<!-- 设置secondarynamenode的http通讯地址 -->
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>slave1:50090</value>
</property>
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/usr/hadoop/hadoop-2.7.5/dfs/name</value>
</property>
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/usr/hadoop/hadoop-2.7.5/dfs/data</value>
</property>
<property>
<name>dfs.replication</name>
<value>3</value>
</property>
<property>
<name>dfs.webhdfs.enabled</name>
<value>true</value>
</property>
<property>
<name>dfs.block.size</name>
<value>268435456</value>
</property>
<property>
<name>dfs.client.block.write.replace-datanode-on-failure.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
<value>NEVER</value>
</property>
</configuration>
8)配置mapred-site.xml,一般情况下,只有一个mapred-site.xml.template ,cp mapred-site.xml.template mapred-site.xml
复制出来一份即可:
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
9)Yarn-site.xml
<configuration>
<property>
<name>yarn.resourcemanager.hostname</name>
<value>Master</value>
</property>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
10)配置slaves文件(指明哪几个节点作为Datanode)
有各种说法,用IP好/用主机名好
本人使用的是主机名:
Master
Slave1
…
Slaven
11)将配置好的hadoop文件copy到另一台slave机器上
scp -r /usr/hadoop/hadoop-2.7.5 root@slave1:/usr/hadoop/hadoop-2.7.5
(-r 因为是文件夹)
12)验证(only Master)
先格式化namenode
hadoop namenode -format
13)启动hdfs (在spark中只要启动hdfs和yarn就好) (only Master)
./sbin/start-dfs.sh
注意!!!!启动前取保防火墙关闭:ufw disable
不然datanode会开启后又自动关闭(!deepin下本就没有开启防火墙,无论iptables还是ufw都没启用)
14)jps 查看启动进程(每台)
如果遇上jps找不到,就Source /etc/profile
15)启动yarn
cd /app/hadoop/hadoop-2.6.0/sbin
./start-yarn.sh
4.配置Spark
(每台配好环境变量先,在/etc/profile文件中)
如下:
export JAVA_HOME=/usr/java/jdk1.8.0_151
export PATH=$JAVA_HOME/bin:$PATH
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export IDEA_JDK=/usr/java/jdk1.8.0_151
export PATH="$PATH:/usr/scala/scala-2.11.11/bin"
export SPARK_HOME=/usr/spark/spark-2.1.1-bin-hadoop2.7
export PATH=$PATH:${SPARK_HOME}/bin
export HADOOP_HOME=/usr/hadoop/hadoop-2.7.5
export PATH=$PATH:$HADOOP_HOME/bin
export HADOOP_HOME_WARN_SUPPRESS=1
说明:本人搭建的测试集群中只有两个节点
节点cpu信息:slave1双核,master4核
1)配置conf/spark-env.sh
cp spark-env.sh.template spark-env.sh
gedit spark-env.sh
添加如下:
export JAVA_HOME=/usr/java/jdk1.8.0_151
export HADOOP_HOME=/usr/hadoop/hadoop-2.7.5
export SPARK_MASTER_IP=Master
export SPARK_MASTER_PORT=7077
export SPARK_WORKER_CORES=2 //Spark应用程序可以使用的核数
export SPARK_WORDER_INSTANCES=1
export SPARK_WORKER_MEMORY=2g //Spark应用程序可以使用的总内存数
export SPARK_MASTER_WEBUI_PORT=8080
export SPARK_HISTORY_OPTS="-Dspark.history.ui.port=18080 -Dspark.history.retainedApplications=3 -Dspark.history.fs.logDirectory=hdfs://Master:9000/directory "
export SPARK_CONF_DIR=/usr/spark/spark-2.1.1-bin-hadoop2.7/conf
2)修改Spark-default.conf文件
spark.master spark://Master:7077
spark.eventLog.enabled true
spark.eventLog.dir hdfs://Master:9000/directory
spark.eventLog.compress true
spark.executor.memory 2g
参数说明:每个executor可使用的内存,默认为1G(对应于在spark-submit 时提交的参数 --executor-memory)
spark.executor.cores 2
参数说明:每个executor的核数,默认为2(对应于在spark-submit 时提交的参数 --executor-cores)
spark.cores.max 4
参数说明:所有executor总共核数(对应于在spark-submit 时提交的参数 --total-executor-cores)
4)配置slaves(指定那些节点作为worker)
Master
slave1
5)把spark分发到各个节点:
scp -r /usr/spark/spark-2.1.1-bin-hadoop2.7 root@slave1:/usr/spark/spark-2.1.1-bin-hadoop2.7
6)启动spark:
./sbin/start-all.sh
7)启动history服务,查看程序的详细情况:
./start-history-server.sh
8)查看
在浏览器输入 locahost:8080
9)验证客户端连接
进入slave1节点,进入spark的bin目录,使用spark-shell连接集群
cd /app/hadoop/spark-1.1.0/bin
spark-shell --master spark://spark1:7077 --executor-memory 500m
在命令中只指定了内存大小并没有指定核数,所以该客户端将占用该集群所有核并在每个节点分配500M内存
关闭Master节点:
sbin/stop-master.sh
关闭Spark:
sbin/stop-all.sh
关闭hdfs集群:
sbin/stop-dfs.sh
10)总结提供查看详细情况的web:
-HDFS:Master:50070 (查看datanode的information)
Slave1:50090 (查看secondarynamenode的information)
-history:localhost:18080
-Spark:localhost:8080
-关于4040端口:
可以通过localhost:4040访问,但必须先启动SparkContext。比如命令:./bin/spark-shell,4040页面只有在有spark 任务运行时才能访问,提交job后Spark-UI才会启动。当任务运行完了,立马端口就释放了。spark-history 页面,可以查看已经finished的job
后记/遇到的问题(不定期更新中)
1.spark上使用HDFS上的数据:
val lines = sc.textFile(“hdfs://master:9000/library/README.txt”)
2. 必须的HDFS操作
hdfs dfs -mkdir -p /directory //建立directory文件夹(一定)
hdfs dfs -put README.txt /test/README.txt
3.用Spark自带求PI的例子,测试集群是否成功(提交自带的jar包):
./bin/spark-submit --master spark://172.31.72.182:7077 --class org.apache.spark.examples.SparkPi --executor-memory 1g /usr/spark/spark-2.0.2-bin-hadoop2.6/examples/jars/spark-examples_2.11-2.0.2.jar
4.更多关于history-server页面的问题请参考:Spark中的监控—-日志聚合的配置,以及REST Api
5.集群中有4个节点,HDFS的备份数设置为3,测试数据集为HIGGS(7.48GB),异常中止:
18/03/21 04:14:02 ERROR DFSClient: Failed to close inode 39566
java.io.IOException: Failed to replace a bad datanode on the existing pipeline due to no more good datanodes being available to try.
尝试:( 参考:hadoop常见错误及解决方法)
修改hadoop下的hdfs-site.xml
<property>
<name>dfs.client.block.write.replace-datanode-on-failure.enable</name>
<value>true</value>
</property>
<property>
<name>dfs.client.block.write.replace-datanode-on-failure.policy</name>
<value>NEVER</value>
</property>
6.自动负载均衡hadoop文件:hadoop balancer
查看各节点的磁盘占用情况 hadoop dfsadmin -report
查看文件的备份系数:hadoop dfs -ls [filename]
查看hadoop集群的备份冗余情况:hadoop fsck /
修改hdfs文件备份系数:hadoop dfs -setrep [-R] path 如果有-R将修改子目录文件的性质。hadoop dfs -setrep -w 3 -R /user/hadoop/dir1 就是把目录下所有文件备份系数设置为3.
参考:设置hdfs副本数
7.设置哪些选项来自动清除已经停止运行的application的文件夹呢?
spark-env.sh中加入如下内容
SPARK_WORKER_OPTS=”-Dspark.worker.cleanup.enabled=true”
Spark 的Job任务在运行过程中产生大量的临时目录位置,导致某个分区磁盘写满,主要原因spark运行产生临时目录的默认路径/tmp/spark*, 建议优化应用程序或更改日志路径到/home/ 子目录下
spark-env.sh下增加
export SPARK_LOCAL_DIRS=/usr/spark/tmp/
/spark/work/目录下存放提交的任务程序定时删除,否则占用磁盘空间
上一篇: 分布式事务笔记