Hadoop的安装分为单机方式、伪分布式方式 和 完全分布式方式。
单机模式 : Hadoop的默认模式。当首次解压Hadoop的源码包时,Hadoop无法了解硬件安装环境,便保守地选择了最小配置。在这种默认模式下所有3个XML文件均为空。当配置文件为空时,Hadoop会完全运行在本地。因为不需要与其他节点交互,单机模式就不使用HDFS,也不加载任何Hadoop的守护进程。该模式主要用于开发调试MapReduce程序的应用逻辑 .
伪分布模式 : Hadoop守护进程运行在本地机器上,模拟一个小规模的的集群。可以使用HDFS和MapReduce .
完全分布模式 : Hadoop守护进程运行在一个集群上。启动所有的守护进程,具有Hadoop完整的功能,可以使用hdfs、mapreduce和yarn,并且这些守护进程运行在集群中,可以真正的利用集群提供高性能,在生产环境下使用 .
伪分布式安装
- 关闭防火墙
service iptables start ; service iptables stop #立即开启/关闭防火墙,但是重启系统后失效
chkconfig iptables on; chkconfig iptables off #开启防火墙,重启后系统后仍生效
-
配置主机名
主机名里不能有_或者$,不然会找不到主机导致无法启动
vim /etc/sysconfig/network
NETWORKING=yes HOSTNAME=hadoop01
source /etc/sysconfig/network
-
配置免密码互通
问题 : Hadoop底层是基于RPC来实现的,所以Hadoop中的很多操作都是通过网络进行信号的传输,也就意味着如果想要访问其他的节点,都需要输入密码。
解决方案 : 生成自己的公钥和私钥,生成的公私钥将自动存放在 /root/.ssh目录下。
$ ssh-keygen #把生成的公钥copy到远程机器上
$ ssh-copy-id [user]@[host]
#此时在远程主机的/root/.ssh/authorized_keys文件中保存了公钥,在known_hosts中保存了已知主机信息,当再次访问的时候就不需要输入密码了。
$ ssh [host] #通过此命令远程连接,检验是否可以不需密码连接 -
安装JDK , Hadoop的运行环境中必须有JDK
-
安装Hadoop
-
解压安装包 : tar -zxvf [Hadoop安装包位置]
-
配置 Hadoop
hadoop-env.sh : 修改JAVA_HOME的路径
-
export JAVA_HOME=${JAVA_HOME} #修改成具体的JDK路径
core-site.xml : 增加namenode配置、产生文件存储位置配置
<configuration>
<property>
<!--用来指定hdfs的老大,namenode的地址-->
<name>fs.defaultFS</name>
<value>hdfs://hadoop01:9000</value>
</property>
<property>
<!--用来指定hadoop运行时产生文件的存放目录-->
<name>hadoop.tmp.dir</name>
<value>/home/park/work/hadoop-2.7.1/tmp</value>
</property>
</configuration>
hdfs-site.xml : 配置包括自身在内的备份副本数量。
<configuration>
<property>
<!--指定hdfs保存数据副本的数量,包括自己,默认为3-->
<!--伪分布式模式,此值必须为1-->
<name>dfs.replication</name>
<value>3</value>
</property>
</configuration>
mapred-site.xml : 配置mapreduce运行在yarn上
说明 : 在/etc/hadoop的目录下,只有一个mapred-site.xml.template文件,
复制cp mapred-site.xml.template 并命名为 mapred-site.xml
<configuration>
<property>
<!--指定mapreduce运行在yarn上-->
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
yarn-site.xml
<configuration>
<property>
<!--指定yarn的老大resourcemanager的地址-->
<name>yarn.resourcemanager.hostname</name>
<value>hadoop01</value>
</property>
<property>
<!--NodeManager获取数据的方式-->
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
slaves
hadoop01 #当前主机名
3. 配置Hadoop的环境变量
vim /etc/profile
JAVA_HOME=/home/software/jdk1.8
HADOOP_HOME=/home/software/hadoop-2.7.1
CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
PATH=$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
export JAVA_HOME PATH CLASSPATH HADOOP_HOME
4. 格式化namenode(仅首次启动时需要执行)
hadoop namenode -format
格式化namenode的原因 : 在namenode节点上,有两个重要的路径分别用来存储元数据信息和操作日志 . 这两个路径来自于配置文件 , 它们对应的属性为dfs.name.dir 和dfs.name.edits.dir , 它们默认的路径均为 /tmp/hadoop/dfs/name. 格式化namenode时, namenode 会清空两个目录下的所有文件, 然后在 dfs.name.dir 目录下创建以下文件 /current/fsimage、/current/fstime、/current/VERSION、/image/fsimage
在dfs.name.edits.dir 目录下创建以下文件
/current/edits 、/current/fstime、/current/VERSION、/image/fsimage
namenode中的核心文件
fsimage : 这是元数据的镜像文件,它存在硬盘上,它并不是元数据的实时同步. 只有在满足条件的时候才进行数据同步 . 它存在的意义就是为了崩溃恢复 .
这里的条件是指: 默认3600s同步一次,当edits达到64M同步一次,Hadoop重启的时候同步一次.
edits: 日志文件 , 每当客户端操作一次hdfs就会先在日志文件下留下操作日志 , 然后才在内存中生成相应的元数据 .
在操作hdfs的时候namenode会将元数据保留在内存一份,这样的话会大大提高请求的应答效率. 而上述的fsimage和edits都是硬盘层面的.
fstime: 记载checkpoint的时间 , 也就是上一次我的fsimage所更新的时间 , 这样的话就能够计算出什么时间应该进行下一次更新 .
VERSION : 用来存储namenode版本信息
/image/fsimage : 上一次提交前的/current/fsimage文件
问题 : 如果格式化多次namenode , 会导致datanode无法启动 , 原因是 每一次格式化namenode都会生成新的clusterID , 而datanode还是保持原来的clusterID
解决办法: 将namenode的clusterID(/tmp/dfs/name/current/VERSION)复制到datanode(/tmp/dfs/data/current/VERSION)的clusterID替换掉.
5 . 启动Hadoop : start-all.sh
启动hdfs : start-dfs.sh
6. 通过浏览器访问hadoop管理页面 http://[server_ip] : 50070
完全分布式安装
为了解决Hadoop1中的单点问题 , 在Hadoop2中可以配置多个NameNode(目前只支持两个),形成互为热备的状态,解决NameNode单节点故障的问题。每一个NameNode都有相同的职能 , 一个是active状态 , 一个是standby状态 . 当集群运行时, 只有active状态的NameNode是正常工作的 , standby状态的namenode是处于待命状态的 , 时刻同步active状态的NameNode的数据 . 一旦active状态的NameNode不能工作 , 通过手工或者自动切换 , standby状态的NameNode就可以转变为active状态 , 继续工作 . 这就是高可用 .
使用JournalNodes集群进行数据共享
两个NameNode为了数据同步 , 会通过一组称作 JournalNodes的独立进程进行相互通信 . 当active状态的NameNode的命名空间有任何修改时 , 会告知大部分的JournalNodes进程 . standby状态的NameNode有能力读取JN集群中的变更信息, 并且一直监控edit log 的变化 , 把变化应用于自己的命名空间. standby 可以确保在集群出错时 , 命名空间已经完全同步了 .
故障切换
对于Hadoop集群而言, 确保同一时刻只有一个NameNode处于active状态是至关重要的 . 否则, 两个NameNode的数据状态就会产生分歧 , 可能丢失数据或者产生错误的结果 . 为了保证这点 , 就需要使用Zookeeper了 . 首先HDFS集群中的两个NameNode都在Zookeeper中进行注册, 当active状态的NameNode出故障时, Zookeeper能检测到这种情况 , 它会自动把standby状态的NameNode切换为active状态.两个NameNode通过Zookeeper实现选举,这个选举的过程是由FailOverController来具体执行的
NameNode(Active): 真正在工作状态的NameNode,保持着元数据,并将元数据的更新信息写入JN
NameNode(Standby): 处在备用装填的NameNode,从JN中获取信息,同步元数据。
DataNode:保存数据的节点
JN集群:用来同步元数据的集群,为了防止单节点故障,做成了集群。
Zookeeper:负责集群协调,包括NameNode的选举
FailOverController:联系NameNode和Zookeeper的进程
Hadoop完全分布式集群规划
i. 两个NameNode一般单独安装
ii. FailOverController的进程必须和NameNode装在一起
iii. ResourceManager一般单独安装或和NameNode安装到一起
iv. DataNode单独安装
v. NodeManager一般和DataNode装在一起
vi. JN要么单独安装,要么和DataNode装在一起
vii. Zookeeper通常是一个单独的集群,如果没有条件也可以配置在hadoop集群中
机器角色
- hadoop01
NameNode 、FailOverController 、ResourceManager、
DataNode、NodeManager、JN、Zookeeper
2. hadoop02
NameNode、FailOverController、DataNode、
NodeManager、JN、Zookeeper
-
hadoop03
DataNode、NodeManager、JN、Zookeeper配置Hadoop完全分布式
-
关闭防火墙
-
修改主机名
-
配置免密登录
-
安装Zookeeper集群
-
配置JDK
-
安装Hadoop并配置环境变量
-
配置文件
export JAVA_HOME=${JAVA_HOME} #修改成具体的JDK路径
core-site.xml
<configuration> <!-- 指定hdfs的nameservice为ns --> <property> <name>fs.defaultFS</name> <value>hdfs://ns</value> </property> <!--指定hadoop数据临时存放目录--> <property> <!--在hadoop安装目录下 创建一个tmp目录--> <name>hadoop.tmp.dir</name> <value>/home/software/hadoop-2.7.1x/temp</value> </property> <property> <name>io.file.buffer.size</name> <value>4096</value> </property> <!--指定zookeeper地址--> <property> <name>ha.zookeeper.quorum</name> <value>hadoop01:2181,hadoop02:2181,hadoop03:2181</value> </property> </configuration>
hdfs-site.xml
<configuration> <!--指定hdfs的nameservice为ns,需要和core-site.xml中的保持一致 --> <property> <name>dfs.nameservices</name> <value>ns</value> </property> <!-- ns下面有两个NameNode,分别是nn1,nn2 --> <property> <name>dfs.ha.namenodes.ns</name> <value>nn1,nn2</value> </property> <!-- nn1的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.ns.nn1</name> <value>hadoop01:9000</value> </property> <!-- nn1的http通信地址 --> <property> <name>dfs.namenode.http-address.ns.nn1</name> <value>hadoop01:50070</value> </property> <!-- nn2的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.ns.nn2</name> <value>hadoop02:9000</value> </property> <!-- nn2的http通信地址 --> <property> <name>dfs.namenode.http-address.ns.nn2</name> <value>hadoop02:50070</value> </property> <!-- 指定NameNode的元数据在JournalNode上的存放位置 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://hadoop01:8485;hadoop02:8485;hadoop03:8485/ns</value> </property> <!-- 指定JournalNode在本地磁盘存放数据的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/home/software/hadoop-2.7.1x/tmp/journal</value> </property> <!-- 开启NameNode故障时自动切换 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!-- 配置失败自动切换实现方式 --> <property> <name>dfs.client.failover.proxy.provider.ns</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <!-- 配置隔离机制 --> <property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <!-- 使用隔离机制时需要ssh免登陆 --> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <property> <!--NameNode数据存放位置--> <name>dfs.namenode.name.dir</name> <value>file:///home/software/hadoop-2.7.1x/tmp/hdfs/name</value> </property> <property> <!--DataNode数据存放位置--> <name>dfs.datanode.data.dir</name> <value>file:///home/software/hadoop-2.7.1x/tmp/hdfs/data</value> </property> <!--HDFS副本数量--> <property> <name>dfs.replication</name> <value>2</value> </property> </configuration>
mapredu-site.xml
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
yarn-site.xml
<configuration> <!-- 指定nodemanager启动时加载server的方式为shuffle server --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 指定resourcemanager地址 --> <property> <name>yarn.resourcemanager.hostname</name> <value>hadoop01</value> </property> </configuration>
slaves
hadoop01 hadoop02 hadoop03
-
复制hadoop到集群其他机器
scp -r hadoop-2.7.1x root@hadoop02:/home/software
scp -r hadoop-2.7.1x root@hadoop03:/home/software
-
集群的启动
-
启动Zookeeper集群
分别在三台机器上执行 sh zkServer.sh start
执行jps , 查看是否启动成功
- 在hadoop01上启动 JournalNode集群
hadoop-daemon.sh start journalnode
执行jps , 查看是否启动成功
- 格式化zkfc , 在zookeeper中生成ha节点 (第一次启动时)
在hadoop01(Active NameNode节点)执行 hdfs zkfc -formatZK , 会出现节点名称
格式化成功后可以在zookeeper执行 ls /hadoop-ha
- 格式化NameNode(第一次启动时)
在Active NameNode节点执行 : hdfs namenode -format - 在hadoop01上启动active的namenode节点
hadoop-daemon.sh start namenode
- 在hadop02上同步namenode的数据 , 并启动standby的namenode节点
hdfs namenode -bootstrapsStandby
hadoop-daemon.sh start namenode
- 启动DataNode节点
在ActiveNameNode节点上运行 : hadoop-daemons.sh start datanode
- 启动zkfc
在每个NameNode节点上运行 : hadoop-daemon.sh start zkfc
- 在作为resourcemanager的机器启动yarn
- 启动结果
hadoop01 :
NameNode
DFSZKFailoverController
NodeManager
QuorumPeerMain
DataNode
ResourceManager
JournalNode
Jps
hadoop02 :
Jps
DFSZKFailoverController
NodeManager
QuorumPeerMain
DataNode
JournalNode
NameNode
hadoop03
DataNode
NodeManager
QuorumPeerMain
JournalNode
Jps
- Yarn完全分布式配置
mapredu-site.xml
<configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
yarn-site.xml
<configuration> <!-- 配置可以在 nodemanager 上运行 mapreduce 程序 --> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> <!-- 激活 resourcemanager 高可用 --> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <!-- 指定 resourcemanager 的集群 id --> <property> <name>yarn.resourcemanager.cluster-id</name> <value>RM_CLUSTER</value> </property> <!-- 定义 RM 的节点--> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <!-- 指定 RM1 的地址 --> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>hadoop01</value> </property> <!-- 指定 RM2 的地址 --> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>hadoop02</value> </property> <!-- 激活 resourcemanager 自动恢复 --> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <!-- 配置 resourcemanager 状态信息存储方式,有 MemStore 和 ZKStore--> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> <!-- 配置为 zookeeper 存储时,指定 zookeeper 集群的地址 --> <property> <name>yarn.resourcemanager.zk-address</name> <value>hadoop01:2181,hadoop02:2181,hadoop03:2181</value> </property> </configuration>
启动yarn ha模式
在Active ResourceManager上启动 : start-yarn.sh
在BackUp ResourceManager上启动 : yarn-daemon.sh start resourcemanager
通过浏览器访问8088端口