1. 准备工作

我们采用真正的分布式环境。机器安排如下:

ip role
10.45.10.33 master(namenode,datanode)
10.45.10.34 slave(datanode)
10.45.10.35 slave(datanode)

我们均使用root用户来完成之后的操作。

1.1 安装JDK

所有节点上均执行以下操作。

我用的jdk1.8。这个比较简单不再赘述。注意下装好JAVA8后,配置下JAVA_HOME、PATH、CLASSPATH这些环境变量。

# jdk settings
JAVA_HOME=/usr/java/jdk1.8.0_91
PATH=$JAVA_HOME/bin:$PATH
CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar
export PATH JAVA_HOME CLASS_PATH

1.2 安装scala

所有节点上均执行以下操作

我使用的是scala 2.11.8
通过官方网站下载scala二进制包,在LINUX解压,然后配置环境变量即可。

# scala settings
export PATH=$PATH:/root/Downloads/scala-2.11.8/bin

1.3 下载安装spark

所有节点上均执行以下操作

建议下载已经build好的spark包,不要浪费时间自己构建。从spark官网可以下载已经编译好的包并且解压。解压后可以设置下环境变量。

建议使用

hadoop则自己单独安装。我们这里也采用这样的方式来进行该安装教程。

# spark settings
export SPARK_HOME=/root/Downloads/spark-1.6.2-bin-without-hadoop
export PATH=$SPARK_HOME/bin:$PATH

由于还没有安装hadoop,所以现在还无法执行spark

1.4 环境变量总结

建议直接修改/etc/profile 中的环境变量,可以对所有用户都生效。以上的环境变量总结如下:

# jdk settings

JAVA_HOME=/usr/java/jdk1.8.0_91
PATH=$JAVA_HOME/bin:$PATH
CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar
export PATH JAVA_HOME CLASS_PATH



# scala settings
export PATH=$PATH:/root/Downloads/scala-2.11.8/bin


# spark settings
export SPARK_HOME=/root/Downloads/spark-1.6.2-bin-without-hadoop
export PATH=$SPARK_HOME/bin:$PATH


# hadoop settings
export HADOOP_HOME=/root/Downloads/hadoop-2.7.2
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin

2. 安装hadoop

2.1 修改hosts文件(每个节点上均要执行)

vi /etc/hosts
# 添加如下内容
10.45.10.33 mysql3
10.45.10.34 mysql4
10.45.10.35 mysql5

2.2 配置master无密码登入slave

根据start-all.sh脚本分析,可以知道只需要master无密码登入slave即可

首先确保安装以下软件(所有机器上均执行):

yum install openssh
yum install openssh-clients
yum install rsycn

在master上执行如下命令:

#确保自己是root用户,并且进入主目录
cd  ~
#生成密钥
ssh-keygen -t rsa -P ''

此时密钥对默认生成在你的主目录下。

注意.ssh是隐藏文件请采用 ll -a 或者 ls -a

#把id_rsa.pub追加到授权的key里面

cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys

此时在.ssh文件下已经有authorized_keys

为了保证能够正常使用RSA功能,做一些权限的修改

chmod 600 ~/.ssh/authorized_keys

然后启用RSA功能,所有节点上均要执行以下的设置

vi /etc/ssh/sshd_config

RSAAuthentication yes 

PubkeyAuthentication yes 

AuthorizedKeysFile .ssh/authorized_keys 

#在vi命令模式下输入/RSAA  即可直接定位到此处,去除前面的#即可.然后保存

重启SSH服务(所有节点上均要执行)

service sshd restart

将master上的公钥传给所有的slave节点root主目录下.ssh目录下(没有.ssh则自己创建)

mkdir .ssh
chmod 700 ~/.ssh

使用ssh + hostname来验证master是否可以访问各个节点

2.3 安装hadoop

apache hadoop官方网站下载最新二进制包,并发送的 到所有节点上解压。我这里使用的是2.7.2。

解压后按照如下设置权限:

chown -R hadoop:hadoop hadoop-2.7.2

增加如下环境变量:

export HADOOP_HOME=/root/Downloads/hadoop-2.7.2
export HADOOP_INSTALL=$HADOOP_HOME
export HADOOP_MAPRED_HOME=$HADOOP_HOME
export HADOOP_COMMON_HOME=$HADOOP_HOME
export HADOOP_HDFS_HOME=$HADOOP_HOME
export YARN_HOME=$HADOOP_HOME
export HADOOP_COMMON_LIB_NATIVE_DIR=$HADOOP_HOME/lib/native
export PATH=$PATH:$HADOOP_HOME/sbin:$HADOOP_HOME/bin

2.4 修改hadoop的配置文件

需要修改的配置文件罗列如下(都在$HADOOP_HOME/etc/hadoop/下):

  1. hadoop-env.sh
  2. core-site.xml
  3. hdfs-site.xml
  4. mapred-site.xml
  5. yarn-site.xml
  6. slaves

PS:配置文件在所有节点均要保持一致
配置文件的配置详细解释可以参考hadoop配置文件配置,官方说明

2.4.1 hadoop-env.sh

在该文件中添加JAVA_HOME环境变量。指定pids存放文件

export JAVA_HOME=/usr/java/jdk1.8.0_91
# 默认存放在tmp,会丢失pid导致stop-all.sh失效,建议使用绝对路径避免出错
export HADOOP_PID_DIR=/root/Downloads/hadoop-2.7.2/pids

