在集群模式下有一个NameNode,数据磁盘化由SNN去做,高可用模式下有两个(hadoop2.0)或多个(3.0)NameNode ,一个主 其他的是备 ,备用节点可以去做磁盘化。
架构如下所示
部署架构图
node1: nameNode1 journal1 DataNode1
node2: journal2 DataNode2
node3: journal3 DataNode3
node4: nameNode1
利用集群模式修改配置文件
首先部署两个NameNode修改配置文件 mycluster为集群名称,根据此名称可以找到其他NameNode
vim core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>node1:2181,node2:2181,node3:2181</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/data/DataOrLogs/hadoop/ha</value>
</property>
</configuration>
vim hdfs-site.xml
<configuration>
<!-- NameNode两台节点配置 -->
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
<property>
<name>dfs.ha.namenodes.mycluster</name>
<value>nn1,nn2</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn1</name>
<value>node1:9000</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>node4:9000</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>node1:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>node4:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1:8485;node2:8485;node3:8485/mycluster</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/data/DataOrLogs/hadoop/ha/hadoop/local/dfs/jn</value>
</property>
<!-- 发出NameNode的选举 决定哪个NameNode是Active 谁是standalone的代理类 -->
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 通过ssh免密通知哪个NameNode是Active 谁是standalone -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
</property>
<property>
<name>dfs.ha.fencing.ssh.private-key-files</name>
<value>/root/.ssh/id_rsa</value>
</property>
<!-- 自动故障转移 不需要指定机器 和NameNode在同一台机器 因为他要和NameNode保持一直 监控 -->
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
<!-- 配置sshfence隔离机制超时时间 -->
<property>
<name>dfs.ha.fencing.ssh.connect-timeout</name>
<value>30000</value>
</property>
<!-- 配置副本数,注意,伪分布模式只能是1。-->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<!-- 修改默认NameNode持久化目录 防止内存紧缺时回收/tmp下文件 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file:/data/DataOrLogs/hadoop/ha/hadoop/local/dfs/name</value>
</property>
<!-- 修改默认DataNode持久化目录 防止内存紧缺时回收/tmp下文件 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file:/data/DataOrLogs/hadoop/ha/hadoop/local/dfs/data</value>
</property>
</configuration>
流程
ssh 免密:
启动start-dfs.sh的脚本机器需要将公钥分发给其他的机器 (前面已经做过)
在HA模式下,ZKFC之间通过ssh方式控制自己和其他NameNode节点的状态
搭建FC
FC需要zookeeper协调 通过回调的机制在一方掉线时候通知另一方更改NameNode状态
初始化启动
先启动JN,hadoop-daemon.sh start journalnode ,因为JN是为NameNode提供数据存储服务如果不先启动 再格式化NameNode后启动,NameNode会加载JN中的数据 造成格式化不起作用
选择一个nameNode格式化 hdfs namenode -format ,初始化 只需要一次
启动这个格式化的NameNode hadoop-daemon.sh start namenode,必须跟随 不能初始化 不然造成ID不一样两个NameNode不是一个主备
在另一台NameNode中执行跟随 hdfs namenode -bootstrapStandby
格式化zookeeper
启动dfs start-dfs.sh
ssh免密 node4执行 执行后Node可以免密登录node1
ssh-keygen -t rsa -m PEM
ssh-copy-id node1
zookeeper集群 参考之前文件 我是部署在node1 node2 node3
启动 node1 node 2 node 3
hadoop-daemon.sh start journalnode
node1 格式化Namenode
hdfs namenode -format
启动
hadoop-daemon.sh start namenode
node4 同步Namenode
hdfs namenode -bootstrapStandby
可以看到两台的集群ID是一样的 说明NameNode已经正常启动主备
格式化zookeeper
查看zookeeper当前节点
zkCli.sh
ls /
执行格式化zk
hdfs zkfc -formatZK
可以看到 格式化前后 其实是多了一个hadoop-ha的节点
启动hdfs
start-dfs.sh
启动之后查看Jn数据目录 发现数据已经同步
此时 zookeeper 节点已经变化
可以看到node1抢到了锁 所以NameNode在node1是激活状态
杀掉NameNode1
节点4自动切换 ,节点1 掉线之后ZKFC释放锁,4节点通过SSH转换状态 并且抢锁成功