Hadoop 完全分布式搭建

集群规划 → 不同的守护进程运行哪些节点

Posted by Phillip on January 19, 2016

结构

  1. HDFS: Namenode   SecndaryNamenode  Datanode  Datanode   Datanode
  2. Yarn: Nodemanager   Nodemanager   Nodemanager   ResourceManager
  3. Histrory: HistroryServer

基本环境准备

对于一个初学者来说,如果想要对海量数据进行分布式处理,就要学会熟练使用Hadoop这个有力的工具, 而要想用好工具, 首先就是要先学会如何去搭建部署它。

我的配置环境: CentOS 6.5, Hadoop 2.5.0 ,   jdk1.7
*注意: 本文基于三台虚拟机进行搭建 (因为贫穷o(╥﹏╥)o),有条件的可以去云上操作一番,应该体验会更加丝滑顺畅。本文默认环境已经安装好jdk,所以不详细介绍如何配置Java环境。

1. 配置IP和DNS 映射 主机名 关闭防火墙 关闭安全子系统

  1. 检查主机名:
    $ cat /etc/sysconfig/network
    
  2. 检查IP 和DNS 网关 配置静态IP:
    $ cat /etc/sysconfig/network-scripts/ifcfg-eth0
    
  3. 检查主机映射:
    $ cat /etc/hosts   ->Linux
    
  4. Windows环境下:
    C:\Windows\System32\drivers\etc\hosts   ->Windows
    

2. 关闭防火墙及安全子系统

如下代码:

# service iptables stop
# chkconfig iptables off

检查:

# sudo service iptables status

会有提示 iptables: Firewall is not running.

# sudo chkconfig --list | grep iptables

会显示  0:off 1:off 2:off 3:off 4:off 5:off 6:off

关闭Linux安全子系统:

# vi /etc/sysconfig/selinux

为了提高性能,可以考虑将启动方式调整为不带桌面

sudo vi /etc/inittab
id:3:initdefault:

3. 创建普通用户名并密码, 配置sudo权限

  1. 查看是否存在用户普通用户,没有就创建,稍后要保证3台帐号密码相同
    # useradd hadoop
    # passwd hadoop   或 # echo 123456 | passwd --stdin hadoop
    
  2. 配置hadoop的sudo权限
  3. 系统和软件【3台】
    # vi /etc/udev/rules.d/70-persistent-net.rules
    
  4. 删除克隆来的信息(也就是eth0),并把eth1改为eth0
    # vi /etc/sysconfig/network-scripts/ifcfg-eth0
    
  5. 删除UUID,修改 HWADDR=当前的mac地址 (与 70-persistent-net.rules的mac地址相同),修改 IPADDR 为对应的 ip

  6. 配置主机映射【三台都需要需要添加】
    # vi /etc/hosts
    192.168.239.211 bigdata01.hadoop.com
    192.168.239.212 bigdata02.hadoop.com
    192.168.239.213 bigdata03.hadoop.com
    
  7. 修改主机名
    修改每台主机的主机名为对应的名字并重启

配置NTP服务

  • 把linux01作为整个集群的时间同步服务器
  • 集群中所有其他服务器都来这台服务器linux01同步时间

1. 检查每台服务器所在的时区 (本文设置Shanghai)

$ date -R

如果不是+0800,如要通过如下命令调整:

# rm  -rf /etc/localtime        ---如果时区不是+0800
# ln -s /usr/share/zoneinfo/Asia/Shanghai   /etc/localtime

2. 安装ntp服务

查看ntp软件包是否已安装:

# rpm -qa | grep ntp  
ntp-4.2.6p5-1.el6.centos.x86_64
ntpdate-4.2.6p5-1.el6.centos.x86_64

如果没有那就需要安装ntp:

yum  -y install ntp