PS:pids目录请提前建好

2.4.2 core-site.xml

添加如下内容:

<configuration>
<!--HDFS的WEB访问地址,注意各个节点要设置相同建议配置,该临时目录存放namenode、datanode的元数据,有时候一些重复格式化导致的版本不一致问题可以删除该目录下的元数据来重置如果不配置,则默认在/tmp/hadoop-${username}下-->
    <property>  
            <name>hadoop.tmp.dir</name>  
            <value>/root/Downloads/hadoop_tmp</value>  
    </property>  
    <property>
        <name>fs.defaultFS</name>
        <value>hdfs://10.45.10.33:9000</value>
    </property>
  <!--需要namenode做ha的需要ZK的配置-->
    <property>
      <name>ha.zookeeper.quorum</name>
      <value>mast1:2181,mast2:2181,mast3:2181</value>
    </property>
</configuration>

2.4.3 hdfs-site.xml

添加如下内容:

 <configuration>
 <!--复制的份数,默认为3份,仅仅在datanode上配置-->
        <property>
                <name>dfs.replication</name>
                <value>3</value>
        </property>

 <!--存储命名空间和操作日志相关的元数据信息的本地文件系统目录-->
        <property>
                <name>dfs.namenode.name.dir</name>
                <value>file:/root/Downloads/hdfs/namenode</value>
        </property>

<!--存储命名空间和操作日志相关的元数据信息的本地文件系统目录-->
        <property>
                <name>dfs.namenode.data.dir</name>
                <value>file:/root/Downloads/hdfs/datanode</value>
        </property>

</configuration>
 ```

注意: 以上配置的文件路径,必须在本地提前建好,并且各个节点均要保持一致!

如果想配namenode的HA的可以参考[Hadoop2.5.2 HA高可靠性集群搭建(Hadoop+Zookeeper)](http://www.open-open.com/lib/view/open1436855630959.html)
 
###2.4.4  mapred-site.xml
按照如下修改
```xml
<configuration>
 <property>
  <name>mapreduce.framework.name</name>
   <value>yarn</value>
 </property>
</configuration>

2.4.5 yarn-site.xml

按照如下配置(PS:每个节点上均按照如下配置,保持一致)

<configuration>
<!--yarn相关的IP设置-->
    <property>
        <name>yarn.resourcemanager.address</name>
        <value>10.45.10.33:8032</value>
    </property>
    <property>
        <name>yarn.resourcemanager.scheduler.address</name>
        <value>10.45.10.33:8030</value>
    </property>
    <property>
        <name>yarn.resourcemanager.resource-tracker.address</name>
        <value>10.45.10.33:8031</value>
    </property>
    <property>
        <name>yarn.resourcemanager.admin.address</name>
        <value>10.45.10.33:8033</value>
    </property>
    <property>
        <name>yarn.resourcemanager.webapp.address</name>
        <value>10.45.10.33:8088</value>
    </property>
    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</value>
    </property>
    <!--支持mr任务提交到yarn-->
    <property>
      <name>yarn.nodemanager.aux-services</name>
      <value>mapreduce_shuffle</value>
  </property>
</configuration>

2.4.6 slaves文件

将slave的ip地址写进去(有些人喜欢设置hostname然后在这里写hostname也可以)

2.5 启动集群

首先格式化一下HDFS
$HADOOP_HOME/bin/hadoop namenode -format

有时候会报域名解析的错误:java.net.UnknownHostException

这是因为用了DNS,在/etc/hosts下配置下ip和hostname。注意hostname要和DNS中的对应,一般为xxx.com

然后启动集群
在master上运行sudo $HADOOP_HOME/sbin/start-all.sh

2.5.1 yarn管理界面

根据我们配置可以打开http://10.45.10.33:8099/来查看节点情况

2.5.2 hdfs管理界面

查看hdfs相关信息可以打开http://10.45.10.33:50070来查看

注意确认下live node的个数,确保都已经启动起来了

3. 配置spark运行示例

确保hadoop已经正常启动之后,我们可以简单配置下spark即可。

cd conf
cp spark-env.sh.template spark-env.sh
cp spark-defaults.conf.template spark-defaults.conf
vi conf/spark-env.sh

修改spark-env.sh添加如下内容

export HADOOP_HOME=/root/Downloads/hadoop-2.7.2
export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop
export SPARK_DIST_CLASSPATH=$(hadoop classpath)

在spark主目录尝试运行以下命令来运行示例:

./bin/run-example SparkPi 10

发现可以正常运行,即可!

4. 问题补充

4.1 本地库导致的一些警告

这样安装好的hadoop可能还存在无法找到本地库相关的警告。可以使用命令hadoop checknative来验证本地库的加载是否成功。若发现都为false。可以在环境hadoop-env.sh环境变量中修改$HADOOP_OPTS变量来保证正确加载本地库。

PS: 注意每个节点上均要修改哦!!

export HADOOP_OPTS="-Djava.library.path=${HADOOP_HOME}/lib/native"

4.2 元数据导致的错误

有时候有类似如下错误,是由于各个节点元数据信息不一致导致的。

 FATAL org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for Block pool <registering> (Datanode Uuid unassigned) service to mysql3/10.45.10.33:9000. Exiting. 

删除各个节点core-site.xml下配置的临时目录下的元数据(主要是一个current目录)然后再重启集群即可。

如果没有配置过临时目录,默认在/tmp/hadoop-${username}下,如图所示: