完全分布式
Hadoop最大的优势就是分布式集群计算,所以在生产环境下都是搭建的最后一种模式:完全分布模式
技术准备
系统规划
搭建
测试
上线使用

HDFS端口
8020 namenode RPC交互端口 core-site.xml
50070 NameNode web管理端口 hdfs- site.xml
50010 datanode 控制端口 hdfs -site.xml
50020 datanode的RPC服务器地址和端口 hdfs-site.xml
50075 datanode的HTTP服务器和端口 hdfs-site.xml
50090 secondary NameNode web管理端口 hdfs-site.xml

MR端口
8021 job-tracker交互端口 mapred-site.xml
50030 tracker的web管理端口 mapred-site.xml
50060 task-tracker的HTTP端口 mapred-site.xml

192.168.4.10
角色 master NameNode SecondaryNameNode ResourceManager
软件 HDFS YARN
192.168.4.11
角色 node1 DataNode NodeManager
软件 HDFS YARN
192.168.4.12
角色 node2 DataNode NodeManager
软件 HDFS YARN
192.168.4.13
角色 node3 DataNode NodeManager
软件 HDFS YARN

hadoop 完全分布式安装

规划集群 namenode ,secnedorynamenode, datanode

使用 4 台机器组件集群,其中 1台作为 master,其他3台做为 node 节点
master 上的角色 namenode , secnedorynamenode
node    上的角色 datanode

master ip => 192.168.4.10
node   ip => 192.168.4.{11,12,13}

修改 /etc/hosts ,配置 ip 与名称的对应关系
#vim /etc/hosts #同步到集群所有主机
192.168.4.10 master1
192.168.4.11 node1
192.168.4.12 node2
192.168.4.13 node3

#for i in master1 node{1..3}; do scp /etc/hosts ${i}:/etc/hosts; done
#or#
#for((i=1;i<4;i++));do rsync -a /etc/hosts 192.168.4.1${i}:/etc/ -e 'ssh'; ssh 192.168.4.${i} 'reboot'; done

禁用防火墙,禁用 selinux

在所有机器上 安装 java 运行环境 openjdk 和 jps 工具
#yum install java-1.8.0-openjdk-devel -y

在master上设置 ssh-key 信任登录,保证 master 能登录所有主机,包括自己
#ssh-keygen -b 2048 -t rsa -N '' -f key
#for i in master1 node{1..3};do ssh-copy-id ${i};done


把软件解压拷贝到 /usr/local/hadoop #配置一台其他同步即可
#scp -r hadoop-2.7.3 master1:/usr/local/hadoop
#bin/hadooop version


HDFS 完全分布式系统配置
配置 hadoop-env.sh
配置 core-site.xml
配置 hdfs-site.xml

1.编辑配置文件(master1)
hadoop-env.sh
配置 JAVA_HOME , HADOOP_CONF_DIR

#readlink -f /usr/bin/java
/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64/jre/bin/java  
#vim etc/hadoop/hadoop-env.sh
export JAVA_HOME="/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64/jre"    #有转移字符就需要加双引,此处可不加
export HADOOP_CONF_DIR="/usr/local/hadoop/etc/hadoop"

xml 配置格式
<property>
<name>关键字</name>
<value>值</value>
<description>描述说明</description>
</property>


2.core-site.xml
#vim etc/hadoop/core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master1:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name> #数据根目录
<value>/var/hadoop</value>
<description>A base for other temporary directories.</description>
</property>
</configuration>

3.hdfs-site.xml
#vim etc/hadoop/hdfs-site.xml
<configuration>
<property>
<name>dfs.namenode.http-address</name>
<value>master1:50070</value>
</property>
<property>
<name>dfs.namenode.secondary.http-address</name>
<value>master1:50090</value>
</property>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
</configuration>

4.配置 slaves ,写入所有 datanode 节点
#vim etc/hadoop/slaves
node1
node2
node3

5.同步所有文件到所有节点
#for i in node{1..3} ;do rsync -avSH --delete /usr/local/hadoop node${i}:/usr/local/ -e 'ssh';done

6.在所有节点上创建 hadoop.tmp.dir 指定的文件夹
#mkdir /var/hadoop
#for i in node{1..3};do ssh ${i} mkdir /var/hadoop;done

7.在 master 上执行格式化 namenode 的操作
#./bin/hdfs namenode -format

8.启动集群
#./sbin/start-dfs.sh
#./sbin/stop-dfs.sh #停止

验证集群:
在 master 上
jps 能看见 namenode ,secondarynamenode
#netstat -ltunp
能看见 9000,50070,50090 端口被监听
#./bin/hdfs dfsadmin -report #查看加入集群的节点

在 node 上
jps 能看见 datanode
#netstat -ltunp
能看见 50075 被监听

排错:
所有的日志在本机的 logs 里面,查看对应的角色日志

通过 web 访问 hdfs角色
http://192.168.4.10:50070/
http://192.168.4.10:50090/
http://192.168.4.12:50075/

hdfs 基本使用
#./bin/hadoop fs
#./bin/hadoop fs -ls hdfs://master1:9000/ #可简写
#./bin/hadoop fs -ls /
#./bin/hadoop fs -mkdir /input
#./bin/hadoop fs -put *.txt /input


yarn 配置文件
mapred-site.xml
yarm-site.xml

1.配置 mapred-site.xml
#cp etc/hadoop/mapred-site.xml.template etc/hadoop/mapred-site.xml
#vim etc/hadoop/mapred-site.xml
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>

2.配置 yarn-site.xml
#vim etc/hadoop/yarn-site.xml
<configuration>

<!-- Site specific YARN configuration properties -->
   <property>
       <name>yarn.nodemanager.aux-services</name>
       <value>mapreduce_shuffle</value>
   </property>
   <property>
       <name>yarn.resourcemanager.hostname</name>
       <value>master1</value>
   </property>
</configuration>

3.配置以后将配置同步到集群所有机器

4.启动服务
#./sbin/start-yarn.sh

验证配置:

在 master 上 jsp 能看见 resourecemanager,netstat 可以看见 8088 端口打开
可以访问 http://master1:8088/
在 node 上 jps 可以看见 nodemanager ,netstat 可以看见 8042 端口打开
可以访问 http://node1:8042/
master: 50070 namen ode
master: 50090 secondary node
master: 8088 resourcemanager
node: 50075 data node
node: 8042 nodemanager

在集群上做数据分析
#./bin/hadoop fs –mkdir /input
#./bin/hadoop fs –put *.txt /input
#./bin/hadoop jar ./share/hadoop/mapreduce/hadoop-mapreduce-examples-2.7.3.jar wordcount /input /output

查看分析结果
#./bin/hadoop fs -cat hdfs://192.168.4.10:9000/output/*


hdfs 进阶应用 NFS 网关

NFS 网关用途
1.用户可以通过操作系统兼容的本地NFSv3客户端来阅览HDFS文件系统
2.用户可以从HDFS文件系统下载文档到本地文件系统
3.用户可以通过挂载点直接流化数据。支持文件附加,但是不支持随机写
NFS 网关支持NFSv3和允许HDFS 作为客户端文件系统的一部分被挂载
#./sbin/stop-all.sh
#jps

特性与注意事项
不支持随机写
在非安全模式,运行网关的用户是代理用户
在安全模式时,Kerberos keytab中的用户是代理用户
AIX NFS有一些知道的问题,不能让默认的HDFS NFS网关正常工作,如果想在 AIX 访问NFS 网关需要配置下面的参数
<property>
<name>nfs.aix.compatibility.mode.enabled</name>
<value>true</value>
</property>

HDFS超级用户是与NameNode进程本身具有相同标识的用户,超级用户可以执行任何操作,因为权限检查永远不会为超级用户失败。

<property>
<name>nfs.superuser</name>
<value>the_name_of_hdfs_superuser</value>
</property>

新建一台主机nfswg 192.168.4.15
安装jdk1.8 复制一份 hadoop 到本机
#rsync -azSH --delete master:/usr/local/hadoop /usr/local/

#vim /etc/hosts #同步到集群所有主机
192.168.4.10 master1
192.168.4.11 node1
192.168.4.12 node2
192.168.4.13 node3
192.168.4.15 nfswg

NFS & portmap 相关配置
core-site.xml
hdfs-site.xml

1.core-site.xml(10-13 15)
hadoop.proxyuser.{nfsuser}.groups
hadoop.proxyuser.{nfsuser}.hosts
这里的 nfsuser 是你机器上真实运行 nfsgw 的用户
在非安全模式,运行nfs网关的用户为代理用户
#vim etc/hadoop/core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://master1:9000</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/hadoop</value>
<description>A base for other temporary directories.</description>
</property>
<property> #挂载点用户所使用的组
<name>hadoop.proxyuser.nfsuser.groups</name>
<value></value>
</property>
<property> #挂载点主机地址
<name>hadoop.proxyuser.nfsuser.hosts</name>
<value>
</value>
</property>
</configuration>
#该配置要同步到其他所有主机上

