学习Hadoop集群环境搭建是Hadoop入门必经之路。搭建分布式集群通常有两个办法:

  • 要么找多台机器来部署(常常找不到机器)
  • 或者在本地开多个虚拟机(开销很大,对宿主机器性能要求高,光是安装多个虚拟机系统就得搞半天……)。

那么,问题来了!

有没有更有可行性的办法?

提到虚拟化,Docker最近很是火热!不妨拿来在本地做虚拟化,搭建Hadoop的伪分布式集群环境。虽然有点大材小用,但是学习学习,练练手也是极好的。

文章比较长,建议先倒杯水,听我慢慢到来……

先说一下我的思路吧:

  1. 先使用Docker构建一个Hadoop运行环境的镜像
  2. 然后使用这个镜像分别启动3个容器:1个Master节点,两个Slave节点
  3. 在Master节点上配置Slave节点信息
  4. 在Master上启动Hadoop
使用Docker搭建Hadoop环境
什么是 Docker?

Docker 是一个开源项目,诞生于 2013 年初,最初是 dotCloud 公司内部的一个业余项目。它基于 Google 公司推出的 Go 语言实现。 项目后来加入了 Linux 基金会,遵从了 Apache 2.0 协议,项目代码在 GitHub 上进行维护。

Docker 自开源后受到广泛的关注和讨论,以至于 dotCloud 公司后来都改名为 Docker Inc。Redhat 已经在其 RHEL6.5 中集中支持 Docker。Google 也在其 PaaS 产品中广泛应用。

Docker 项目的目标是实现轻量级的操作系统虚拟化解决方案。 Docker 的基础是 Linux 容器(LXC)等技术。

在 LXC 的基础上 Docker 进行了进一步的封装,让用户不需要去关心容器的管理,使得操作更为简便。用户操作 Docker 的容器就像操作一个快速轻量级的虚拟机一样简单。

Docker安装

我使用的是linux,命令如下:

docker pull daocloud.io/centos:6
Docker常用命令介绍
  • docker images:列出所有镜像(images)
  • docker ps:列出正在运行的(容器)containers
  • docker pull centos:下载镜像
  • docker run -i -t ubuntu /bin/bash:运行ubuntu镜像
  • docker commit 3a09b2588478 centos:mynewimage:提交你的变更,并且把容器保存成Tag为mynewimage的新的镜像.(注意,这里提交只是提交到本地仓库,类似git)

其他常用命令,参考这里

启动第一个容器

下面,我们准备以centos镜像作为基准镜像,构建我们的Hadoop运行环境镜像。

先使用命令如下命令启动容器:

yum -y install wget 
docker run -ti centos

注意:我们在不指定Tag的情况下,默认选择Tag为latest的镜像启动容器。 指定Tag启动命令为:

docker run -ti daocloud.io/centos:6

另外,每次容器启动的时候需要指定一个命令,容器启动后便会执行这个命令。例如执行下面的命令:

Java安装

依次执行如下命令

yum -y install wget 
wget --no-cookies --no-check-certificate --header "Cookie: gpw_e24=http%3A%2F%2Fwww.oracle.com%2F; oraclelicense=accept-securebackup-cookie" "http://download.oracle.com/otn-pub/java/jdk/8u141-b15/336fa29ff2bb4ef291e347e091f7f4a7/jdk-8u141-linux-x64.tar.gz"
tar xzf jdk-8u141-linux-x64.tar.gzyum -y install wget 
注意:
  • 这里安装的Java8(JDK1.8),如需其他版本请自行修改

另外,大家可以将装好java的镜像保存为一个副本,他日可以在此基础上构建其他镜像。命令如下:

cldeMacBook-Pro:~ cl$ docker commit -m "java install" 3d4716997b67  centos:java
sha256:8f35dbd50afa2b6938d5c088bb7e0919c137724559599218d315721dfca3fa36
cldeMacBook-Pro:~ cl$ docker images

上面命令中3d4716997b67为当前容器的ID, centos:java是为新的镜像指定一个标识,centos仓库名javaTag

如何获取容器ID:

  • 有个简便的办法找到此ID,就是命令行用户名@后面的那一串字符。这个方法只在容器启动时没有指定hostname时才能用。
  • 使用docker ps列出所有运行的容器,在命令结果中查看
