CAP(一致性Consistency,可用性Availability,分区性Partitions)
-
既要提升系统的可用性
-
又要保证数据的实时可见
-
还有提升系统的容错能力
在分布式系统中,无法保证同时满足CAP
Hadoop 2.x版本Federation和HA分离,HA只能有两个NameNode用于解决单点故障
HDFS HA:通过主备NameNode解决
如果主NameNode发生故障,则切换到备NameNode上。
解决内存受限问题
HDFS Federation(联邦);水平扩展,支持多个NameNode;
(1)所有NameNode共享所有DataNode存储资源
(2)每个NameNode分管一部分目录;
下图为Hadoop HA的框架图:
- 一个NameNode进程处于Active状态,另1个NameNode进程处于Standby状态。Active的NameNode负责处理客户端的请求。
- Active的NN修改了元数据之后,会在JNs的半数以上的节点上记录这个日志。Standby状态的NameNode会监视任何对JNs上edit log的更改。一旦edits log出现更改,Standby的NN就会根据edits log更改自己记录的元数据。
-
当发生故障转移时,Standby主机会确保已经读取了JNs上所有的更改来同步它本身记录的元数据,然后由Standby状态切换为Active状态。
-
为了确保在发生故障转移操作时拥有相同的数据块位置信息,DNs向所有NN发送数据块位置信息和心跳数据。
- JNs只允许一台NameNode向JNs写edits log数据,这样就能保证不会发生“脑裂”。
- ZKFC监控NameNode健康状态,并向Zookeeper注册NameNode。NameNode挂掉后,ZKFC为NameNode竞争锁,获得ZKFC 锁的NameNode变为active
Hadoop HA搭建架构:
node1 | node2 | node3 | node4 |
NameNode1 | NameNode2 | ||
DataNode1 | DataNode2 | DataNode3 | |
ZooKeeper1 | Zookeeper2 | Zookeeper3 | |
ZKFC1 | ZKFC2 | ||
JNN1 | JNN2 | JNN3 |
1、给每台服务器配置免秘钥登录
2、配置jdk环境,记得修改/etc/profile
3、修改hadoop环境(/etc/profile)
4、修改zookeeper环境(/etc/profile)配置完成之后输入zkServer. 按table键可出现补齐
5、配置zookeeper,打开文件夹/opt/zookeeper-3.4.6/conf
将zoo_sample.cfg复制一份改名为zoo.cfg即 cp zoo_sample.cfg zoo.cfg
打开zoo.cfd
将dataDir修改为:
dataDir=/var/bjsxt/zookeeper/data
在clientPort下面一行加入: clientPort是客户端连接zookeeper时用的端口
server.1=node2:2881:3881 #3881是交换选举信息,选出一个leader
server.2=node3:2881:3881 #通过2881进行投票表决信息
server.3=node4:2881:3881
mkdir -p /var/bjsxt/zookeeper/data
echo 1 > /var/bjsxt/zookeeper/data/myid
scp -r /opt/zookeeper-3.4.6/ node3:/opt && scp -r /opt/zookeeper-3.4.6/ node4:/opt
scp /etc/profile node3:/etc/ && scp /etc/profile node4:/etc/
node3:
mkdir -p /var/bjsxt/zookeeper/data
echo 2 > /var/bjsxt/zookeeper/data/myid
node4:
mkdir -p /var/bjsxt/zookeeper/data
echo 3 > /var/bjsxt/zookeeper/data/myid
在node3、node2、node4上以此顺序运行如下代码:
zkServer.sh start
zkServer.sh status
可看出node3是leader,node2跟node4是follower
6、配置hadoop
打开/opt/hadoop-2.6.5/etc/hadoop/slaves
将localhost修改为
node2
ndoe3
node4
打开/opt/hadoop-2.6.5/etc/hadoop/hadoop-env.sh
将JAVA_HOME修改为:export JAVA_HOME=/usr/java/jdk1.8.0_221-amd64
打开/opt/hadoop-2.6.5/etc/hadoop/core-site.xml
在configuration标签内加入
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/bjsxt/hadoop/ha</value>
</property>
<!-- 指定每个zookeeper服务器的位置和客户端端口号 -->
<property>
<name>ha.zookeeper.quorum</name>
<value>node2:2181,node3:2181,node4:2181</value>
</property>
启动HA:
启动zookeeper:
zkServer.sh statrt
启动journalnode:
hadoop-daemon.sh start journalnode
node1格式化NameNode:
hdfs namenode -format
node1启动namenode:
hadoop-daemon.sh start namenode
node2格式化namenode:
hdfs namenode -bootstrapStandby
从namenode1上同步数据。
node2启动namenode:
hadoop-daemon.sh start namenode
node4上输入:
zkCli.sh #进入zookeeper
node2上输入:
hdfs zkfc -formatZK
namenode上输入可直接启动:
start-dfs.sh
也可以自己写一段脚本启动HA
#!/bin/bash
for node in node2 node3 node4
do
ssh $node ". /etc/profile; zkServer.sh start"
done
sleep 1
start-dfs.sh
echo "--------------node1-jps------------------"
jps
for node in node2 node3 node4
do
echo "--------------$node-jps------------------"
ssh $node "source /etc/profile; jps"
done
写一段脚本停止HA:
#!/bin/bash
stop-dfs.sh
sleep 1
for node in node2 node3 node4
do
ssh $node "source /etc/profile; zkServer.sh stop"
done
echo "--------------node1-jps------------------"
jps
for node in node2 node3 node4
do
echo "--------------$node-jps------------------"
ssh $node "source /etc/profile; jps"
done