2.hdfs-site.xml (注意 只在nfsgw 15!)
nfs.exports.allowed.hosts (* rw) #允许那些主机 访问权限默认ro
dfs.namenode.accesstime.precision (3600000) #减少atime更新减少I/O压力
nfs.dump.dir (/tmp/.hdfs-nfs) #转储目录推荐有1G空间
nfs.rtmax (4194304) 一次读占用4M内存
nfs.wtmax (1048576) 以此写占用1M内存
用户可以像访问本地文件系统的一部分一样访问HDFS,但硬链接和随机写还不支持。对于大文件I/O的优化,可以在mount的时候增加NFS传输的大小(rsize和wsize)。在默认情况下,NFS网关支持1MB作为最大的传输大小。更大的数据传输大小,需要在hdfs-site.xml中设置“nfs.rtmax” 和“nfs.wtmax”
nfs.port.monitoring.disabled (false) #允许从没有权限的客户端挂载 nfs

#vim etc/hadoop/hdfs-site.xml   #只配置nfswg
<configuration>
    <property>
    <name>dfs.namenode.http-address</name>
    <value>master1:50070</value>
    </property>
    <property>
    <name>dfs.namenode.secondary.http-address</name>
    <value>master1:50090</value>
    </property>
    <property>
    <name>dfs.replication</name>
    <value>2</value>
    </property>
    <property>  #允许挂载的客户端
    <name>nfs.exports.allowed.hosts</name>
    <value>* rw</value> #Java正则或者IP,多个用;来分割
    </property>
    <property>
    <name>dfs.namenode.accesstime.precision</name>
    <value>3600000</value>  #默认值1小时
    </property>
    <property>
    <name>nfs.dump.dir</name>   #转储目录
    <value>/tmp/.hdfs-nfs</value>
    </property>
    <property>
    <name>nfs.rtmax</name>
    <value>4194304</value>  #4M
    </property>
    <property>
    <name>nfs.wtmax</name>
    <value>1048576</value>
    </property>
    <property>
    <name>nfs.port.monitoring.disabled</name>
    <value>false</value>
    </property>
</configuration>
该配置文件不需要同步到其他主机

这里要注意 关闭系统的 portmap 和 nfs 服务添加用户
#yum erase nfs-utils rpcbind #移除掉防止系统调用错误
确保2049 111端口不被占用就可以

在nfsgw和master1上创建用户 确保两处用户uid gid和用户组 要一致
#useradd nfsuser

nfsgw:设置权限
给nfs代理用户写日志的权限
#setfacl -m u:nfsuser:rwx /usr/local/hadoop/logs
#mkdir /tmp/.hdfs-nfs #创建转储目录
#chown nfsuser:nfsuser /tmp/.hdfs-nfs

重启 hdfs 集群服务 在namenode上
#./sbin/stop-dfs.sh
#./sbin/start-dfs.sh
#./bin/hdfs dfsadmin -report
#jps 查看启动

在nfswg上启动 portmap 服务 #启动 portmap 需要使用 root 用户
#./sbin/hadoop-daemon.sh --script ./bin/hdfs start portmap
#jps 查看有portmap角色
#netstat 有111端口

启动 nfs3 服务 #启动 nfs3 需要使用 core-site 里面设置的用户
sudo -u 你core-site里面配置的用户
#su -l nfsuser
#./sbin/hadoop-daemon.sh --script ./bin/hdfs start nfs3

在一台新机器上挂载测试15
#mount -t nfs -o vers=3,proto=tcp,nolock,sync,noatime,noacl 192.168.4.15:/ /mnt #
#cd /mnt
#ls
挂载 nfs
目前NFS v3仅使用TCP作为传输协议。 不支持NLM,因此需要安装选项“nolock”。 强烈建议使用安装选项“sync”,因为它可以最小化或避免重新排序写入,这将导致更可预测的吞吐量。 未指定同步选项可能会导致上传大文件时出现不可靠的行为
如果必须使用软安装,用户应该给它一个相对较长的超时(至少不小于主机上的默认超时)


调试与日志排错
在配置 NFS 网关过程中经常会碰到各种各样的错误,
如果出现了错误,打开调试日志是一个不错的选择
#vim etc/hadoop/log4j.property #加入下面项
log4j.logger.org.apache.hadoop.hdfs.nfs=DEBUG
log4j.logger.org.apache.hadoop.oncrpc=DEBUG

