搭建spark+hadoop平台
1、安装jdk
2、安装scala,更改/etc/profile
加入:
export SCALA_HOME=/root/bigData/scala-2.11.8
export PATH=${SCALA_HOME}/bin:$PATH
source /etc/profile 生效
测试:直接输入scala
3、设置ssh免密登录
设置本地路由:/etc/hosts
xxx.xxx.xxx.xxx Master
xxx.xxx.xxx.xxx Slave1
Master上用ssh生成rsa密匙对:ssh-keygen -t rsa (-t是type的意思)
将其复制到Slave1上:scp ~/id_rsa.pub ubuntu@Slave1:~/.ssh/ (ubuntu为Slave用户名,Slave1为域名或ip)
Slave1上将id_rsa.pub的内容追加到~/.ssh/authorized_keys里:cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
Master上测试:ssh ubuntu@Slave1 (可以直接切换上Slave1上的shell则成功,输入exit可退出)
注意:在Master上也要把自己生成的id_rsa.pub的内容加到authorized_keys里,才能ssh localhost 免密登录到自己
另外免密登录通常是当前主机的用户名登录到另外一台主机,所以另外一台主机的用户一定要有现在这台主机的用户一样的用户名
3-1、修改主机名
临时修改:hostname name
查看:hostname
永久修改:vi /etc/hostname
原因:开始没有修改主机名,可是在生成免密登录时,发现,公钥后来是用户@主机名,与用户@域名相似,所以为避免麻烦,可一些问题,我还是改了
4、安装hadoop
下载安装包 wget http://mirrors.hust.edu.cn/apache/hadoop/common/hadoop-2.7.3/hadoop-2.7.3.tar.gz
解压:tar -zxvf hadoop-2.7.3.tar.gz
加入环境变量:
在hadoop-env.sh中加入JAVA_HOME地址,不然会出现JAVA_HOME is not set and could not be found
export SCALA_HOME=/root/bigData/scala-2.11.8
export PATH=${SCALA_HOME}/bin:$PATH
生效:source /etc/profile
检验:hadoop version
5、配置hadoop
设置节点:vi hadoop-2.7.3/etc/hadoop/slaves
加入: Slave1 (这个为节点的域名或ip,有更多的节点可以换行写,如果加上Master则说明,要在Master上运行DataNode)
Master
配置:core-site.xml <configuration> <property>
<name>fs.defaultFS</name> <value>hdfs://Master:9000</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/root/bigData/info/tmp/hadoop</value> <description>keep the log and .out</description> </property> <property> <name>fs.permissions.umask-mode</name> <value>002</value> <description>use the permissions when create the file or directory</description> </property> <property> <name>io.file.buffer.size</name> <value>131072</value>
<description>128kb,默认为4kb,4096</description>
</property> </configuration>
配置hdfs-site.xml
<configuration> <property> <name>dfs.replication</name> <value>2</value> <description>file replication total count,默认为3</description> </property> <property> <name>dfs.namenode.name.dir</name> <value>file:///root/bigData/info/hadoop/hdfs/name</value> <description> namenode 用来持续存放命名空间和交换日志的本地文件系统路径 </description> </property> <property> <name>dfs.datanode.data.dir</name> <value>file:///root/bigData/info/hadoop/hdfs/data</value> <description> DataNode 在本地存放块文件的目录列表,用逗号分隔,这里由于nameNode与dataNode配置不一样所以设的不一样,后来又设为一样了 </description> </property> <property> <name>dfs.namenode.http-address</name> <value>Master:50070</value> <description> NameNode 通过当前参数 获得 fsimage 和 edits </description> </property>
<property> <name>dfs.namenode.secondary.http-address</name> <value>Slave1:50090</value> <description> secondNameNode 通过当前参数 获得 fsimage 和 edits,这里放在Slave1上不然如不配置secondNameNode会默认运行在Master上</description> </property>
</configuration>
配置mapred-site.xml
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> <property> <name>mapreduce.jobtracker.http.address</name> <value>Master:50030</value> </property> <property> <name>mapreduce.jobhistory.address</name> <value>Master:10020</value> </property> <property> <name>mapreduce.jobhistory.webapp.address</name> <value>Master:19888</value> </property> <property> <name>mapreduce.jobtracker.address</name> <value>Master:9001</value> </property> </configuration>
配置yarn-site.xml
<configuration> <!-- Site specific YARN configuration properties --> <property> <name>yarn.resourcemanager.hostname</name> <value>Master</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.resourcemanager.address</name> <value>Master:8032</value> </property> <property> <name>yarn.resourcemanager.scheduler.address</name> <value>Master:8030</value> </property> <property> <name>yarn.resourcemanager.resource-tracker.address</name> <value>Master:8031</value> </property> <property> <name>yarn.resourcemanager.admin.address</name> <value>Master:8033</value> </property> <property> <name>yarn.resourcemanager.webapp.address</name> <value>Master:8088</value> </property> </configuration>
5、启动及预操作
在Master格式化namenode
hadoop namenode -format (or hdfs namenode -format)
(DEPRECATED: Use of this script to execute hdfs command is deprecated. Instead use the hdfs command for it)
验证:Exiting with status 0 表示成功,在unix中0表示成功,1表示失败
注意:格式化前可以先自定义集群名字,如果未定义,系统将自动生成 。
hadoop namenode -format -clusterid clustername
启动:可以一个个启动也可以./start-all.sh
为了避免刚安装上有些未知错误,这里一步步启动
启动hdfs: ./start-dfs.sh
(插曲:安装clustershell, apt-get install clustershell, 然后在/etc/clustershell/下建立groups文件,这里输入hadoop:Master,Slave1,保存,然后运行:clush -g hadoop -a -b jps,可以查看集群的运行的java进程)
(不过我这里有点错,找不到Master的jps,在Master本可以,不知道原因:)
启动hdfs后,查看java进程. (可以看到在Master上运行有DataNode与NameNode,在Slave1上运行有DataNode)
但是发现一个问题,Secondarynamenode没有在Slave1上启动起来,查看cat /root/bigData/hadoop-2.7.3/logs/hadoop-root-secondarynamenode-Slave1.log,发现:
java.net.BindException: Port in use: Slave1:50090 at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:919) at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:856) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.initialize(SecondaryNameNode.java:276) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.<init>(SecondaryNameNode.java:192) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.main(SecondaryNameNode.java:671) Caused by: java.net.BindException: Cannot assign requested address at sun.nio.ch.Net.bind0(Native Method) at sun.nio.ch.Net.bind(Net.java:433) at sun.nio.ch.Net.bind(Net.java:425) at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223) at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) at org.mortbay.jetty.nio.SelectChannelConnector.open(SelectChannelConnector.java:216) at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:914) ... 4 more 2016-09-03 11:12:12,364 FATAL org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: Failed to start secondary namenode java.net.BindException: Port in use: Slave1:50090 at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:919) at org.apache.hadoop.http.HttpServer2.start(HttpServer2.java:856) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.initialize(SecondaryNameNode.java:276) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.<init>(SecondaryNameNode.java:192) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.main(SecondaryNameNode.java:671) Caused by: java.net.BindException: Cannot assign requested address at sun.nio.ch.Net.bind0(Native Method) at sun.nio.ch.Net.bind(Net.java:433) at sun.nio.ch.Net.bind(Net.java:425) at sun.nio.ch.ServerSocketChannelImpl.bind(ServerSocketChannelImpl.java:223) at sun.nio.ch.ServerSocketAdaptor.bind(ServerSocketAdaptor.java:74) at org.mortbay.jetty.nio.SelectChannelConnector.open(SelectChannelConnector.java:216) at org.apache.hadoop.http.HttpServer2.openListeners(HttpServer2.java:914) ... 4 more 2016-09-03 11:12:12,368 INFO org.apache.hadoop.util.ExitUtil: Exiting with status 1 2016-09-03 11:12:12,368 INFO org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode: SHUTDOWN_MSG: /************************************************************ SHUTDOWN_MSG: Shutting down SecondaryNameNode at Slave1/123.207.82.234
端口被占用,但是在Slave1上用lsof -i:50090与netstate -anp并没有发现占用端口的进程,不知道什么原因,弄了一天也没有解决,可能是腾讯云的问题。
然后我将Slave1又改回Master这样,在Master上可以启动secondaryNameNode,将就这样吧。实在是穷途陌路,没有找到解决办法,如果要解决我想只有重装一下机子了。
后来补充:原来腾讯云无法用外网绑定端口,所以不得行,暂时没有好的解决办法。参考最后面网址
解决:我后来,把腾讯云的hosts中的Slave1改为了内网ip就可以在腾讯云上启动secondaryNameNode了。
6、最后效果:启动./start-dfs.sh与./start-yarn.sh后(就是运行./start-all.sh)
在http://Master:50070 (这是dfs的)
在http://Master:8088 (这是yarn的)
好的这下就可以了
7、这过程中遇到问题:
1、Slave1不能ping通Master,Master不通ping通Slave1,且Slave1不能ping通外网?
由于用的腾讯云,开始时我设置安全组仅公开放了22,80,8080端口,而ping需要开通3389外网访问,才行,于是我又改安全组为默认策略全部开放就好了。
2、启动集群后,网页Master:50070,只显示一个DataNode,另一个节点没有检测到,deadnode也为0,这说明没有连接上Slave1,而且slave1下的data文件夹下没有内容,至少有个current/VERSION吧?
由于我设置的安全组没有对外开发相应端口,同样,把安全组设置策略全部开放就好了。然后删除了 hdfs的tmp,logs,name,data下面的文件,重启,重新format就好了。
8、安装spark
1) 下载spark的压缩包,spark-2.0.0-bin-hadoop2.7.tgz,解压,我这里解压到bigData下面
2)配置环境变量:在/etc/profile中加入
export SPARK_HOME=/root/bigData/spark-2.0.0-bin-hadoop2.7
export PATH=${SPARK_HOME}/bin:$PATH
3) 配置spark-env.sh, 复制一份spark-env.sh.template,然后里面有详细的说明,我加下如下:
export HADOOP_CONF_DIR=/root/bigData/hadoop-2.7.3/etc/hadoop
export SPARK_DRIVER_MEMORY=512M #默认为1G,最小为512M左右,由于我买的云服务器内存只有1G所以设成512M,不然会报内存无法分配的错误。
4)运行测试:spark-shell
运行后可以访问spark 单机webUI:http://XXX.XXX.XXX.XXX:4040/
5) 运行spark算法
spark-submit SparkPi 10
成功正确运行,环境搭建完毕
6) 启动spark集群,start-all.sh
可能提示JAVA_HOME not find,可能是集群的运行的环境变化和单机是分开的,需要重新设置,于是在spark-env.sh中加上:
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0_101
启动成功
可以访问spark 集群webUI:http://XXX.XXX.XXX.XXX:8080/
现在可以看到集群中只有一台机子
在conf下有个Slaves.template文件,复制成Slaves然后加入节点:
Master
Slave1
然后重新启动./stop-all.sh, ./start-all.sh
在上面网站上就可以看到两个worker
在Master上的所有java进程
在Slave1上的所有java进程
spark web集群管理页面
这里有两个worker,注意ip,我这里用了一个阿里云,一个腾讯云,其中腾讯云用的是内网ip, 因为腾讯云用外网ip访问不了端口,不知道什么原因(我安全组策略是全开放的),可能由于腾讯云都是弹性动态ip吧,所以是由网关转发原因造成,阿里云没有这些问题存在。
开始用外网ip,在spark-env.sh中
export SPARK_LOCAL_IP=10.104.73.84 //这里绑定主机ip,在阿里云中不用设此项默认为外网ip, 在腾讯云如果不设或者设成外网ip会出错,提示端口冲突'sparkWorker' could not bind on port 0. Attempting port 1.等,设成内网ip就好了,设成0.0.0.0也可以,所以腾讯云中最好自身用内网ip操作,外面的事务请求才用外网ip(网关过滤转发)
所以虽然一个直接设了外网ip,一个设了内网ip,但是最终也都能从外网ip访问(腾讯云是通过外网访问云网关,再由网关转发到相应服务器,所以只要安全组的端口开放的,那么就会转化请求到服务器,服务器作出响应)
http://blog.csdn.net/chenggong2dm/article/details/51475222 (从这文中受到启发,也可以通过0.0.0.0实现对公网ip的绑定,也可以用内网ip代替)
腾讯云非常奇怪,无法绑定公网IP。对于服务器应用程序来讲,有点蛋疼。
解决办法是绑定 0.0.0.0 以实现对公网IP的绑定。
9、spark几种部署方式理解
http://www.cnblogs.com/jingblogs/p/5716139.html
yarn: 只需要在一个node上安装spark,然后spark-submit提交作业到yarn,实际上是由yarn在运行。
standalone: 类hadoop,在每台机子上部署,并且无单点问题。