Hadoop安装

渐渐切入正题了O(∩_∩)O~

使用刚刚已经安装了Java的容器镜像启动:

docker run -ti centos:java

启动成功了,我们开始安装Hadoop。这里,我们直接使用wget下载安装文件。

下载并解压安装文件:
mkdir /usr/hadoop
cd /usr/hadoop
wget http://mirrors.sonic.net/apache/hadoop/common/hadoop-2.8.3/hadoop-2.8.3.tar.gz
tar xvzf hadoop-2.8.3.tar.gz

注意:这里我们安装的Hadoop版本是2.8.3,如果需要其他版本,请在这里找到链接地址后修改命令即可

环境变更配置
vi ~/.bashrc 
#JAVA VARIABLES  START
export JAVA_HOME=/usr/java/jdk1.8.0_141
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
#JAVA VARIABLES END

#HADOOP VARIABLES START
export HADOOP_HOME=/usr/local/hadoop/hadoop-2.8.3
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=$HADOOP_HOME/sbin:$HADOOP_HOME/bin:$PATH
export CLASSPATH=$($HADOOP_HOME/bin/hadoop classpath):$CLASSPATH
#HADOOP VARIABLES END 
配置生效
source ~/.bashrc

此处有坑如下 ,如果which找不到


yum install which
Hadoop配置

这里创建了三个目录,后续配置的时候会用到:

  1. tmp:作为Hadoop的临时目录
  2. namenode:作为NameNode的存放目录
  3. datanode:作为DataNode的存放目录
mkdir tmp
mkdir namenode
mkdir datanode
cd etc/hadoop/

1).core-site.xml配置

<!-- Put site-specific property overrides in this file. -->
<configuration>
    <property>
            <name>hadoop.tmp.dir</name>
            <value>/usr/local/hadoop/hadoop-2.8.3/tmp</value>
            <description>A base for other temporary directories.</description>
    </property>

    <property>
            <name>fs.default.name</name>
            <value>hdfs://master:9000</value>
            <final>true</final>
            <description>The name of the default file system.  A URI whose
            scheme and authority determine the FileSystem implementation.  The
            uri's scheme determines the config property (fs.SCHEME.impl) naming
            the FileSystem implementation class.  The uri's authority is used to
            determine the host, port, etc. for a filesystem.</description>
    </property>
</configuration>

注意:

  • hadoop.tmp.dir配置项值即为此前命令中创建的临时目录路径。
  • fs.default.name配置为hdfs://master:9000,指向的是一个Master节点的主机(后续我们做集群配置的时候,自然会配置这个节点,先写在这里)

2).hdfs-site.xml配置

<configuration>
    <property>
        <name>dfs.replication</name>
        <value>2</value>
        <final>true</final>
        <description>Default block replication.
        The actual number of replications can be specified when the file is created.
        The default is used if replication is not specified in create time.
        </description>
    </property>

    <property>
        <name>dfs.namenode.name.dir</name>
        <value>/usr/local/hadoop/hadoop-2.8.3/namenode</value>
        <final>true</final>
    </property>

    <property>
        <name>dfs.datanode.data.dir</name>
        <value>/usr/local/hadoop/hadoop-2.8.3/datanode</value>
        <final>true</final>
    </property>
</configuration>

注意:

  • 我们后续搭建集群环境时,将配置一个Master节点和两个Slave节点。所以dfs.replication配置为2。
  • dfs.namenode.name.dirdfs.datanode.data.dir分别配置为之前创建的NameNode和DataNode的目录路径

3).mapred-site.xml配置

cp mapred-site.xml.template mapred-site.xml
vi mapred-site.xml
<!-- Put site-specific property overrides in this file. -->
<configuration>
    <property>
        <name>mapred.job.tracker</name>
        <value>master:9001</value>
        <description>The host and port that the MapReduce job tracker runs
        at.  If "local", then jobs are run in-process as a single map
        and reduce task.
        </description>
    </property>
</configuration>

这里只有一个配置项mapred.job.tracker,我们指向master节点机器

4)指定JAVA_HOME环境变量

使用命令vi hadoop-env.sh,修改如下配置:

# The java implementation to use.
export JAVA_HOME=/usr/java/jdk1.8.0_141
5).格式化 namenode

