搭建Hadoop+Spark集群的方法
这篇文章主要是介绍了怎么在Linux平台下搭建Hadoop与Spark集群,得声明一点的是Spark并不依赖于Hadoop。Hadoop有自己的资源管理者ResourceManager,YARN(Yet Another Resource Negotiator)。Spark经常需要搭配其他的资源管理者使用,常见的有YARN,Mesos
Hadoop是一个由Apache所开发的分布式系统架构,可以简单理解成由两部分构成:1.HDFS(Hadoop Distributed File System)分布式存储系统,一个由多台计算机相互连接组成的存储系统,避免了单个计算机存储的高昂代价 2.MapReduce(一种计算模式)。那什么是Spark呢?它的出现正是来弥补MapReduce计算模式中的缺陷的,原来MapReduce处理数据的方法是先将大数据的文本划分为非常小的文件,并将其分布到集群上,集群上的每个计算机处理一个文件,这个过程叫做Map,即映射。接着集群上的单个计算机会对单个文件进行处理,这个文件处理并不一定是一次完成的,比如机器学习中会有很多迭代的算法,因此计算机会把迭代完一次的处理结果送回给集群中,接着又从集群中读取更新后的数据,进行下一次的处理。集群上所有的计算机进行处理后,就要在相邻节点之间进行数据两两的统计合并,最后汇集成一个结果文件,这个过程叫做Reduce,值得指出的一点是,Map的执行过程是高度并发的,而Reduce虽然也是并发的,但是其并发度显然没有Map高。显然在多次迭代的过程中MapReduce就产生了很高的时延,因为它要多次进行I/O操作。Spark的处理是基于抽象数据结构RDD(Resilient Distributed Dataset)弹性分布式数据集,它既可以在内存中,也可以在磁盘里,在进行多次迭代操作时,数据会在内存中完成操作,减少了磁盘的I/O操作,因此大大降低了时延,Spark相比于Hadoop的处理速度提高了几十甚至百倍。
##下面分开讲,先具体讲解如何搭建Hadoop,然后再讲搭建Spark(参考了王家林老师的书籍)
##搭建Hadoop集群
步骤总体有如下几点:
-
搭建好三台ubuntu虚拟机,并设置为root登陆。本人是在VMware中配置了三台计算机,分别是SparkMaster,SparkWorker1,SparkWorker2。
-
配置好三台机器的主机名与ip关系
-
在三台虚拟机上安装ssh,实现它们之间的ssh无密码登陆。
-
由于Hadoop是基于JVM的,因此需要java环境,安装JDK,同时安装Hadoop,并配置好Hadoop的配置文件。
###1.搭建好三台ubuntu虚拟机,并设置为root登陆。
-
在终端输入sudo su,输入密码进入root模式。
-
vim /etc/lightdm/lightdm.conf,将其修改为
[SeatDefaults] greeter-session=unity-greeter user-session=Ubuntu greeter-show-manual-login=true allow-guest=false
-
启动root账号
sudo passwd root
修改完毕,重启再以root用户登录:
###2.配置好三台机器的主机名与ip关系 -
分别
vim /etc/hostname
,修改三台机器的主机名,分别为SparkMaster,SparkWorker1,SparkWorker2。 -
分别
vim /etc/hosts
,修改ip地址对应的主机名
###3.在三台虚拟机上安装ssh,实现它们之间的ssh无密码登陆。
- 终端输入>
apt-get install ssh
,选择Y安装。 ssh start
启动ssh服务,接着输入ps -e | grep ssh
查看服务是否正常启动- 设置免密码登陆,生成公匙,私匙。终端输入
ssh-keygen -t rsa -P ""
注意P是大写 - 在/root/.ssh 中生成两个文件:id_rsa 和 id_rsa.pub,id_rsa 为私钥,id_rsa.pub 为公钥,我们将公钥 id_rsa.pub 追加到 authorized_keys 中,因为authorized_keys 用于保存所有允许以当前用户身份登录到 ssh 客户端用户的公钥内容。终端输入:
cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
。接着输入ssh localhost
,选择Y,查看是否能免密码登陆到主机。 - 以上几步是ssh免密码登陆到本地方法,如果想三台机器相互ssh免密码登陆,比如SparkMaster与SparkWorker1之间ssh免密码通信,SparkMaster生成公匙,私匙,再用
vim ~/.ssh/id_rsa.pub
打开公匙文件,再将SparkMaster的公匙复制到SparkWorker1下的~/.ssh/authorized_keys文件下。此时SparkWorker1有SparkMaster的公匙,意味着SparkMaster可以免密码登陆到SparkWorker1,想让SparkWorker1免密码登陆到SparkMaster的话只需要反过来就可以了。
###4.安装JDK,同时安装Hadoop,并配置好Hadoop的配置文件。
-
下载好JDK,比如下载jdk1.7.0_67且解压到/usr/local/java下,接下来修改好环境变量,
vim /etc/profile
。添加如下两行:export JAVA_HOME=/usr/local/java/jdk1.7.0_67 export PATH=${JAVA_HOME}/bin:$PATH
-
source /etc/profile
即可使配置生效,输入java -version
检查java环境是否成功搭建好。 -
下载好hadoop,比如hadoop-2.7.2.tar.gz到/usr/local/hadoop/ 并解压。同样
vim /etc/profile
,添加如下两行配置好hadoop环境变量:export HADOOP_HOME=/usr/local/hadoop/hadoop-2.7.2 export PATH=${HADOOP_HOME}/bin:$PATH
-
source /etc/profile
使配置生效 -
接着在目录/usr/local/hadoop/hadoop-2.7.2 下分别创建文件夹dfs,tmp.再进入dfs目录下再创建两个目录name,data。 终端输入
mkdir dfs tmp
.接着cd dfs,mkdir name data
。 -
进入目录
cd /usr/local/hadoop/hadoop-2.7.2/etc/hadoop
-
修改hadoop-envsh,在其中加入JAVA_HOME。
-
修改yarn-en.sh,在其中加入JAVA_HOME。
-
修改mapred-env.sh,在其中加入JAVA_HOME.
-
修改配置文件slaves,将其改为:
SparkWorker1 SparkWorker2
-
修改core-site.xml,改为如下:
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://SparkMaster:9000/</value> <description>The name of the default file system</description> </property> <property> <name>hadoop.tmp.dir</name> <value>/usr/local/hadoop/hadoop-2.7.2/tmp</value> <description>A base for other temporary directories</description> </property> </configuration>
-
修改hdfs-site.xml为如下:
<configuration> <property> <name>dfs.replication</name> <value>2</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/usr/local/hadoop/hadoop-2.7.2/dfs/name</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/usr/local/hadoop/hadoop-2.7.2/dfs/data</value> </property> </configuration>
-
修改mapred-site.xml。先拷贝一份mapred-site.xml.template命名为mapred-site.xml,vim mapred-site.xml.修改为如下:
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
-
修改配置文件yarn-site.xml如下所示:
<configuration> <property> <name>yarn.resourcemanager.hostname</name> <value>SparkMaster</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <property> <name>yarn.scheduler.maximum-allocation-mb</name> <value>10000</value> </property> <property> <name>yarn.scheduler.minimum-allocation-mb</name> <value>3000</value> </property> <property> <name>mapreduce.map.memory.mb</name> <value>3000</value> </property> <property> <name>mapreduce.reduce.memory.mb</name> <value>3000</value> </property> </configuration>
-
在SparkWorker1和SparkWorker2上完成和SparkMaster同样的Hadoop-2.7.2操作,建议使用 SCP 命令把 SparkMaster 上安装和配置的 Hadoop 的各项内容拷贝到SparkWorker1 和 SparkWorker2 上;
如把yarn-site.xml复制到SparkWorker1上命令为(最好都用绝对路径):
scp /usr/local/hadoop/hadoop-2.7.2/etc/hadoop/yarn-site.xml root@SparkWorker1:/usr/local/hadoop/hadoop-2.7.2/etc/hadoop/
-
启动Hadoop分布式集群
- 执行命令
hadoop namenode -format
进行hdfs格式化
2.cd /usr/local/hadoop/hadoop-2.7.2/etc/hadoop/sbin
.
执行./start-all.sh
- jps查看主节点机器和从节点机器的运行进程,从节点机器进程中成功启动了datanode。
注意*:如果从节点没有成功启动datanode节点,不要慌,这是因为你可能多次执行了对hdfs的格式化,因为执行一次格式化后主节点dfs/name/下会产生一个current文件夹,下面有一个VERSION文件,这个文件中有个clusterID。对应从节点dfs/data下也会产生一个current文件夹下面有一个VERSION,这个文件夹中也有一个clusterID,导致问题的原因是多次执行格式化后主文件夹下的clusterID会变化,而从节点的clusterID不会变,导致了两个clusterID不一致。解决方法有两个:一个是修改这其中一个clusterID使clusterID一致;或者是删掉主从节点机器下的current文件夹,并且重新格式化,再启动就好了*
- 执行命令
###至此Hadoop分布式系统已经安装完成,访问http://SparkMaster:50070可以登录Web查看HDFS集群的状况。
####Hadoop执行文件操作的命令:1.创建文件夹:hadoop fs -mkdir -p /data/
2.删除文件夹:hadoop fs -rm -r /data/
3.上传文件:hadoop fs -put ../etc/README.md /data/
4.下载文件:hadoop fs -get /data/ ../etc/
5.删除文件:hadoop fs -rm /data/README.md
6.展示目录内容: hadoop fs -ls /data/
####验证一下hadoop分布式计算
-
首先在hdfs上创建两个文件夹分别是/data 和 /output
-
提交本地的wordcount文件到/data/下
-
展示一下/data/下的内容,或者访问webUI查看。
-
执行命令
hadoop jar /usr/local/hadoop/hadoop-2.7.2/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.2.jar wordcount /data/wordcount /output/wordcount
.上面的命令表面执行的是一个jar文件,文件路径,jar文件的类名为wordcount,输入文件,输出文件
-
可以在web上看到/output/wordcount的情况。
##至此已经完整搭建并验证了Hadoop的分布式集群。
##开始搭建Spark集群
步骤总体如下:
- 安装并配置Scala。
- 下载并配置Spark。
- 搭建scala IDE for eclipse,用scala语言编写第一个Spark程序
- 运行这个spark程序并得出正确结果
###1. 安装并配置Scala。
-
下载好scala并配置,具体方法与下载Java并配置一样,在/etc/profile中设置好PATH的环境变量就好
###2. 下载并配置Spark。 -
下载spark并解压到/usr/local/spark下,此时路径为/usr/local/spark/spark-1.6.2-bin-hadoop2.6
-
-
同样把Spark/bin添加到环境变量PATH中
-
cd conf进入配置目录
-
修改slaves文件为
SparkWorker1 SparkWorker2
-
修改spark-env.sh为如下:注意下面都是你自己电脑上的环境变量值
export JAVA_HOME=/usr/lib/java/jdk1.7.0_67 export SCALA_HOME=/usr/lib/scala/scala-2.10.4 export HADOOP_HOME=/usr/local/hadoop/hadoop-2.7.2 export HADOOP_CONF_DIR=/usr/local/hadoop/hadoop-2.7.2/etc/hadoop export SPARK_MASTER_IP=SparkMaster export SPARK_WORKER_MEMORY=1g
-
使用scp将这些文件复制到SparkWorker1,SparkWorker2上
-
测试一下,首先启动Hadoop集群,在/hadoop-2.7.2/sbin 目录下执行
./start-all.sh
。Hadoop集群正确启动后,开始启动Spark集群,进入/spark/spark-1.6.2-bin-hadoop2.6 目录下执行./start-all.sh。使用jps命令查看进程,主节点会多出Master进程,从节点会多出Worker进程。并且可以登录http://sparkmaster:8080查看webUI.
###3. 搭建scala IDE for eclipse,用scala语言编写第一个spark程序
-
-
我选择在Windows下编程,下载scala IDE for eclipse,new a scala project名为spark-exercise,在src目录下创建一个package名为spark.wordcount,然后在其下创建一个scala object名为WordCount.因为要编写Spark程序,因此单独创建一个lib文件夹,并且把spark-assembly-1.6.2-hadoop2.6.0.jar放入lib文件夹,然后右键工程build path,把jar添加到路径。编写WordCount程序,代码如下:
package spark.wordcount import org.apache.spark.SparkContext import org.apache.spark.SparkContext._ import org.apache.spark.SparkConf object WordCount { def main(args: Array[String]) { val infile = "/data/input" // Should be some file on your system val conf = new SparkConf().setAppName("word count") val sc = new SparkContext(conf) val indata = sc.textFile(infile, 2).cache() val words = indata.flatMap(line => line.split(" ")).map(word => (word,1)).reduceByKey((a,b) => (a+b)) words.saveAsTextFile("/output/wordcount") println("All words are counted!") } }
右键export jar文件名为spark-wordcount-in-scala.jar,至此完成Spark编程。
###4. 运行这个spark程序并得出正确结果
在/usr/local/spark/spark-1.6.2-bin-hadoop2.6/sbin 目录下执行命令:spark-submit --class spark.wordcount.WordCount /usr/local/spark-wordcount-in-scala.jar
在webUI中可以看到/output/wordcount文件,为正确输出结果。
ps:如果想实现单机运行的话,只需要注释掉spark-en.sh下的hadoop路径就可以了,否则启动就只能先启动hadoop
###至此整个Spark的搭建及简单的编程完成,后面需要深入研究源码才能知道具体原理。