3. 修改ntp的配置文件(bigdata01.hadoop.com

vi /etc/ntp.conf

去掉第18行的#, 修改成自己的网段

restrict 192.168.239.0 mask 255.255.255.0 nomodify notrap

注释掉以下几行:

    # server 0.centos.pool.ntp.org iburst
    # server 1.centos.pool.ntp.org iburst
    # server 2.centos.pool.ntp.org iburst
    # server 3.centos.pool.ntp.org iburst

CentsOS 6.4 去掉注释第35, 36行;
CentsOS 6.536行去手动添加以下内容:

server 127.127.1.0   # local clock
fudge 127.127.1.0  stratum 10

4. 同步服务器的时间(bigdata01.hadoop.com

# ntpdate cn.pool.ntp.org   # 操作这一步时关闭ntp服务

5. 启动ntp服务(默认式开始)PC1 root用户操作

# service ntpd start
# chkconfig ntpd on
# chkconfig --list | grep ntpd
ntpd       0:off   1:off   2:on    3:on    4:on    启动状态就可以了
# ntpdate 202.120.2.101  #测试(向一个ip同步时间)
   9 Jun 15:27:49 ntpdate[2689]: the NTP socket is in use, exiting
# 表示服务器1 作为时间服务器,同步时间不可用
# ntpd一旦开启就不能手动同步时间

6. 如果另外两台的ntp的进程开启,那么需要关闭

# service --status-all | grep ntpd  查看ntpd服务是否开启
# chkconfig --list | grep ntpd     查看ntpd服务是否随开机启动
    # 如果服务可能开启  执行以下命令:
    # service ntpd stop
    # chkconfig ntpd off

7. 第2、3台向第一台同步时间

# ntpdate bigdata01.hadoop.com
18 Jan 23:01:34 ntpdate[2304]: step time server 192.168.239.211 offset -28768.643767 sec

8. 制定周期性时间同步计划任务(PC2、PC3定时向PC1手动同步时间)

在 PC2 PC3 每10分钟同步一次时间:

# crontab -e
*/10 * * * * /usr/sbin/ntpdate  bigdata01.hadoop.com

[注意]:如果确实无法向第一台同步时间,请在交互窗口(可以同时设置3台时间)执行手动设置时间 date -s '时间'.

配置SSH免密钥登录

切换为普通用户hadoop 使用普通用户操作
使用ssh登录的时候不需要用户名密码  $ sbin/start-dfs.sh, 每个节点操作  $ ssh-keygen, 生产当前主机的公钥和私钥 (~/.ssh).
分发密钥(要向3台都发送):

$  ssh-copy-id bigdata01.hadoop.com
$  ssh-copy-id bigdata02.hadoop.com
$  ssh-copy-id bigdata03.hadoop.com

测试:

$  ssh bigdata02.hadoop.com

如果测试失败,先删除.ssh目录,重做一遍:

$ rm -r ~/.ssh

安装 Hadoop

1. 下载到Linux并解压hadoop的.tar.gz

$ tar -zxf hadoop-2.5.0.tar.gz -C /opt/modules/

2. 删除 ${HADOOP_HOME}/share/doc

$ rm -rf doc/

3. 配置java环境支持在 ${HADOOP_HOME}/etc/hadoop

在  hadoop-env.sh   mapred-env.sh   yarn-env.sh 中配置

4. =======core-site.xml=======

<!--  指定第一台作为NameNode  -->
<property>
    <name>fs.defaultFS</name>
    <value>hdfs://bigdata01.hadoop.com:8020</value>
</property>
<property>
    <name>hadoop.tmp.dir</name>
    <value>/opt/modules/hadoop-2.5.0/data</value>
</property>

5. =======hdfs-site.xml=======

<property>
    <name>dfs.replication</name>
    <value>3</value>
</property>
<!-- secondarynamenode主机名 -->
<property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>bigdata02.hadoop.com:50090</value>
</property>
<!-- namenode的web访问主机名:端口号 -->
<property>
    <name>dfs.namenode.http-address</name>
    <value>bigdata01.hadoop.com:50070</value>
</property>
<!-- 关闭权限检查用户或用户组 -->
<property>
    <name>dfs.permissions.enabled</name>
    <value>false</value>
</property>

6. =======mapred-site.xml=======

<!-- 指定mapreducer向yarn提交 -->
<property>
    <name>mapreduce.framework.name</name>
    <value>yarn</value>
</property>

<property>
    <name>mapreduce.jobhistory.address</name>
    <value>bigdata01.hadoop.com:10020</value>
</property>

<property>
    <name>mapreduce.jobhistory.webapp.address</name>
    <value>bigdata01.hadoop.com:19888</value>
</property>

7. =======yarn-site.xml=======

<!-- 指定哪个节点作为resourcemanager -->
<property>
    <name>yarn.resourcemanager.hostname</name>
    <value>bigdata03.hadoop.com</value>
</property>

<!-- 在mapreducer过程中启用shuffle -->
<property>
    <name>yarn.nodemanager.aux-services</name>
    <value>mapreduce_shuffle</value>
</property>

<!-- 启用日志聚合 -->
<property>
    <name>yarn.log-aggregation-enable</name>
    <value>true</value>
</property>

<!-- 日志保存时间 -->
<property>
    <name>yarn.log-aggregation.retain-seconds</name>
    <value>86400</value>
</property>

8. 配置slaves

    bigdata01.hadoop.com
    bigdata02.hadoop.com
    bigdata03.hadoop.com

注意事项】:

  • slaves中配置集群中所有的主机名
  • 所有节点上的配置文件内容都是一样的
  • 要按照集群规划配置所属进程
  • 配置普通用户, 所有节点 有相同的帐号密码

分发

bigdata01.hadoop.com 分发hadoop(已经配置好的)目录到其他两台(bigdata02和bigdata03)服务器上;
scp -r bigdata01要复制的目录 bigdata02复制到的目录

$ scp -r /opt/modules/hadoop-2.5.0/ bigdata03.hadoop.com:/opt/modules/
$ scp -r /opt/modules/hadoop-2.5.0/ bigdata03.hadoop.com:/opt/modules/

格式化 Namenode

在namenode所在的服务器bigdata01上,进行格式化${HADOOP_HOME}/bin

$ bin/hdfs namendoe -format

注意

  • 先将PC1的hadoop配置目录分发到PC2和PC3
  • 保证3台上的配置内容一模一样
  • 先确保将3台没有格式化信息
  • 最后格式化

启动进程

1. 在PC1上使用如下命令启动HDFS

$ sbin/start-dfs.sh

2. 在PC3上使用如下命令启动YARN

$ sbin/start-yarn.sh

3. 如果要停止进程

在PC1上使用如下命令停止HDFS:
    $ sbin/stop-dfs.sh

在PC3上使用如下命令停止YARN:
    $ sbin/stop-yarn.sh

注意

  • 修改任何配置文件,请先停止所有进程,然后重新启动

检查启动是否正常

3台上 jps 查看进程:

PC1:
    28626 DataNode
    28883 NodeManager
    28989 Jps
    28531 NameNode

PC2:
    7528 DataNode
    7826 Jps
    7717 NodeManager
    7583 SecondaryNameNode

PC3
    7622 NodeManager
    7922 Jps
    7527 ResourceManager
    7405 DataNode

总结

完全分布式的搭建可以帮助更好的理解MapReduce的原理,建议自己亲自搭建一下.
此外关于map个数和reduce个数的确定:

  1. map task的个数: map task的个数和切片数相同,默认情况下切片数和block个数相同block 的大小 (默认128M) : dfs.blocksize 的文件大小 除以 128M
     切片个数确定
                 FileInputFormat.setMaxInputSplitSize(job, 1024*1024*300);  设置最大切片大小
                 FileInputFormat.setMinInputSplitSize(job, 1024*1024*100);  设置最小切片大小
                 FileInputFormat:
                     |--方法 getSplits()
                         |--long splitSize = computeSplitSize(blockSize, minSize, maxSize);
                             computeSplitSize方法中的代码
                             |-- Math.max(minSize, Math.min(maxSize, blockSize));
             切片个数 = 文件大小 / Math.max(minSize, Math.min(maxSize, blockSize));
                
             切片大小  大于 blockSize map个数减少, 网络IO
             切片大小  小于 blockSize map个数增多, 网络IO
    
  2. reduce 的个数:
      由分区个数决定