这是很重要的一步,执行命令hadoop namenode -format

4.安装SSH

搭建集群环境,自然少不了使用SSH。这可以实现无密码访问,访问集群机器的时候很方便。

yum install passwd openssl openssh-server -y


SSH装好了以后,由于我们是Docker容器中运行,所以SSH服务不会自动启动。需要我们在容器启动以后,手动通过/usr/sbin/sshd 手动打开SSH服务。未免有些麻烦,为了方便,我们把这个命令加入到~/.bashrc文件中。通过vi ~/.bashrc编辑.bashrc文件,在文件后追加下面内容:

#autorun
/usr/sbin/sshd
chmod 700 ~/.ssh/
chmod 600 ~/.ssh/authorized_keys
5.生成访问密钥
ssh-keygen -t rsa -P '' -f ~/.ssh/id_dsa
cd ~/.ssh/
cat id_dsa.pub >> authorized_keys

注意: 这里,我的思路是直接将密钥生成后写入镜像,免得在买个容器里面再单独生成一次,还要相互拷贝公钥,比较麻烦。当然这只是学习使用,实际操作时,应该不会这么搞,因为这样所有容器的密钥都是一样的!!

6.保存镜像副本

这里我们将安装好Hadoop的镜像保存为一个副本。

docker commit -m "hadoop install" 3d4716997b67   linux:hadoop

Hadoop分布式集群搭建

重点来了!

按照 hadoop 集群的基本要求,其 中一个是 master 结点,主要是用于运行 hadoop 程序中的 namenode、secondorynamenode 和 jobtracker(新版本名字变了) 任务。用外两个结点均为 slave 结点,其中一个是用于冗余目的,如果没有冗 余,就不能称之为 hadoop 了,所以模拟 hadoop 集群至少要有 3 个结点。

前面已经将Hadoop的镜像构建好了,下面就是使用这个镜像搭建Master节点和Slave节点了:

节点hostnameip用途Docker启动脚本
Mastermaster10.0.0.2

namenode

secondaryNamenode

jobTracker

docker run  -p 50070:50070 -p 19888:19888 -p 8088:8088  --name  master  -ti -h master linux:hadoop
Slaveslave110.0.0.3

datanode

taskTracker

docker run -it -h slave1 --name slave1  linux:hadoop  /bin/bash
Slaveslave210.0.0.4

datanode

taskTracker

docker run -it -h slave2 --name slave2  linux:hadoop  /bin/bash

这里有几个问题:

  1. Docker容器中的ip地址是启动之后自动分配的,且不能手动更改
  2. hostname、hosts配置在容器内修改了,只能在本次容器生命周期内有效。如果容器退出了,重新启动,这两个配置将被还原。且这两个配置无法通过commit命令写入镜像
配置hosts
  1. 通过ifconfig命令获取各节点ip。环境不同获取的ip可能不一样,例如我本机获取的ip如下: 
    • master:172.17.0.2
    • slave1:172.17.0.3
    • slave2:172.17.0.4
  2. 使用vi /etc/hosts命令将如下配置写入各节点的hosts文件,注意修改ip地址:

    172.17.0.2      master
    172.17.0.3      slave1
    172.17.0.4      slave2
  3. 启动sshd  /usr/sbin/sshd 

配置slaves
在master节点容器中执行如下命令
vi /usr/local/hadoop/hadoop-2.8.3/etc/hadoop/slaves

将如下slave节点的hostname信息写入该文件

master
slave1
slave2
启动Hadoop

在master节点上执行start-all.sh命令,启动Hadoop。


在个节点上执行jps命令

下面,我们在master节点上通过命令hdfs dfsadmin -report 查看DataNode是否正常启动:

还可以通过Web页面看到查看DataNode和NameNode的状态:http://IP:50070/ (由于我宿主机器上没有配置master的hosts解析,所以只能用ip地址访问,大家将ip改为各自的master节点容器的ip即可):


感谢如下的帮助

http://www.tianshangkun.com/2017/06/13/Centos%E4%B8%8Bdocker%E6%90%AD%E5%BB%BAHadoop%E9%9B%86%E7%BE%A4/

https://www.cnblogs.com/onetwo/p/6419925.html


Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