HDFS存在的问题:NameNode的内存受限,压力过大,影响系统拓展性;以及NameNode的单点故障问题,难以应用于在线场景!
MapReduce存在问题:
2. Hadoop 2.0产生背景
– Hadoop 1.0中HDFS和MapReduce在高可用、扩展性等方面存在问题
– HDFS存在的问题
1 NameNode单点故障,难以应用于在线场景
2 NameNode压力过大,且内存受限,影响系统扩展性
– MapReduce存在的问题
1 JobTracker访问压力大,影响系统扩展性
2 难以支持除MapReduce之外的计算框架,比如Spark、 Storm等
3. HDFS 2.x
– 解决HDFS 1.0中单点故障和内存受限问题。
– 解决单点故障
1 HDFS HA:通过主备NameNode解决
2 如果主NameNode发生故障,则切换到备NameNode上
– 解决内存受限问题
1 HDFS Federation(联邦)
2 水平扩展,支持多个NameNode;
3 每个NameNode分管一部分目录;
4 所有NameNode共享所有DataNode存储资
– 2.x仅是架构上发生了变化,使用方式不变
– 对HDFS使用者透明
– HDFS 1.x中的命令和API仍可以使用
4. HDFS的HA:
– 主备NameNode
– 解决单点故障
1 主NameNode对外提供服务,备NameNode同步主NameNode元数据,以待切换
2 所有DataNode同时向两个NameNode汇报数据块信息
– 两种切换选择
1 手动切换:通过命令实现主备之间的切换,可以用HDFS升级等场合
2 自动切换:基于Zookeeper实现
– 基于Zookeeper自动切换方案
1 Zookeeper Failover Controller:监控NameNode健康状态,
2 并向Zookeeper注册NameNode
3 NameNode挂掉后,ZKFC为NameNode竞争锁,获得ZKFC 锁
4 的NameNode变为active
5.HDFS 2.x Federation
– 通过多个namenode/namespace把元数据的存储和管理分散到多个节点中,使到namenode/namespace可以通过增加机器来进行水平扩展。
– 能把单个namenode的负载分散到多个节点中,在HDFS数据规模较大的时候不会也降低HDFS的性能。可以通过多个namespace来隔离不
同类型的应用,把不同类型应用的HDFS元数据的存储和管理分派到不同的namenode中。
2.Hadoop 2.x由HDFS、MapReduce、Yarn三部分组成;
3.HDFS2.X 的Federation:解决HDFS1.X内存受限问题!相互独立,资源共享!由HDFS2.X将元数据划分,分别掌管一部分信息,
但是DataNode节点的信息是共享的!怎么做到的?,实际中可以实现按着业务划分吗?入口是多个,
在Federation中有三个或者多个处于Active状态的NameNode有多个!
各个NameNode都要有相应的Secondary NameNode!
我们可以在java代码,做个判断,然后发给相应的Federation中对应的Namenode来运行,实现业务区分,通过命名空间划分(在NameNode)!
zookeeper集群会维护一个数据库,将内存不稳定数据放入到dataDir中,这个需要我们自己配置成实际目录!
server.1=zoo1:2888:3888(zoo1是指的主机名名字或者IP!)
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888
zkServer.sh start|status|stop|restart
4. HDFS2.X HA和Federation之间区别?
HDFS2.X的Federation和HDFS2.X的HA其实是做高可用的,两者的关系是合作的关系,其中HDFS 的Federation是解决NameNode单节点内存压力问题,而HDFS2.X的HA是解决Hadoop1.x的单节点故障问题!
说到底,无论是HDFS2.X的Federation还是HDFS2.X的HA都是解决HDFS的问题,不是解决MapReduce的问题哦!
而且我们说HDFS2.X的Federation和HDFS2.X的HA是合作的关系:实际上是指:首先通过HDFS2.X的Federation将HDFS的服务分为几个NameService(可以按着不同的业务,来分成不同的NameService,解决了HDFS的内存问题),
然后又通过HDFS2.X的HA来解决每一个NameServic单节点故障问题,当然这是通过和zookeeper合作来完成保证每一个NameServic单节点故障问题不会出现,zookeeper能够保证针对每一个NameService都会有两个NameNode或者多个NameNode(但是只有一个NameNode是处于Active的,其余的NameNode都是Standby状态的)!
所以以后就不要说Zookeeper和HDFS2.X的Federation之间的关系了,因为他们没多大关系,Zookeeper只是和HDFS2.X的HA有关系,因为HDFS2.X的HA是需要zookeeper来配合使用的!
我们在写代码的时候,只要在我们的代码中做个判断,那么不同的业务处理,就可以调用不同的NameService服务了,这样也减轻了Hadoop1.x的HDFS的单NameNode的内存压力!
当然们在一般的公司中一般情况下只会用到一个NameService就够了,所以一般公司的HDFS2.X的Federation通常不配置成几个!除非是像非常大的公司,比如阿里等等才会用到这样的多个NameService这样的配置的!(都上千台机器了)
注意:在我们不配置HDFS2.X高可用的时候,HDFS是有secondary NameNode节点的信息的(用来做备份),但是当我们用了HA(Hdfs的高可用的时候)
HDFS2.X就没有了secondary NameNode这么个信息的存在了!
2.NameNode节点的元数据文件一个也就150b,对于一些超大公司,可能真的会出现内存不够用的问题!
3.除了软件上的容灾,已经上也要有容灾!
4.HDFS的HA(针对NameNode的单点故障问题):
1.元数据必须保持一致:
fsimage+edits文件都要保持一致;
(产生的时候就要一致(在一台NameNode节点上格式化,然后拷贝到另一台上(也可以在没有格式化的namenode节点上执行一条命令,本质也是复制)),
发生变化的时候也要保持一致:这个可以将edits文件交给第三方管理(High Availability With NFS,NFS这种方式本身就存在单点故障问题,所以企业中也不会用这种方式,企业中会用High Availability With QJM这种方式,即将edits文件都交给JN(JournalNode集群节点管理),所以先启动JN集群,再执行NameNode的格式化)!
Hadop2.x的fsimage和edits文件的合并交由处于standy状态的节点来完成的!(edits文件不再从edits文件拿,而是从JN集群节点拿,JournalNode节点也是>=3的,防止自身高可用)
生产环境下,我们也不会人工监控NameNode是否有故障,所以就用到了zookeeper了!
zookeeper集群监控和管理我们的NameNode集群,在所有的NN(不管是Active和Standy上,)都有ZKFC(FailOverControllerStandby),如果zkfc看到我们的NameNode Active节点
挂掉,那么它会再将Standby的节点状态改为Active!------即监控和管理!
zookeeper本身是靠zookeeper集群内部的选举机制(且>=3的奇数个(2:1),容易分出胜负,减少分出胜负的时间,选出是不是Active,是否需要切换,以及自身高可靠,)
其实zookeeper对NN节点的管理是通过zkfc来管理的,zkfc是监控NameNode的健康状态,而Zk来完成当一个NameNode挂掉,zookeeper通过zkfc将处于standby状态的节点激活(变成Active,而且zookeeper自身高可用!)!
dataNOde的信息它也要知道)
注:NameNode格式化的时候会产生fsimage+edits文件,高可用的HDFS2.x集群将fsimage和edits文件的合并交给了standbyNamenode!
zookeeper的工作:
1).监控:最终靠ZKFC监控NameNode来实现的
2). 管理:将状态切换,也是最终靠ZKFC来实现的!
5. HA:是解决HDFS的问题,不是解决MapReduce的问题对吧?
是的,无论是HDFS2.x的HA和HDFS2.x的Federation都是用来解决Hadoop1.x的HDFS的单节点的内存和单节点故障问题的,这两个都是针对HDFS的,不是针对MapReduce的!
3.High Availability With QJM
<property>
<name>dfs.nameservices</name>
<value>mycluster</value>
</property>
命名服务配置nameSERVICE:要求 值为字母和数字的组合,但是开头必须为字母,可以都是字母
4.<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node1.example.com:8485;node2.example.com:8485;node3.example.com:8485/mycluster</value>
</property>
这里注意:端口是journalNode端口8485;书写以qjournal://开头,以/mycluster(Nameservice的值哦)结尾;各个journalNode节点的配置之间用分号隔开!zookeeper端口是2181;
6.手动删掉masters文件(每台)-----因为这个文件中的信息是用来指定Secondary NameNode节点在哪台机子上运行的!
7.zookeeper要先启用,再执行格式化(目的就是将HDFS高可用信息在zookeeper的启动之后,再写入zookeeper中),然后再启动集群
8.两台NN之间一定要做免秘钥,不是不直接通信嘛?
他们之间是有通信的,所以我们也要配置这两个之间的免密码登录的!
9.http://zookeeper.apache.org/doc/r3.4.9/zookeeperStarted.html地址:
10.rpc通信协议和http协议之间的区别?
rpc协议在Hadoop这里其实也就是上传和下载,http协议其实在Hadoop这里也就是通过页面访问的!
dfs.journalnode.edits.dir必须为空或者不存在!
zookeeper 的2888和3888都是干嘛的?
zookeeper对外提供服务的端口是2181,zookeeper内部之间互相通信的接口是2888,zookeeper集群选举的端口号是3888!
NN DN JN ZK ZKFC
node1 1 1 1
node2 1 1 1 1 1
node3 1 1 1
node4 1 1
1、时间同步
yum install ntp
ntpdate -u s1a.time.edu.cn
date
网络 hosts 防火墙关闭。。。
2、jdk1.7
3、上次 解压
4、免密钥
node1到 node1-4
node2到 node1-4
两台NN 之间一定要做免密钥
$ ssh-keygen -t dsa -P '' -f ~/.ssh/id_dsa
$ cat ~/.ssh/id_dsa.pub >> ~/.ssh/authorized_keys
a-->b
a公钥文件 拷贝到b 再把a的公钥文件内容 追加到b的authorized_keys
5、修改配置文件
!!!1.x当中创建的masters文件 一定要保证每台服务器都删除
export HADOOP_HOME=
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
hadoop-env.sh 中的 JAVA_HOME
core-site.xml hadoop.tmp.dir <>/opt/hadoop</> !!保证每台服务器该目录不存在或者为空目录
hdfs-site.xml
slaves 指定DN
(zookeepper在三台)都要装,然后export到PATH
6、!!!同步配置文件
7、启动JN 三台node2、3、4上执行 hadoop-deamon.sh start journalnode(JournalNode集群先启动是为了记录NameNode节点格式化生成的fsimage文件和edits文件)
8、格式化NN 在一台NN上 node1 hdfs namenode -format
9、同步 其他没有格式化的NN上执行 node2 hdfs namenode -bootstrapStandby(在此之前先启动node1 :hadoop-daemon.sh startnamenode,要不然没法同步! )
10、启动ZK集群 三台zk node1、2、3执行 zkServer.sh start(最好这三台的启动同时执行,如果只有一个leader,其余都是follower,说明启动没有问题,万一有问题,就在执行命令的文件夹下查看生成的zookeeper.out文件)
11、格式化zk 在一台NN(注意哦:这里是在NameNode节点上执行的哦)上执行 node1 hdfs zkfc -formatZK(zookeeper格式化是在zookeeper启动之后再执行是为了HDFS的高可用信息在zookeeper集群中保存,所以在此之前要先启动Zookeeper集群,最后将Zookeeper集群格式化!)
12、启动 start-dfs.sh(NameNode在Zookeeper之后启动是为了在NameNode启动的时候zookeeper集群就可以监控的到NameNode的信息)
注:zookeeper格式化会将配置的NameService放入到zookeeper文件系统(zookeeper换个角度也可以看成类似文件系统)中,zookeeper文件系统的目录也可以存数据(ZNODE)!,同时也要注意不要NameNode的高可用的Nameservice和Yarn的高可用的NameService设置成一致的,因为都是会存到Zookeeper的内存文件系统中的,有冲突!
再启动:(这里一定要重新启动哦,因为此时如果不重新启动,高可用是不怎么好用的,有可能多台NameNode都会变为Standby状态的NameNode!)
1、启动zk集群 三台zk node1、2、3执行 zkServer.sh start
2、启动 start-dfs.sh
综上:以后先启动zookeeper集群,再启动dfs就可以了!
集群搭建完了之后先jps自己检验一下,是否正常!
区分开active NameNode 和standyBy namenode在页面的区别!
停掉active namenode,再看standby namenode状态变化!
再启动Active NameNode 看状态!
搭建完成后重启集群
stop-dfs.sh
记住:当我们配置了环境之后,在linux命令中就可以linux系统的任意命令行打命令的时候,会有自动补全功能,而且也不用我们自己非得跑到应用程序的安装目录的bin目录下!
上面都是针对HDFS文件系统的!
====================================================================================================
下面都是针对MapReduce的!
1.MapReduce执行的四个核心步骤
1.一个很大的文件先split-------------------------->map----------------------------->shuffle--------------------------->reduce!
2.复杂的MapReduce:链式MapReduce的!
注:Map是一行一行的读,Map端是不会做map任务的累加的,因为有可能文本的第一个和文本的最后一个相加,当这样的文件多了之后,这就会造成内存的严重让费!
reduce也不是一下子接收文件的,它是通过迭代器一点点拿的!
3.我们也可以控制MapReduce的Split的大小!(MapReduce现在是按着128M执行的)
默认就是一个HDFS的一个块大小,也就是每个split默认都是一个块文件!可以配置允许map并行执行多个任务!
每一个map任务都是针对多个split的吧?每一个Map是可以运行多个split的!
reduce的数目可以在mapred-site.xml文件中设置,默认值是1;但是一般保持默认,因为这是全局性的,但是我们自己写程序的时候,可以通过job.setNumberTask()(来指定)
MapReduce的 Split大小
– max.split(100M)
– min.split(10M)
– block(64M)
– max(min.split,min(max.split,block))
4.
下载软件的时候要下载稳定版本+兼容性(最好这两个条件要同时满足)好的,所以我们一般不会下载最新的软件使用!--自己搭建大数据架构的时候就要考虑这些问题了!
我们用的是Hadoop2.5.x而不是用Hadoop2.7.x是因为:http://hbase.apache.org/book.html#basic.prerequisites这个路径下可以查看,版本选择问题!
5.MapReduce设计理念
– 何为分布式计算。
– 移动计算,而不是移动数据。
6. Mapper
– Map-reduce的思想就是“分而治之”
Mapper负责“分”,即把复杂的任务分解为若干个“简单的任务”执行
– “简单的任务”有几个含义:
数据或计算规模相对于原任务要大大缩小;
就近计算,即会被分配到存放了所需数据的节点进行计算;
这些小任务可以并行计算,彼此间几乎没有依赖关系
7.Hadoop计算框架Reducer
– 对map阶段的结果进行汇总。
– Reducer的数目由mapred-site.xml配置文件里的项目mapred.reduce.tasks决定。缺省值为1,用户可以覆盖之
8.Hadoop计算框架Shuffler
– 在mapper和reducer中间的一个步骤
– 可以把mapper的输出按照某种key值重新切分和组合成n份,把key值符合某种范围的输出送到特定的reducer那里去处理(其实分组什么的都是通过操做key来实现的!)
– 可以简化reducer过程
9.读API,一般也就是从一个小Demo开始,然后再这么做下去!
10.Spark的待遇很高的,好好学!
11.Hadoop计算框架的Shuffler(以前我们说过MapReduce是移动计算而不是移动数据,但是这里有可能会移动数据)
12.shuffle的group位置?
分区和reduce有关,关系到由哪个reduce处理!分区的默认计算公式:key hash值%Reduce个数 ==0,1,2三种情况
分区和分组(二次sort)的关系:
Map端默认的(sort)排序:根据字典对每个map(即一个split数据块)内部排序,当然我们可以覆写!hash值来排序的!
注意:合并的过程中也会保证排序,按着sort的字典规则排序!
Map端内存的溢出是溢出到本地磁盘还是HDFS中,这里应该是HDFS上,但是同时也是在这个数据块(split)所在的节点上!
Reduce端排序(sort)也叫分组(group):默认的排序对多个map也是:字典规则排序!
顺序:split--->map任务--》partition -->sort-->combiner(在map端做一次统计,针对每个map任务,针对某个key,
不能代替reduce,因为它只是针对一个map任务输出,但是在某些特定的情况下可以优化网络问题,先reduce一下,reduce是针对全局的,所有的map)-----》在reduce端执行前也会合并-------》然后执行reduce操作
分区,分组,以及combiner啥的都是针对key而言的!
13.MemoryBuffer默认是100M,阈值是0.8;即达到内存的80M的时候,就会发生Map任务的溢写!
14.DataNode和NodeManager一般要在一个节点上:因为MapReduce的设计就是移动计算而不是移动数据!
15.Zookeeper集群维护了一个内存数据库(内存类文件系统)!
注:zookeeper格式化会将配置的NameService放入到zookeeper文件系统(zookeeper换个角度也可以看成类似文件系统)中,zookeeper文件系统的目录也可以存数据(ZNODE)!,同时也要注意不要NameNode的高可用的Nameservice和Yarn的高可用的NameService设置成一致的,因为都是会存到Zookeeper的内存文件系统中的,有冲突!
16.zookeeper执行的时候在其执行命令的地方会生成zookeeper的.out文件,看出错信息就可以解决问题!貌似这个日志文件的位置和HDFS日志的地方不一样(HDFS日志是在Hadoop的安装目录的logs文件夹下!)
这两天我们做了配置NameNode的高可用和Yarn的高可用!
17.我们配置ResourceManager的时候,我们并没有专门配置NodeManager,这是因为我们配置了slaves文件,这个文件中的内容即是datanode节点也是nodemanager来看!
从节点nodemanager,datanode是不存在单点故障,是通过副本和主节点的调度再分配实现的!
ResourceManager,NameNode服务是在两台机子都启动的,只是有一个是standby状态的,但是都要提供服务,standby状态的也必须提供服务,防止Active的NameNode或者NodeManager出现问题!
NN DN JN ZK ZKFC RS NM(NodeManager)
node1 1 1 1
node2 1 1 1 1 1 1
node3 1 1 1 1 1
node4 1 1 1 1
1.Map是一行一行的读,Reduce是靠迭代器读数据的!
分区的规则:默认是(partition),分区的默认计算公式:key hash值%Reduce个数 ==0,1,2三种情况
Map端的排序(sort):默认是按着字典规则排序!
combiner:默认是没有的,需要我们自己写:网络,即reduce计算复杂度!
Reduce端的排序(group):默认是按着字典规则排序!
reduce端:
18.各个UI和服务的端口号总结:=========================??????????????????
在我们Eclipse配置连接的时候,一般配置的都是rpc的端口号!(存活的主NameNode的IP或者域名:端口号(RPC协议的端口号哦))
但是在我们访问Hadoop页面的时候都是访问的是HTTP的端口号!,
那么如何查看我们到底看哪个口号呢?这时候就需要查看文档了!看我们的配置文件,我们配置的HTTP-Address的端口号就是我们要访问的地址!
如果我们没有配置这些HTTP的端口号,那么我们就必须查看官方文档了,官方文档中会有默认的端口号!无论是HTTP的还是RPC通信的端口号,都有默认值!
集群搭建完了之后先jps自己检验一下配置的各个服务,是否启动正常!
1.区分开active NameNode 和standyBy namenode在页面的区别!
直接通过active NameNode 和standyBy namenode的 ip:端口号 的形式来访问;(ip也可以换成域名,如果要用域名,就要在本地的windows的hosts文件中进行ip和域名的映射,端口号通过看配置文件和文档来看)
停掉active namenode,再看standby namenode状态变化!
再启动Active NameNode 看状态!
再次直接通过active NameNode 和standyBy namenode的 ip:端口号 的形式来访问;
区分开active ResourceManager 和standyBy ResourceManager在页面的区别!
直接通过active ResourceManager 和standyBy ResourceManager ip:端口号 的形式来访问;(ip也可以换成域名,如果要用域名,就要在本地的windows的hosts文件中进行ip和域名的映射,端口号通过看配置文件和文档来看)
停掉active ResourceManager,再看standby ResourceManager状态变化!
再启动Active ResourceManager 看状态!
再次直接通过active ResourceManager 和standyBy ResourceManager ip:端口号 的形式来访问;
检查zookeeper是否正常启动的命令为:
zkServer.sh start 在各台zokeeper安装节点先启动zookeeper集群!
zkServer.sh status 然后用于查看zookeeper集群的状态 (如果有多个follower,1个leader就说明是正确的)
各种启动命令总结:
配置了HA的高可用之后,
我们只需要先在zookeeper安装的各个节点上先启动zookeeper
即:zkServer.sh start (此时可以先检查一下zookeeper.sh status看看状态是否正确)
然后在执行start-dfs.sh (此时NameNode,DataNode,zkfc,journalNode的信息)--->因为配置了高可用,就没有secondary NameNode了!倒是有两个甚至多个NameNode!
如果我们也配置ResoucerManager的话,我们就不要用start-dfs.sh命令启动集群了,
我们就用start-all.sh启动集群!(当然我们也要先启动zookeeper集群!),然后
我们还需要在装resourcemanager的两台或者多台执行yarn-daemon.sh start resourcemanager!
上述命令:只需要按着倒序将start改为stop就可以关闭了!
21.start-all.sh的bug需要我们自己手动去yarn-daemon.sh start resourcemanager?是的,是这样的,然后通过jps来检查一下!
19.只用一行代码指定namenode处于Active的就行?是的,因为这里我们用的是nameservice!
conf.set("fs.defaultFS", "hdfs://node1:8020");
20.hdfs-site.xml文件中的
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node02:8485;node03:8485;node04:8485/chinahrt</value>
</property>
这个属性用于指定哪几台主机是JournalNode节点!
21.和eclipse做结合的时候,要导入hadoop2.5.x的jar包,jar包包含:(这里只要是Hadoop2.5.x版本的jar包都可以)
hadoop-2.5.2\hadoop-2.5.2\share\hadoop 的common,hdfs,tools目录下的jar包,以及这些目录中的lib包下的所有的jar包都加入到eclipse的依赖包中(通过build path!)