美文网首页我爱编程hadoop
Hadoop: 完全分布式环境搭建

Hadoop: 完全分布式环境搭建

作者: kviccn | 来源:发表于2017-03-03 22:39 被阅读557次

    说明:本文所有操作均在 64位 ubuntu 16.04 操作系统下进行

    准备

    通过物理机器虚拟化 4 台虚拟机:1 个 Master 节点,3 个 Slave 节点。为了实现节点间在同一局域网上定向通信,配置使用静态地址,各节点的 IP 分布如下:

    节点主机名 静态 IP 地址 主要角色
    master 192.168.1.200 namenode 节点
    slave01 192.168.1.201 datanode 节点
    slave02 192.168.1.202 datanode 节点
    slave03 192.168.1.203 datanode 节点

    Master 节点机器主要配置 NameNode 和 JobTracker 角色,总体负责分布式数据和分解任务的执行;Slave 节点机器配置 DataNode 和 TaskTracker 的角色,负责分布式数据存储以及任务的执行。

    需要的软件:

    软件名称 描述
    VirtualBox 用于虚拟化主机
    Ubuntu Server 16.04.2 LTS 服务器版的 ubuntu 操作系统
    jdk-8u121-linux-x64.tar.gz Hadoop 需要 JDK 的支持
    hadoop-2.7.3.tar.gz hadoop 的安装文件

    配置一个单节点环境

    安装 VirtualBox

    使用 apt 安装 virtual box

    $ sudo apt install virtualbox
    

    新建虚拟机

    打开 VirtualBox,点击 New,Name 填 master (为方便区分),Type 选择 Linux,Version 选择 Ubuntu(64-bit),点击下一步。

    一路 Next,最终如下图。

    为虚拟机安装操作系统

    选择镜像

    点击 Settings,选中 Storage -> Controller:IDE -> Empty


    右上方有一个光盘的小图标,点击之后选择下载好的 Ubuntu Server 镜像


    点击 OK 确定。

    安装

    点击 Start 运行虚拟机开始安装


    注意:语言请选择 "English",选择 "中文" 安装过程中会报错


    选择 "Install Ubuntu Server"

    一路回车,到创建新用户时停止。


    这里我将用户名设置为 spark (最头疼的就是起名字了,你可以根据自己的喜好随意起名 _ )

    continue,continue,到设置密码的时候停止。


    注意:密码输入完成后还需重新输入一次以确认两次密码是否一致

    如果密码强度太弱系统会发出如下提示:


    手动选择 Yes

    然后一路回车。注意,在此过程中系统会自动配置时区时间,就不要 cancel 了,让它自己配一会儿。

    接下来是给磁盘分区,依旧回车,到如图所示的时候停下来,选择 Yes

    继续,到这一步,选择 Yes


    现在静静的等一小会儿_

    到这一步,直接 continue


    然后系统会连接网络更新软件,这一步不是必须的(且比较耗时),所以选择 cancel,然后继续回车,到下图所示的步骤停止。

    这里我们选择安装 standard system utilitiesOpenSSH serverstandard system utilities 不安装的话机器基本无法正常使用,安装 OpenSSH server 是为了方便集群之间的通信。

    好了,剩下的所有对话框都可以用回车解决了。
    等待安装完成,系统会自动重启。

    关闭虚拟机,并设置虚拟机的网络为桥接(bridged adapter)模式。

    对安装的操作系统进行配置

    启动虚拟机,并进行如下配置:

    1. 设置主机名
    2. 设置静态 IP
    3. 安装 JDK
    4. 安装 Hadoop

    1. 设置主机名

    打开文件 hostname

    $ sudo vim /etc/hostname
    

    将内容修改为 master

    2. 设置静态 IP

    打开文件 interfaces

    $ sudo vim /etc/network/interfaces
    

    我的 interfaces 文件中的内容如下:

    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    
    source /etc/network/interfaces.d/*
    
    # The loopback network interface
    auto lo
    iface lo inet loopback
    
    # The primary network interface
    auto enp0s3
    iface enp0s3 inet dhcp
    

    dhcp 修改为 static,并添加 ip 地址,子网掩码,网关

    修改完成后的文件内容如下:

    # This file describes the network interfaces available on your system
    # and how to activate them. For more information, see interfaces(5).
    
    source /etc/network/interfaces.d/*
    
    # The loopback network interface
    auto lo
    iface lo inet loopback
    
    # The primary network interface
    auto enp0s3
    iface enp0s3 inet static
    address 192.168.1.200
    netmask 255.255.255.0
    gateway 192.168.1.1
    

    完成后继续配置 DNS 解析

    $ sudo vim /etc/resolvconf/resolv.conf.d/base 
    

    添加如下内容:

    nameserver 192.168.1.1
    nameserver 114.114.114.114
    

    重启使配置生效

    此时,主机名已经是 master 了,运行 ifconfig 查看一下 ip 是否正确修改

    spark@master:~$ ifconfig
    ...
    enp0s3    Link encap:Ethernet  HWaddr 08:00:27:0f:f6:ec  
              inet addr:192.168.1.200  Bcast:192.168.1.255  Mask:255.255.255.0
              inet6 addr: fe80::a00:27ff:fe0f:f6ec/64 Scope:Link
              UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
              RX packets:86 errors:0 dropped:0 overruns:0 frame:0
              TX packets:86 errors:0 dropped:0 overruns:0 carrier:0
              collisions:0 txqueuelen:1000 
              RX bytes:12088 (12.0 KB)  TX bytes:12102 (12.1 KB)
    ...
    

    看到 inet addr 已经修改为 192.168.1.200

    在进行接下来的操作之前我们先配置一下本机(物理机)的 hosts 文件,使 ip 和主机名绑定,方便后续操作

    $ sudo vim /etc/hosts
    

    在文件末尾添加如下内容:

    192.168.1.200 master
    192.168.1.201 slave01
    192.168.1.202 slave02
    192.168.1.203 slave03
    

    现在我们就可以通过主机名来连接主机了

    打开终端,使用 ssh 连接虚拟机

    $ ssh spark@master 
    

    spark 为虚拟机中创建的用户名,master 为刚才配置的主机名
    中间会有个小提示,输入 yes 回车,然后输入 spark 用户的密码

    3. 安装 JDK

    参考 JDK 的正确安装姿势

    4. 安装 Hadoop

    我已经提前下载好了 hadoop-2.7.3.tar.gz,直接传到虚拟机里就可以了
    这里有个小技巧,可以用 scp 命令在 linux 主机之间传文件,例如:

    $ scp hadoop-2.7.3.tar.gz spark@master:/home/spark/
    

    这条命令表示将文件 hadoop-2.7.3.tar.gz 从本机复制到 master 主机的 /home/spark/ 目录下

    在虚拟机中进行安装 hadoop 的操作

    解压安装文件

    在用户家目录下新建 apps 目录,将 hadoop-2.7.3.tar.gz 移动到 apps 目录中进行解压

    $ mkdir apps && mv hadoop-2.7.3.tar.gz apps && cd apps && tar zxvf hadoop-2.7.3.tar.gz 
    

    配置

    1. 配置 hadoop 环境变量
    export HADOOP_HOME="/home/spark/apps/hadoop-2.7.3"
    export HADOOP_LOG_DIR="$HADOOP_HOME/logs"
    export YARN_LOG_DIR="$HADOOP_LOG_DIR"
    export PATH="$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin"
    

    使配置立即生效

    $ source ~/.bashrc 
    

    执行 hadoop 命令,出现如下信息则说明环境配置成功

    $ hadoop
    Usage: hadoop [--config confdir] [COMMAND | CLASSNAME]
     CLASSNAME            run the class named CLASSNAME
    ...
    
    1. 修改 hadoop 配置文件
      2.1 修改 ~/apps/hadoop-2.7.3/etc/hadoop 目录下的 hadoop-env.sh yarn-env.sh mapred-env.sh 文件中 JAVA_HOME 的值为 /opt/java/jdk1.8.0_121
      2.2 修改 ~/apps/hadoop-2.7.3/etc/hadoop/slaves 文件内容如下:
    slave01
    slave02
    slave03
    

    2.3 配置 ~/apps/hadoop-2.7.3/etc/hadoop/core-site.xml
    添加如下内容:

      <property>
        <name>fs.defaultFS</name>
        <value>hdfs://master:9000</value>
        <description>设定 namenode 的主机名及端口</description>
      </property>
      <property>
        <name>hadoop.tmp.dir</name>
        <value>/home/spark/apps/hadoop-2.7.3/tmp/hadoop-${user.name}</value>
        <description>存储临时文件的目录</description>
      </property>
    
      <!-- 用户 "spark" 可以代理所有主机上的所有用户 -->
      <property>
        <name>hadoop.proxyuser.spark.hosts</name>
        <value>*</value>
      </property>
      <property>
        <name>hadoop.proxyuser.spark.groups</name>
        <value>*</value>
      </property>
    

    2.4 配置 ~/apps/hadoop-2.7.3/etc/hadoop/hdfs-site.xml
    添加如下内容:

     <property>
        <name>dfs.namenode.http-address</name>
        <value>master:50070</value>
        <description> NameNode 地址和端口 </description>
    </property>
    
    <property>
        <name>dfs.namenode.secondary.http-address</name>
        <value>slave01:50090</value>
        <description> SecondNameNode 地址和端口 </description>
    </property>
    
    <property>
        <name>dfs.replication</name>
        <value>3</value>
        <description> 设定 HDFS 存储文件的副本个数,默认为 3 </description>
    </property>
    
    <property>
        <name>dfs.namenode.name.dir</name>
        <value>file:///home/spark/apps/hadoop-2.7.3/dfs/name</value>
        <description> namenode 用来持续存储命名空间和交换日志的本地文件系统路径 </description>
    </property>
    
    <property>
        <name>dfs.datanode.data.dir</name>
        <value>file:///home/spark/apps/hadoop-2.7.3/dfs/data</value>
        <description> DateNode 在本地存储块文件的目录列表 </description>
    </property>
    
    <property>
        <name>dfs.namenode.checkpoint.dir</name>
        <value>file:///home/spark/apps/hadoop-2.7.3/dfs/namesecondary</value>
        <description> 
           设置 secondarynamenode 存储临时镜像的本地文件系统路径,
           如果这是一个用逗号分隔的列表,则镜像将会冗余复制到所有目录 
       </description>
    </property>
    
    <property>
        <name>dfs.webhdfs.enabled</name>
        <value>true</value>
        <description> 是否允许网页浏览 HDFS 文件 </description>
    </property>
    
    <property>
        <name>dfs.stream-buffer-size</name>
        <value>131072</value>
        <description> 
           默认 4KB,作为 hadoop 缓冲区,用于 hadoop 读 HDFS 的文件和写 HDFS 的文件,
           还有 map 的输出都用到了这个缓冲区容量,对于现在的硬件,可以设置为 128KB(131072),
           甚至是 1MB(太大了 map 和 reduce 任务可能会内存溢出) 
       </description>
    </property>
    

    2.5 配置 ~/apps/hadoop-2.7.3/etc/hadoop/mapred-site.xml
    该文件需要通过模板复制一份

    $ cp mapred-site.xml.template mapred-site.xml
    

    添加如下内容:

    <property>
        <name>mapreduce.framework.name</name>
        <value>yarn</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>
    

    2.6 配置 ~/apps/hadoop-2.7.3/etc/hadoop/yarn-site.xml
    添加如下内容:

    <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.nodemanager.aux-services.mapreduce.shuffle.class</name>
        <value>org.apache.hadoop.mapred.ShuffleHandler</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>
    

    绑定 hostnameip
    之前我们在物理机中绑定过 iphostname。现在,在虚拟机中进行同样的操作

    $ sudo vim /etc/hosts
    

    在文件末尾添加如下内容:

    192.168.1.200 master
    192.168.1.201 slave01
    192.168.1.202 slave02
    192.168.1.203 slave03
    

    通过 ping master 检查是否修改成功

    $ ping master
    PING master (192.168.1.200) 56(84) bytes of data.
    64 bytes from master (192.168.1.200): icmp_seq=1 ttl=64 time=0.016 ms
    64 bytes from master (192.168.1.200): icmp_seq=2 ttl=64 time=0.022 ms
    64 bytes from master (192.168.1.200): icmp_seq=3 ttl=64 time=0.021 ms
    

    至此,我们已经完成了一台主机上 hadoop 的配置,接下来,我们通过 master 主机克隆 3 个 slave 主机

    克隆多个虚拟主机

    关闭虚拟机,选中列表中的 master,右键选择 clone

    将其命名为 slave01,并把下面的对勾打上(用于重新初始化 MAC 地址)

    继续创建 slave02, slave03,方法同上

    现在,我们就有了 4 台虚拟主机

    配置 slave 主机

    修改 slave01 的 hostname

    $ sudo vim /etc/hostname 
    

    内容如下:

    slave01
    

    修改 slave01 的 ip

    $ sudo vim /etc/network/interfaces
    

    address 修改为 192.168.1.201

    对 slave02 和 slave03 做类似操作

    配置 SSH 免密码登录

    在 master 主机上运行如下命令(一路回车):

    $ ssh-keygen -t rsa
    

    此时 ~/.ssh 目录下会生成两个文件:id_rsa id_rsa.pub,前者是私钥,后者是公钥

    id_rsa.pub 写入 authorized_keys 文件并测试是否可以对本机进行 SSH 无密码登录

    $ cat .ssh/id_rsa.pub >> .ssh/authorized_keys
    $ chmod 600 .ssh/authorized_keys 
    $ ssh localhost // 接下来会询问是否继续,输入 yes 回车
    

    对 3 台 slave 主机进行上述操作均会生成自己的 authorized_keys

    将 slave 主机的公钥依次复制到 master 主机

    $ ssh-copy-id -i ~/.ssh/id_rsa.pub spark@master
    

    此时 master 主机的 authorized_keys 文件内容如下:

    $ cat .ssh/authorized_keys 
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDPdIlGd1POJtarQAVIos5GuZKs64wRQfDXBT/p8WtLshKQ2NN+HGqOqwOY42VjtaEAhoWiWUaT4DPuMgMVso7N90oLVADOu8kEqE8EErrZKTbD1qW4HJOA5LNdNt6ExrTQQMQ8W8gdxN209/e/z7ZIblnT2ZXfw0Y5bQHYf37RI9+vo//NTPFLTP07YoKc9LYTx4YxQxw7PJRm7+G6B2wY5x/YIqYlhwWCqDut/lfoRFR0iMbifsjyOyNMSDF2/f6DQvTgx+EZ3UAxZFSQhE1HSdxpTsWA/SbRctF7MlTWrDYP6eknVfHjdD15CBcqEdkVbiKNJk6WjobeUy8XSWyz spark@master
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC20+5tTSIoj+cLVN9lhWtyyJudzKJP7lEz/bP3fecX00nNAeWD0YJnWMOVibw3ISMZ8lHu4YUqZjzN6taDesqGWtI57o7cRr5PeeuU2Iwruy48MOPHlx4kgXPjLN4APapTJ5m5UPZYjERt3RnEGfHMU5dowZ8QKAl4rk0yApctXoD3N1Kz2avNqKiREdzGo7bJm/HrEzt5uUqKqEQqVpFGOZRhZ7t2Ad/mu5/CvgB/weA24wC3noXliGTxdX6x0/SHKBdIBCWnTzgX6xAbs/l/Gix2Se70/Xl23pJRp4GK/ulOB4zKasxJOTfe0/33BhNT48AUCVoYXRUNuoq7Um3L spark@slave01
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC7To6Xa58/2EPR0OOHFpsy5n9acp+a/cwoYXI9rIvO8ISG52FBHahtimEN2RgIon0oU+r32+E3wcZRB/4uwfBQriKxGHpII3WVTEj8qZoDywqITvbhM08EXBISzIIOfIc6s3zCZb6fqQW1Vsw5Toz6QteEB8g9Eq6AXrvM4PKILq+aZeV8qnjFZOWccjz+sHRXyNcP1v111hZbrrOBvAvh5Q8P79ReLDyWjJodfS6MTuQe6kMnTscvwA+2x/qxeYthkXDlp7+ETogYrP/LBcfd+LUX6A2fzFahQSy/Ok1Dzq0N/BRPnpEWD920GwpN0VhjOQMn7relKHxl0I4HUwAz spark@slave02
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC54wC6D1TckbScYKtErVdM8a332bIyyaFDTCoL7kyvHubx4ZE2uY9CxBxosKk/eC9GLYc3gIOfVrXotGBzafQxUUVf/AxsuP2cMoSQU4yjLmyFE5D/HISIG+1kt9wGE6RqL0HmQ7BAOMBwv0rvI4GeEpnEo3O7cwRmEh42r5mS7kAHYKg2f8sLqMeA8UXrh4YUqzs8r64lEphOgd4UBmAdc1xKrM9j95P3dKeFfRANSfckJkNHgdzGYWioaY/qSfYczjR8JLXT6veC822xF6Q6Za05fYMzVVW9f/DfNdXba01rb20RJmQ1lC68ClqgR5EDFqSt5xAaVn4aSuH57IOv spark@slave03
    

    复制此文件到 3 台 slave 主机即可实现节点之间的免密码登录

    $ scp .ssh/authorized_keys spark@slave01:/home/spark/.ssh/
    $ scp .ssh/authorized_keys spark@slave02:/home/spark/.ssh/
    $ scp .ssh/authorized_keys spark@slave03:/home/spark/.ssh/
    

    Hadoop 的启动和测试

    格式化文件系统

    $ hdfs namenode -format
    

    输出如下信息:

    ...
    17/03/03 21:11:54 INFO util.ExitUtil: Exiting with status 0
    17/03/03 21:11:54 INFO namenode.NameNode: SHUTDOWN_MSG: 
    /************************************************************
    SHUTDOWN_MSG: Shutting down NameNode at master/192.168.1.200
    ************************************************************/
    

    提示 Exiting with status 0 则表示格式化成功

    启动 HDFS

    启动 Hadoop HDFS 服务

    $ start-dfs.sh
    

    验证是否启动成功,在浏览器地址栏输入 http://master:50070 ,出现如下图所示的信息则表示启动成功:

    也可以通过 jps 命令查看各节点是否正常启动

    启动 Yarn

    $ start-yarn.sh
    

    验证是否启动成功,在浏览器地址栏输入 http://master:8088 ,出现如下图所示的信息则表示启动成功:

    同样的,也可以使用 jps 命令查看各节点启动的进程
    此时可以看到 master 节点多了 ResourceManager 进程,slave 节点多了 NodeManager 进程

    集群验证

    使用 Hadoop 自带的 WordCount 例子进行集群验证

    1. 在 HDFS 上创建目录
    $ hadoop fs -mkdir -p /data/input
    
    1. 在本地创建 wordcount.txt 文件并上传到 HDFS
      wordcount.txt中的内容如下:
    Hello laowang
    hello kviccn
    hello jack
    

    上传到文件到 HDFS

    $ hadoop fs -put wordcount.txt /data/input
    
    1. 运行 WordCount
    $ hadoop jar ${HADOOP_HOME}/share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount /data/input /data/output
    

    等待运行结束,输出如下信息:

    17/03/03 21:48:46 INFO client.RMProxy: Connecting to ResourceManager at master/192.168.1.200:8032
    17/03/03 21:48:48 INFO input.FileInputFormat: Total input paths to process : 1
    17/03/03 21:48:48 INFO mapreduce.JobSubmitter: number of splits:1
    17/03/03 21:48:48 INFO mapreduce.JobSubmitter: Submitting tokens for job: job_1488547769795_0001
    17/03/03 21:48:49 INFO impl.YarnClientImpl: Submitted application application_1488547769795_0001
    17/03/03 21:48:49 INFO mapreduce.Job: The url to track the job: http://master:8088/proxy/application_1488547769795_0001/
    17/03/03 21:48:49 INFO mapreduce.Job: Running job: job_1488547769795_0001
    17/03/03 21:49:00 INFO mapreduce.Job: Job job_1488547769795_0001 running in uber mode : false
    17/03/03 21:49:00 INFO mapreduce.Job:  map 0% reduce 0%
    17/03/03 21:49:09 INFO mapreduce.Job:  map 100% reduce 0%
    17/03/03 21:49:20 INFO mapreduce.Job:  map 100% reduce 100%
    17/03/03 21:49:21 INFO mapreduce.Job: Job job_1488547769795_0001 completed successfully
    17/03/03 21:49:21 INFO mapreduce.Job: Counters: 49
    ...
    

    查看结果:

    $ hadoop fs -cat /data/output/*
    Hello   1
    hello   2
    jack     1
    kviccn   1
    laowang  1
    

    至此,Hadoop 完全分布式环境搭建成功。

    其他:

    Ubuntu16.04换源 参考 这篇文章
    中文乱码 参考 这篇文章

    相关文章

      网友评论

        本文标题:Hadoop: 完全分布式环境搭建

        本文链接:https://www.haomeiwen.com/subject/qglrgttx.html