准备环境:
7台Linux虚拟机都已经安装Hadoop2.X(是单机版)并且各服务器之间都已经配置SSH免密码登录。
我的安装步骤:每台机器先将单机版本部署;将02、03、11三台机安装好ZooKeeper;最后修改配置文件(配置文件复制给每台机器即可):
修改配置文件:
1、core-site.xml
<configuration> <property> <name>fs.defaultFS</name> <value>hdfs://ns1/</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/hadoop-sv/HADOOP/hadoop-2.6.5/tmp</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>Hadoop-ABO-02:2181,Hadoop-ABO-03:2181,Hadoop-ABO-11:2181</value> </property> </configuration>
2、hdfs-site.xml
<configuration> <property> <name>dfs.nameservices</name> <value>ns1</value> </property> <property> <name>dfs.ha.namenodes.ns1</name> <value>nn1,nn2</value> </property> <!-- nn1的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.ns1.nn1</name> <value>Hadoop-ABO-04:9000</value> </property> <!-- nn1的http通信地址 --> <property> <name>dfs.namenode.http-address.ns1.nn1</name> <value>Hadoop-ABO-04:50070</value> </property> <!-- nn2的RPC通信地址 --> <property> <name>dfs.namenode.rpc-address.ns1.nn2</name> <value>Hadoop-ABO-05:9000</value> </property> <!-- nn2的http通信地址 --> <property> <name>dfs.namenode.http-address.ns1.nn2</name> <value>Hadoop-ABO-05:50070</value> </property> <!-- 指定NameNode的元数据在JournalNode上的存放位置 --> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://Hadoop-ABO-11:8485;Hadoop-ABO-02:8485;Hadoop-ABO-03:8485/ns1</value> </property> <!-- 指定JournalNode在本地磁盘存放数据的位置 --> <property> <name>dfs.journalnode.edits.dir</name> <value>/hadoop-sv/HADOOP/hadoop-2.6.5/journaldata</value> </property> <!-- 开启NameNode失败自动切换 --> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property> <!-- 配置失败自动切换实现方式 --> <property> <name>dfs.client.failover.proxy.provider.ns1</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <!-- 配置隔离机制方法,多个机制用换行分割,即每个机制暂用一行--> <property> <name>dfs.ha.fencing.methods</name> <value> sshfence shell(/bin/true) </value> </property> <!-- 使用sshfence隔离机制时需要ssh免登陆--> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <!-- 配置sshfence隔离机制超时时间 --> <property> <name>dfs.ha.fencing.ssh.connect-timeout</name> <value>30000</value> </property> </configuration>
3、mapred-site.xml <!-- 我的不需要修改 -->
<configuration> <!-- 指定mr框架为yarn方式 --> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration>
4、yarn-site.xml
<configuration> <!-- 开启RM高可用 --> <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <!-- 指定RM的cluster id --> <property> <name>yarn.resourcemanager.cluster-id</name> <value>yrc</value> </property> <!-- 指定RM的名字 --> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <!-- 分别指定RM的地址 --> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>Hadoop-ABO-06</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>Hadoop-ABO-07</value> </property> <!-- 指定zk集群地址 --> <property> <name>yarn.resourcemanager.zk-address</name> <value>Hadoop-ABO-11:2181,Hadoop-ABO-02:2181,Hadoop-ABO-03:2181</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration>
5、修改slaves,只在Hadoop-ABO-04和Hadoop-ABO-06,当他们的小弟不同时候,slaves可以不一样。(slaves是指定子节点的位置,因为要在Hadoop-ABO-04上启动HDFS、在Hadoop-ABO-06启动yarn,所以Hadoop-ABO-04上的slaves文件指定的是datanode的位置,Hadoop-ABO-06上的slaves文件指定的是nodemanager的位置,datanode和nodemanager在一起,在一起)。
Hadoop-ABO-11
Hadoop-ABO-02
Hadoop-ABO-03
(在单一的机器上配置完之后,可以将其拷贝到其他机器上,然后开始启动集群)
启动集群:首次
1、 启动zookeeper集群(分别在>Hadoop-ABO-11、>Hadoop-ABO-02、>Hadoop-ABO-03上启动zk)
cd /Hadoop-ABO-11/ZooKeeper/zookeeper-3.4.5/bin/
./zkServer.sh start
#查看状态:一个leader,两个follower
./zkServer.sh status
此时的Zookeeper中只有zookeeper一个节点。
2、启动journalnode(分别在>Hadoop-ABO-11、>Hadoop-ABO-02、>Hadoop-ABO-03上执行)
cd /Hadoop-ABO-11/HADOOP/hadoop-2.6.5/
sbin/hadoop-daemon.sh start journalnode
#运行jps命令检验,Hadoop-ABO-11、Hadoop-ABO-02、Hadoop-ABO-03上多了JournalNode进程。 也会多个目录:journaldata
3、格式化HDFS
#在NN的一个节点上执行命令:
hdfs namenode -format
#格式化后会在根据core-site.xml中的hadoop.tmp.dir配置生成个文件,同时在journaldata目录中生成ns1目录
之后要拷贝tmp文件到另一台NN 但是建议在另一台NN上执行建议hdfs namenode -bootstrapStandby来实现拷贝(保证元数据的一致性)
4、格式化ZKFC(在Hadoop-ABO-04上执行即可)
hdfs zkfc -formatZK
此时Zookeeper中的节点会对一个:hadoop-ha ,同时它的子节点为ns1
5、启动HDFS(在在Hadoop-ABO-04上执行)
sbin/start-dfs.sh
此时NN的HA机制已经跑起来了!
6、启动YARN(#####注意#####:是在Hadoop-ABO-06上执行start-yarn.sh,把namenode和resourcemanager分开是因为性能问题,因为他们都要占用大量资源,所以把他们分开了,他们分开了就要分别在不同的机器上启动)
sbin/start-yarn.sh
此时Yarn的HA没有跑起来还需要手动:hadoop-daemon.sh 或者 yarn-daemon.sh start resourcemanager
到此,hadoop配置完毕,可以统计浏览器访问:
http://192.168.20.114:50070
NameNode 'Hadoop-ABO-04:9000' (active)
http://192.168.20.115:50070
NameNode 'Hadoop-ABO-05:9000' (standby)
验证集群:
验证HDFS HA: 首先向hdfs上传一个文件 hadoop fs -put /etc/profile /profile hadoop fs -ls / 然后再kill掉active的NameNode Hadoop-ABO-04 kill -9 <pid of NN> 通过浏览器访问:http://192.168.20.115:50070 NameNode 'Hadoop-ABO-05:9000' (active) 这个时候Hadoop-ABO-05上的NameNode变成了active 在执行命令: hadoop fs -ls / -rw-r--r-- 3 root supergroup 1926 2014-02-06 15:36 /profile 刚才上传的文件依然存在!!! 手动启动那个挂掉的NameNode Hadoop-ABO-04 sbin/hadoop-daemon.sh start namenode 通过浏览器访问:http://192.168.20.114:50070 NameNode 'Hadoop-ABO-04:9000' (standby)
验证YARN:
运行一下hadoop提供的demo中的WordCount程序:
hadoop jar share/hadoop/mapreduce/hadoop-mapreduce-examples-2.4.1.jar wordcount /profile /out
hadoop datanode节点超时时间设置
datanode进程死亡或者网络故障造成datanode无法与namenode通信, namenode不会立即把该节点判定为死亡,要经过一段时间,这段时间暂称作超时时长。 HDFS默认的超时时长为10分钟+30秒。如果定义超时时间为timeout,则超时时长的计算公式为: timeout = 2 * heartbeat.recheck.interval + 10 * dfs.heartbeat.interval。 而默认的heartbeat.recheck.interval 大小为5分钟,dfs.heartbeat.interval默认为3秒。 需要注意的是hdfs-site.xml 配置文件中的 heartbeat.recheck.interval的单位为毫秒, dfs.heartbeat.interval的单位为秒。 所以,举个例子,如果heartbeat.recheck.interval设置为5000(毫秒),dfs.heartbeat.interval设置为3(秒,默认),则总的超时时间为40秒。 hdfs-site.xml中的参数设置格式: <property> <name>heartbeat.recheck.interval</name> <value>2000</value> </property> <property> <name>dfs.heartbeat.interval</name> <value>1</value> </property>
HDFS冗余数据块的自动删除
在日常维护hadoop集群的过程中发现这样一种情况: 某个节点由于网络故障或者DataNode进程死亡,被NameNode判定为死亡, HDFS马上自动开始数据块的容错拷贝; 当该节点重新添加到集群中时,由于该节点上的数据其实并没有损坏, 所以造成了HDFS上某些block的备份数超过了设定的备份数。 通过观察发现,这些多余的数据块经过很长的一段时间才会被完全删除掉, 那么这个时间取决于什么呢? 该时间的长短跟数据块报告的间隔时间有关。 Datanode会定期将当前该结点上所有的BLOCK信息报告给Namenode, 参数dfs.blockreport.intervalMsec就是控制这个报告间隔的参数。 hdfs-site.xml文件中有一个参数: <property> <name>dfs.blockreport.intervalMsec</name> <value>10000</value> <description>Determines block reporting interval in milliseconds.</description> </property> 其中3600000为默认设置,3600000毫秒,即1个小时,也就是说,块报告的时间间隔为1个小时,所以经过了很长时间这些多余的块才被删除掉。 通过实际测试发现,当把该参数调整的稍小一点的时候(60秒),多余的数据块确实很快就被删除了。