搭建集群的模式有三种

	1.伪分布式:在一台服务器上,启动多个线程分别代表多个角色(因为角色在集群中使用进程表现的)
	2.完全分布式:在多台服务器上,每台服务器启动不同角色的进程,多台服务器构成集群
	3.高可用的完全分布式

本次搭建是在完全分布式的基础上搭建的,完全分布式请看 完全分布式的搭建.

.

  • 首先为什么会提出高可用的完全分布式呢?
    因为以往的架构,毕竟是单节点(namenode),虽有SNN为其承担部分功能(持久化到本地),但SNN毕竟不是namenode,当namenode禁不住大量用户的请求(汇报)挂掉之后,SNN并不能承担起来namenode的功能
  • 高可用的完全分布式对比完全分布式有什么区别?
    高可用的完全分布式没有了SNN节点,多了JournalNode集群、ZooKeeper集群和ZKFC,还有一个备用NameNode(standby)它来实现SNN的功能,并作为active NN的热备。

如图所示

hadoop集群环境搭建之高可用的完全分布式集群环境搭建

  • Standby NameNode的作用
    - 作为Active NameNode的热备,当其崩溃时,快速地切换为Active NameNode
    - 充当SNN的角色,从JournalNode集群中拿到最新的edits文件进行重演合并后形成FSImage推送给Active NameNode
  • JournalNode集群的作用
    -存储由Active NameNode发送的edits文件
  • Zookeeper集群的作用
    - 来监控Active NameNode的健康状态,当其挂掉后选取新的Active NameNode,但是Active NameNode很忙没法发送自己的状态,所有又有了ZKFC
    - 当Active NameNode挂掉之后,他会想Standby NameNode节点的ZKFC发送一条信息,让ZKFC把Standby NameNode变为Active NameNode
  • ZKFC的作用
    -主动监控两个NN的状态,同时与Zookeeper相连
    -根据Zookeeper的指令对NN进行状态的改变

架构的几个问题

  1. 为什么要使用JournalNode集群而不是JournalNode节点?
    - 数据安全
    - 以防JournalNode节点挂掉导致数据的丢失
  2. 既然Active NN与Standby NN会发生状态的变化,如何保证他们之间的数据同步,才能无缝地对外服务呢?
    - 他们通过JournalNode来实现edits文件的共享,Standby NameNode重演合并后的FSImage推送给Active NN保证两者的元数据信息一致。
  3. Active NameNode在向JournalNode集群中上传edits文件时是否提供服务?
    - 不会
    - 当NameNode上传Edits文件至JournalNode集群节点的半数以上时(并行写入edits文件),而不是上传到所有的节点,这样效率太低
  4. 为什么Active Name Node要提交到JournalNode集群的半数以上的节点?
    -JournalNode集群中有个势力范围的概念,当Journal Node集群因为网卡的原因无法同信,就会分裂成几个组织,当每个组织的节点数小于势力范围时,就会自杀,为了保证只有一个JournalNode集群,把势力范围定为半数以上的节点数
    -这样才会使Standby NN一直读取到最新的edits文件

.
hadoop集群环境搭建之高可用的完全分布式集群环境搭建

hadoop集群环境搭建之高可用的完全分布式集群环境搭建

.
hadoop集群环境搭建之高可用的完全分布式集群环境搭建
hadoop集群环境搭建之高可用的完全分布式集群环境搭建

.

当两个ZFKC都挂掉之后,此时这个集群相当于孤立了Zookeeper集群,当Active NN挂掉之后,需要手动把Standby NN 变为Active NN.hadoop集群环境搭建之高可用的完全分布式集群环境搭建
.
.
.

现在了解了高可用的完全分布式的架构之后,我们开始搭建它的环境,首先是四台虚拟机分别代表的角色如下表

Active NameNode Standby NameNode DataNode Zookeeper ZKFC JournalNode
node01 - - -
node02 -
node03 - - -
node04 - - - -

1.在完全分布式的基础上,需要配置node02对于node01的面密码登陆

node02上运行
ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
因为node02有一种操作是node02的ZKFC把node01的active NN关闭,所以需要免密登陆

