Hadoop 2.0 产生背景
- Hadoop1.0中的HDFS和MapReduce在高可用,扩展性等方面存在问题
- HDFS存在两个问题:
- NameNode单点故障,难以应用于在线场景 HA = 高可用
- NameNode压力过大,且内存受限,影响扩展性 F= 联邦 【脑裂】
- MapReduce 存在的问题响系统
- JobTracker访问压力大,影响系统扩展性
- 难以支持除MapReduce之外的计算框架,比如 Spark, Storm等
hadoop 1.x 与hadoop2.x
hadoop2.x由HDFS,MapReduce 和YARN三个分支构成:
- HDFS : NN Federation 联邦 HA
2.x只支持2个节点HA,3.0实现一主多从 - MapReduce 运行在YARN上的MR
- 离线计算,基于磁盘io计算
- YARN 资源管理系统
HDFS 2.X
- 解决hdfs1.0中单点故障和内存受限问题
- 解决单点故障:
- hdfs ha:通过主备NameNode解决
- 如果主NameNode发生故障,则切换到备NameNode上
- 解决内存受限个问题
- HDFS Federation联邦
- 水平扩展:支持多个NameNode
- 每个NAmeNode分管一部分目录
- 所有NameNode共享所有DataNode存储资源
- 2.x仅是架构上发生了变化,使用方式不变
- 对HDFS使用者透明
- HDFS1.x中的命令和API仍然可以使用
HDFS 2.x HA
HDFS 2.x HA
主备NameNode
解决单点故障(属性,位置)
主NameNode对外提供服务,备NameNode同步主NameNode元数据,以待切换
所有DataNode同时向两个NameNode汇报数据块信息(位置)
standby:备,完成了edits.log文件的合并产生新的image,推送回ANN
主备切换需要同步元数据,静态数据+动态数据
静态数据:edits 和fsimage 写入 由原来的Nfs(单点,可能出现单点故障) 改为 journalnode(3台服务器来同时接收)
动态数据:block的存储信息,让DataNode向两个NN发送数据
手动切换:
通过命令实现主备之间的切换,可以用HDFS升级等场合
自动切换:zookeeper 分布式协调系统
开源,基于zab协议 paxos消息传递一致性算法
在两个NameNode上zookeeper都会开辟出一个Failover Controller进程(zkfc)
zookeeper会开辟投票选举机制,在zookeeper上注册成功会创建znode,然后提供事件监控,
NameNode挂掉后,ZKFC为NameNode竞争锁,获得ZKFC 锁的NameNode变为active
zkfc会有两个作用:健康检查和选举机制,一旦主节点出现问题,主节点上的zkfc告知zookeeper消息,备节点通过zkfc委托zookeeper监控主节点,所以zookeeper在得到主节点出现问题的消息后会告知备节点(不委托不告知),此时备节点将自己的standby状态改为 active状态(函数回调=> 客户端的函数(由备节点自己决定)),此时就会有两个active节点,就会出现脑裂状况。所有需要在备节点变为active时将主节点由active改为standby状态。
HDFS 2.x Federation
通过多个namendoe/namespace把元数据的存储和管理分散到多个节点,使到namenode/namespace可以通过增加机器来进行水平扩展
能把单个namenode的负载分散大搜多个节点上,在HDFS数据规模较大的时候不会也降低HDFS的性能,可以通过多个namespace来隔离不同类型的应用,把不同类型应用的HDFS元数据的存储和管理分派到不同的namenode中
多个namenode并行工作,共同利用底层所有datanode
高可用搭建
NN-1 | NN-2 | DN | ZK | ZKFC | JNN | |
---|---|---|---|---|---|---|
Node001 | * | * | * | |||
Node002 | * | * | * | * | * | |
Node003 | * | * | * | |||
Node004 | * | * |
java安装
hadoop2.x安装java7就行,hadoop3.x需要安装java8
rpm -i
cd /usr/java/jdk1.7.0_67/
pwd # 复制
vi + /etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
PATH=$PATH:$JAVA_HOME/bin
source /etc/profile
jps # 查看java是否配置好了
免秘钥登陆
需要先安装ssh
sudo yum install ssh
sudo yum install rsync
[root@node001 ~]# cd
[root@node001 ~]# ll -a # 去找 .ssh文件夹
total 52
dr-xr-x---. 2 root root 4096 Aug 29 06:12 .
dr-xr-xr-x. 22 root root 4096 Oct 18 05:39 ..
-rw-------. 1 root root 900 Aug 29 05:42 anaconda-ks.cfg
-rw-------. 1 root root 729 Oct 18 06:01 .bash_history
-rw-r--r--. 1 root root 18 May 20 2009 .bash_logout
-rw-r--r--. 1 root root 176 May 20 2009 .bash_profile
-rw-r--r--. 1 root root 176 Sep 23 2004 .bashrc
-rw-r--r--. 1 root root 100 Sep 23 2004 .cshrc
-rw-r--r--. 1 root root 8815 Aug 29 05:42 install.log
-rw-r--r--. 1 root root 3384 Aug 29 05:41 install.log.syslog
-rw-r--r--. 1 root root 129 Dec 4 2004 .tcshrc
[root@node001 ~]# ssh node001 #如果没有ssh文件夹则自己ssh下自己, 然后就有了
The authenticity of host 'node001 (192.168.9.31)' can't be established.
RSA key fingerprint is 26:84:1e:bd:91:0b:b9:8f:9b:a5:44:f7:ff:4a:3a:a4.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added 'node001,192.168.9.31' (RSA) to the list of known hosts.
root@node001's password:
Last login: Fri Oct 18 06:10:13 2019 from 192.168.9.1
[root@node001 ~]# exit
[root@node001 ~]# ll -a
total 56
dr-xr-x---. 3 root root 4096 Oct 18 06:14 .
dr-xr-xr-x. 22 root root 4096 Oct 18 05:39 ..
-rw-------. 1 root root 900 Aug 29 05:42 anaconda-ks.cfg
-rw-------. 1 root root 743 Oct 18 06:14 .bash_history
-rw-r--r--. 1 root root 18 May 20 2009 .bash_logout
-rw-r--r--. 1 root root 176 May 20 2009 .bash_profile
-rw-r--r--. 1 root root 176 Sep 23 2004 .bashrc
-rw-r--r--. 1 root root 100 Sep 23 2004 .cshrc
-rw-r--r--. 1 root root 8815 Aug 29 05:42 install.log
-rw-r--r--. 1 root root 3384 Aug 29 05:41 install.log.syslog
drwx------ 2 root root 4096 Oct 18 06:14 .ssh
-rw-r--r--. 1 root root 129 Dec 4 2004 .tcshrc
cd .ssh
ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa # 生成秘钥
cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys #追加公钥
将公钥发给要用的所有的服务器
安装hadoop
mkdir /opt/hdp
tar xf hadoop-2.6.5.tar.gz -C /opt/hdp/
cd /opt/hdp/hadoop-2.6.5
vi + /etc/profile
增加
export HADOOP_HOME=/opt/hdp/hadoop-2.6.5
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
source /etc/profile
配置hadoop
修改java目录 /opt/hdp/hadoop-2.6.5/etc/hadoop/
vi hadoop-env.sh
#The java implementation to use.
export JAVA_HOME=/usr/java/jdk1.7.0_67
vi mapred-env.sh
export JAVA_HOME=/usr/java/jdk1.7.0_67
vi yarn-env.sh
export JAVA_HOME=/usr/java/jdk1.7.0_67
配置 core-site.xml
<configuration>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>hadoop.tmp.dir</name>
<value>/var/hdp/hadoop/ha</value>
</property>
<property>
<name>ha.zookeeper.quorum</name>
<value>node002:2181,node003:2181,node004:2181</value>
</property>
</configuration>
配置hdfs-site.xml
<configuration>
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
<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>node001:8020</value>
</property>
<property>
<name>dfs.namenode.rpc-address.mycluster.nn2</name>
<value>node002:8020</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn1</name>
<value>node001:50070</value>
</property>
<property>
<name>dfs.namenode.http-address.mycluster.nn2</name>
<value>node002:50070</value>
</property>
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node001:8485;node002:8485;node003:8485/mycluster</value>
</property>
<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>
<property>
<name>fs.defaultFS</name>
<value>hdfs://mycluster</value>
</property>
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/hdp/hadoop/ha/journalnode</value>
</property>
<property>
<name>dfs.ha.automatic-failover.enabled</name>
<value>true</value>
</property>
</configuration>
配置slaves
node002
node003
node004
分发 hdfs-site.xml 和 core-site.xml 到所有节点
scp hdfs-site.xml core-site.xml node002:pwd
scp hdfs-site.xml core-site.xml node003:pwd
scp hdfs-site.xml core-site.xml node004:pwd
给node002, node003,node004 安装zookeeper
tar xf zookeeper-3.4.6.tar.gz -C /opt/hdp/
配置zookeeper
cd /opt/hdp/zookeeper-3.4.6/conf
mv zoo_simple.cfg zoo.cfg
vi 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/hdp/zk # 创建存放目录
# 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 =node002:2888:3888
server.2 =node003:2888:3888
server.3 =node004:2888:3888
scp复制 zookeeper整个文件夹到003,004节点
然后在三个节点中执行 mkdir /var/hdp/zk
在002节点 echo 1 > /var/hdp/zk/myid
在003节点 echo 2 > /var/hdp/zk/myid
在004节点 echo 3 > /var/hdp/zk/myid
配置zookeeper的环境变量/etc/profile
export JAVA_HOME=/usr/java/jdk1.7.0_67
export HADOOP_HOME=/opt/hdp/hadoop-2.6.5
export ZOOKEEPER_HOME=/opt/hdp/zookeeper-3.4.6
PATH=$PATH:$JAVA_HOME/bin:$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$ZOOKEEPER_HOME/bin
分发给003,004
source /etc/profile.
同时启动节点002,003,004的 zookeeper
zkServer.sh start
查看状态
zkServer.sh status
会发现 004 的mode为 leader, 002,003为 follower 一主多从
服务器编号大的为主
当已经有主了,再有大的服务器启动,不变
启动journalndoe
在001,002,003 启动journalnode
hadoop-daemon.sh start journalnode
初始化hadoop
在主节点初始化
hdfs namenode -format
同步数据给另一个(必须启动journalnode 和主节点初始化后必须启动 )
主节点 hadoop-daemon.sh start namenode
从节点 hdfs namenode -bootstrapStandby
在主节点namenode执行:
hdfs zkfc -formatZK
然后启动
start-dfs.sh
完成