nfs.map
系统管理员必须确保在NFS客户端的用户和在HDFS网关主机上的用户有相同的名称和UID。
不同主机上创建的用户需要修改UID(例如使用“usermod -u 123myusername”),在NFS客户端或者NFS网关主机
来进行。如果客户端的用户和NFS网关的用户 uid 不能保持一致需要我们配置 nfs.map 的静态映射关系
#vim etc/hadoop/nfs.map
uid 10 100 # Map the remote UID 10 the local UID 100
gid 11 101 # Map the remote GID 11 to the local GID 101


HDFS 增加节点

  1. 配置hadoop环境,包括主机名、ssh免密码登录、禁用 selinux、iptables、安装 java 环境
    #vim /etc/hosts #同步到集群所有机器
    192.168.4.10 master1
    192.168.4.11 node1
    192.168.4.12 node2
    192.168.4.13 node3
    192.168.4.14 newnode
    192.168.4.15 nfswg
    #yum install java-1.8.0-openjdk-devel -y

  2. 修改namenode的slaves文件增加该(newnode 14 )节点
    #vim etc/hadoop/slave
    node1
    node2
    node3
    newnode

    同步所有
    #!/bin/bash
    for i in node{1..3}
    do
    rsync -avSH --delete /usr/local/hadoop/etc/hadoop/ ${i}:/usr/local/hadoop/etc/hadoop/ -e 'ssh'
    wait
    done

  3. 把namnode的hadoop复制到newnode目录下
    #rsync -avSH --delete /usr/local/hadoop newnode:/usr/local/ -e 'ssh'

  4. 在newnode启动Datanode
    #./sbin/hadoop-daemon.sh start datanode
    #jps #查看有Datanode

  5. 在master上增加同步数据带宽,默认后台转数据,将原有服务器的数据均到新节点上但是有点慢
    #./bin/hdfs dfsadmin
    #./bin/hdfs dfsadmin -setBalancerBandwidth 67108864 #增加同步数据的带宽
    #./sbin/start-balancer.sh -threshold 5 #启动同步线程

  6. 查看集群状态
    #./bin/hdfs dfsadmin -report

HDFS 删除节点

  1. 配置NameNode的hdfs-site.xml
    #vim etc/hadoop/hdfs-site.xml
    #检查 dfs.replication 设置的副本数量,备份份数要小于删除后的节点数
    #增加 dfs.hosts.exclude 配置
    <property>
    <name>dfs.hosts.exclude</name>
    <value>/usr/local/hadoop/etc/hadoop/exclude</value>
    </property>

  2. 增加 exclude 配置文件,写入要删除的节点 ip
    #vim etc/hadoop/exclude
    newnode

  3. 将配置同步到剩余 所有节点上
    #./rsyncfile.sh

  4. 在master更新数据
    #./bin/hdfs dfsadmin -refreshNodes

  5. 查看状态
    #./bin/hdfs dfsadmin -report
    Hostname: node5
    Decommission Status : Decommission in progress
    #等待状态面成下面在继续操作 否则集群会崩哒!
    #./bin/hdfs dfsadmin -report
    Hostname: node5
    Decommission Status : Decommissioned

    关闭节点
    #./sbin/hadoop-daemon.sh stop datanode
    #jps 此时没有任何角色了


HDFS 修复节点
修复节点比较简单
单独配置一台新 datanode
启动服务
#./sbin/hadoop-daemon.sh start datanode
数据恢复是自动的
我们上线以后会自动恢复数据,如果数据量非常巨大,可能需要一定的时间

Yarn 的相关操作
由于在 2.x hadoop 引入了 yarn 框架,对于计算节点的操作已经变得非常简单

增加节点
#sbin/yarn-daemon.sh start nodemanager

删除节点
#sbin/yarn-daemon.sh stop nodemanager

查看节点 (Resourcemanager)
#./bin/yarn node -list
当没成功时 重启服务再查看 
#./sbin/stop-yarn.sh
#./sbin/start-yarn.sh 

HDFS 还有很多其他的应用方式,比如 native-hdfs,有兴趣的可以自行测试
用到的软件依赖
cmake, fuse-devel
protobuf
protobuf-c
native-hdfs-fuse

知识点总结
Hadoop 完全分布式安装的配置
java 环境
ssh key 认证
hosts 配置
hadoop-env.sh
core-site.xml
hdfs-site.xml
mapred-site.xml
yarn-site.xml
slaves
Hadoop NFS网关
hadoop-env.sh
core-site.xml
hdfs-site.xml
mount 参数