2.删除之前四台虚拟机的所有hadoop包,我们重新配置

重新解压后修改以下配置文件
hdfs-site.xml

<property>
	<!--两个NN的逻辑名-->
 	<name>dfs.nameservices</name>
 	<value>mycluster</value>
</property>
<property>
  <!--两个NN的名字-->
  <name>dfs.ha.namenodes.mycluster</name>
  <value>nn1,nn2</value>
</property>
<property>
  <!--Active NN的别名-->
  <name>dfs.namenode.rpc-address.mycluster.nn1</name>
  <value>node01:8020</value>
</property>
<property>
  <!--Standby NN的别名-->
  <name>dfs.namenode.rpc-address.mycluster.nn2</name>
  <value>node02:8020</value>
</property>
<property>
	<!--Active NN的地址-->
  <name>dfs.namenode.http-address.mycluster.nn1</name>
  <value>node01:50070</value>
</property>
<property>
<!--Standby NN的地址-->
  <name>dfs.namenode.http-address.mycluster.nn2</name>
  <value>node02:50070</value>
</property>
<property>
  <name>dfs.namenode.shared.edits.dir</name>
  <value>qjournal://node01:8485;node02:8485;node03:8485/mycluster</value>
</property>
<property>
  <!--JournalNode保存edits文件的地址-->
  <name>dfs.journalnode.edits.dir</name>
  <value>/var/sxt/hadoop/ha/jn</value>
</property>
<property>
<!--代理,来区分两个NN-->
  <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>
<!--拿自己的私钥去连接node01-->
  <name>dfs.ha.fencing.ssh.private-key-files</name>
  <value>/root/.ssh/id_rsa</value>
</property>
<property>
<!--打开ZKFC-->
   <name>dfs.ha.automatic-failover.enabled</name>
   <value>true</value>
 </property>

core-site.xml

<property>
   <name>fs.defaultFS</name>
   <value>hdfs://mycluster</value>
</property>
<property>
   <name>ha.zookeeper.quorum</name>
   <value>node02:2181,node03:2181,node04:2181</value>
</property>
 <!-- 指定hadoop运行时产生临时文件的存储目录 -->
<property>
        <name>hadoop.tmp.dir</name>
        <value>/var/abc/hadoop/local</value>
</property>

slaves

node02
node03
node04

hadoop-env.sh

sudo vim ${HADOOP_HOME}/etc/hadoop/hadoop-env.sh


# 修改JAVA_HOME的环境配置为如下所示:

export JAVA_HOME=/opt/software/jdk1.8.0_151

把配置好的Hadoop包发送给每台机器
.

2.搭建Zookeeper集群

1.解压Zookeeper压缩包
2.修改conf路径下的zoo_sample.cfg为zoo.cfg
3.更改zoo.cfg的内容
4.记住zoo.cfg中的路径:dataDir=/var/zxj/zookeeper
5.在此路径下创建myid文件,在这个文件中写上当前节点ID号
6.将配置好的zookeeper安装包拷贝到node03 node04
7.拷贝完毕后,在各自节点上创建myid号,ID号要依次递增

zoo.cfg

# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
dataDir=/var/zxj/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
server.1=node02:2888:3888
server.2=node03:2888:3888
server.3=node04:2888:3888

创建myid文件例如:

 vim /var/zxj/zookeeper/myid
 	1

发送给node03,node04

scp -r zookeeper node03:`pwd`
scp -r zookeeper node04:`pwd`

搭建好后,在其的bin目录下,运行./zkServer.sh start 开启zookeeper集群
.

3.启动的流程

1.在node01、02、03中先开启Journal Node。hadoop-daemon.sh start journalnode
		为什么在NN初始化之前启动它,因为NN初始化产生的edits要放在JournalNode中
2.选择一台Active NN进行格式化,hdfs namenode -format
3.启动此NN,hadoop-daemon.sh start namenode
4.在standby NN中同步Active NN的数据,hdfs namenode  -bootstrapStandby
5.初始化ZKFC,hdfs zkfc -formatZK
6.关闭所有进程,stop-dfs.sh
7.启动:start-dfs.sh

相关文章: