一、规划角色
TIPS:
- ZKFC和NN成对出现
- NN:独享硬件
- ZK:单独一个集群
二、ZK配置(在node02、node03、node04上安装ZK)
1、解压
2、配置环境变量(node02、node03、node04都配置,配置完成记得加载profile文件)
vi /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
export HADOOP_HOME=/opt/hadoop-2.6.5
export ZOOKEEPER_HOME=/opt/zookeeper-3.4.6
export PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin
3、配置ZK
cp zoo_sample.cfg zoo.cfg
dataDir=/var/zookeeper
clientPort=2181
server.1=192.168.224.12:2888:3888
server.2=192.168.224.13:2888:3888
server.3=192.168.224.14:2888:3888
创建目录并将自己的数字写入myid
mkdir -p zookeeper
echo 1 > zookeeper/myid
4、ZK原理
zk运行时有两个状态,一个可用(有主模型),一个不可用(无主模型)。
zk工作在主从模型,一个leader,多个follower,follower提交增删改的操作给leader,leader是单点,当leader挂掉,即无法提供服务,此时进入无主模型,将进行选举,选出新的leader对外提供服务。
当leader挂掉,然后选举,再恢复,官方压测结果为200ms。端口2888用于有主模型,端口3888用于无主模型。
过半机制:
一半写成功即成功,不为强一致性,损失可用性。在事务决策和选举时,一半成功即成功。
如何选举:
- 看zxid(事务id)
数据版本的id,谁的更全,更大,谁就是leader
- 看serverid
server.1、server.2、server.3三个数字,当无主模型下,哪个数字大,哪个就是leader。
5、分发ZK到node03、node04,并配置myid
scp -r ./zookeeper-3.4.6/ node03:`pwd`
scp -r ./zookeeper-3.4.6/ node04:`pwd`
mkdir -p zookeeper
echo 2 > zookeeper/myid
mkdir -p zookeeper
echo 3 > zookeeper/myid
6、启动ZK
启动node02(因为过半机制,三台机器需要启动两台才能进入有主模式)
启动node03(此时,选举完成,node03是leader,node02是follower)
启动node04(此时,毫无意外,node04是follower)
三、配置Hadoop
1、备份完全分布式配置文件
2、配置NameNode(逻辑到物理的映射)
vi hdfs-site.xml
<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>node01:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>node02:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>node01:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>node02:50070</value>
</property>
TIPS:SecondaryNameNode的配置不再需要,它的功能由StandbyNameNode实现了。
3、配置JournalNode
vi hdfs-site.xml
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value>
</property> #JournalNode的位置、数据目录
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/hadoop/ha/jn</value> #持久化数据存放目录
</property>
TIPS:
- NN和JN的通信
- 管理脚本启动JN
- 使用JN的数据目录
4、故障转移的实现和代理
vi hdfs-site.xml
<property>
<name>dfs.client.failover.proxy.provider.mycluster</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<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_dsa</value>
</property>
5、配置ZKFC
vi hdfs-site.xml
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
6、配置HDFS客户端的路径和数据存放目录
vi core-site.xml
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/hadoop/ha</value>
</property>
7、在Hadoop中配置Zookeeper
vi core-site.xml
<property>
<name>ha.zookeeper.quorum</name>
<value>node02:2181,node03:2181,node04:2181</value>
</property>
8、往node02、node03、node04分发hadoop配置
9、免密钥
9.1、场景:
- 管理节点给其他节点分发,node01到其他节点
- ZKFC免秘钥,node01到自己,node01到node02,node02到自己,node02到node01。
9.2、创建秘钥(node01、node02、node03、node04):
ssh-keygen -t dsa -P '' -f /root/.ssh/id_dsa
- -t:类型
- -P:密码
- -f:文件生成路径(公钥)
- ls -a:显示隐藏文件
9.3、对自己免密钥(node01、node02):
cat id_dsa.pub >> authorized_keys
9.4、对其他节点免秘钥(node01对node02、node03、node04)(node02对node01):
9.4.1、秘钥分发到node02、node03、node04
scp id_dsa.pub node02:`pwd`/node01.pub
scp id_dsa.pub node03:`pwd`/node01.pub
scp id_dsa.pub node04:`pwd`/node01.pub
9.4.2、将node01的秘钥添加到node02、node03、node04的授权文件
cat node01.pub >> authorized_keys(node02、node03、node04)
9.4.3、将node02的秘钥发给node01
9.4.4、将node02的秘钥添加到node01的授权文件
9.4.5、测试
四、部署
1、启动JournalNode(node01、node02、node03)
hadoop-daemon.sh start journalnode
TIPS:
JN里面保存了edits,格式化需要清理的内容
2、格式化并启动其中一台NameNode(看到successfully formatted表示格式化成功)
hdfs namenode -format
hadoop-daemon.sh start namenode
3、另外一台NameNode以Standby方式启动(去同步第一台NameNode元数据)
hdfs namenode -bootstrapStandby
TIPS:
此时不对ZK格式化并启动ZK,工作模式就是半自动HA。
4、ZKFC格式化ZK(其实就是在zk下创建一个节点,不会影响到其他的HDFS集群)
hdfs zkfc -formatZK
5、查看ZK
6、启动HDFS
start-dfs.sh
7、查看各个节点的角色
8、查看ZK
9、查看图像化界面
五、验证HA
1、手动杀死node01的NameNode
访问http://node01:50070和http://node02:50070,发现node01无法访问,node02升级为Active。
ZK的目录锁也变成node02的
2、恢复node01的NameNode
hadoop-daemon.sh start namenode
访问http://node01:50070和http://node02:50070,发现node01为Standby,node02为Active。
3、手动杀死node02的ZKFC
访问http://node01:50070和http://node02:50070,发现node01升级为Active,node02降级为Standby。
ZK的目录锁也变成node01的
4、恢复node02的ZKFC
hadoop-deamon.sh start zkfc
六、停止HDFS
stop-dfs.sh