赞
踩
1.最终去开发MapReduce计算程序
2.新版本,hadoop2.x 出现了yarn:资源管理 -> MR没有后台的长服务
yarn模型:container 容器,里面会运行我们的application master,map/reduce task
目的:解耦计算程序和资源调度
MapReduce on yarn
架构:
角色:resource manager 和 node manager
搭建:将角色变成相应的活动JVM运行起来
4台服务器,分别是node01 node02 node03 node04
NN JN ZKFC ZK DN RM NM
node01 * * *
node02 * * * * * *
node03 * * * * *
node04 * * * *
在hdfs当中已经搭建了hdfs相应的角色,在hdfs中有NameNode,在第一台中有一个,第二台有一个,namenode之间的数据同步使用的是journalNode,JN同步的是日志,在一二三节点上,两个namenode HA的协调使用的是zkfc,必须和nemenode在同一节点无法控制,zkfc会依赖ZK,选择的是二三四节点。DataNode存放数据,存放在二三四。关于hdfs就这么多。
最终要跑MapReduce,先把yarn搭建出来。
yarn的两个角色ResourceManager和NodeManager
RM在hadoop2.x的时候,对HA的概念已经非常清晰了,所以需要的RM也是两个,一个active,一个standby,因为要和NameNode岔开,选择在三四节点启动RM。还有NodeManager这个长服务,NodeManager未来要产生容器container,container里面要跑计算的任务map/reduceTask,DataNode是存放数据,计算和数据在集群当中应该是1:1的关系,统称叫slaves,在哪些节点有DataNode,那些节点除了有DataNode还需要有NodeManager,如果节点没有NodeManager,那个节点只能有数据,未来是不能有container,不能有计算的。
还需要明白yarn和hdfs是两个独立的东西,是两个概念。搭建yarn和hdfs是不互相冲突的,不需要停止hdfs,是要在已有的角色之外,再不全其中yarn的角色,而且两者之间没有必然的关系,不是必须有hdfs才可以使用yarn。
通过官网:
http://hadoop.apache.org/old/
Documentation->Release 2.6.5
getting started->Single Node Setup
YARN on Single Node
You can run a MapReduce job on YARN in a pseudo-distributed mode by setting a few parameters and running ResourceManager daemon and NodeManager daemon in addition.
The following instructions assume that 1. ~ 4. steps of the above instructions are already executed.
Configure parameters as follows: etc/hadoop/mapred-site.xml: <configuration> <property> <name>mapreduce.framework.name</name> <value>yarn</value> </property> </configuration> etc/hadoop/yarn-site.xml: <configuration> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration> Start ResourceManager daemon and NodeManager daemon: $ sbin/start-yarn.sh Browse the web interface for the ResourceManager; by default it is available at: ResourceManager - http://localhost:8088/ Run a MapReduce job. When you're done, stop the daemons with: $ sbin/stop-yarn.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
在单节点模式中,加下如下的配置:
(一般来说,配置都是见名知意的)
(给MapReduce配了一个配置,这个配置叫做MapReduce平台的名字,写了yarn,能配yarn也可以写别的单词,比如local,就是一个单机的程序自己跑没有yarn什么事,一个单机JVM进程里,跑完所有计算逻辑,不是分布式的。如果写yarn,application task和map/reduce task就要在集群里,application master也是通过yarn的resource manager来启动的)
etc/hadoop/mapred-site.xml: 映射出MapReduce on yarn
<configuration>
<property>
<name>mapreduce.framework.name</name>
<value>yarn</value>
</property>
</configuration>
1
2
3
4
5
6
etc/hadoop/yarn-site.xml:
控制yarn里的nodemanager来集成一个服务,这个服务是MapReduce的shuffle,shuffle 洗牌,map -shuffle-> reduce
(map到reduce之间必须经过一个网络,所有的map跑完之后,reduce要从map这里拉取数据,这一拉取数据的过程叫做shuffle,所有的map里都包含了每个分区的数据,0号分区reduce要从所有分区里拉走属于0号分区的数据,就和打牌的时候按照花色发牌,这个就是洗牌的过程)
为什么要给nodemanager做关于shuffle的集成?
如果有几台计算机之间要互相拉取数据,想成只有一个reduce,前面有很多的map,这个reduce要和所有的map建立连接。如果未来集群很复杂的时候,有一个节点上面有3~4个reduce进程,1号分区2号分区在一个物理节点。这两个进程要和所有节点建立连接,拉取各自属于他自己的数据。从宏观上来看,这一个节点上会有很多连接向节点进行重复连接。这样会无形中开启很多TCP长连接,优化方式,由一个物理节点当中必须有的nodemanager来完成连接和拉取的协调的事情,减少资源的消耗
<configuration>
<property>
<name>yarn.nodemanager.aux-services</name>
<value>mapreduce_shuffle</value>
</property>
</configuration>
1
2
3
4
5
6
start-yarn.sh就是直接启动yarn
在集群当中就会出现resourcemanager和nodemanager
这是在单机的时候。
期望部署一个高可用完全分布式的集群,而不是单机的。
但是这两个配置是MapReduce on yarn必配的东西,不可以少的。
后面在完全分布式和HA的时候,只是在这两步之上扩展了配置。
官网继续看:
https://hadoop.apache.org/docs/r2.6.5/hadoop-yarn/hadoop-yarn-site/ResourceManagerHA.html
左边栏找到yarn->ResourceManager HA
在这里插入图片描述
思考:resource manager有active和standby,也是HA模式,一谈到分布式情况下要做HA(高可用),要做选主了,它一定会基于zookeeper,在搭建hdfs的时候,两个namenode,分别是active和standby。它们之间角色的协调是由zkfc来完成的,且zkfc用到了zookeeper。相同的HA的事,到了yarn当中,resource manager也是两台,未来也会是active和standby,却没有一个第三方进程,比如zkfc或者yarnfc之类的,缺了一个角色。
补充:
Column 1 Column 2 Column 3
hadoop 1.x 2.x
hdfs no HA ha(向前兼容,没有过多的改namenode,而是通过新增了角色 zkfc)
yarn no yarn yarn(不是新增角色,而是直接在resource manager进程中增加了ha的模块)
要明白:zkfc只负责namenode的选主和协调,切换主备的概念。
yarn好像是将曾经的namenode和zkfc合成一个东西了,软件开发的版本迭代的过程当中,哪种方式好?还是后续没有早先版本遗留问题,开发在一起更精炼,在resource manager里既有resource manager自己的代码,又有曾经的zkfc的代码放在进程里,如果resource manager活着就一定会去连接zookeeper,如果进程挂掉了,和zookeeper的连接一定会断开。曾经namenode和zkfc被隔离的时候,namenode是好的,但是zkfc可能会挂,会牵扯到降级等一系列问题。合并成一个的时候没有一个中间状态,不存在自己还活着但是他的协调挂掉了,因为他自身在协调,变得更简单了。
Sample configurations
Here is the sample of minimal setup for RM failover.
yarn.resourcemanager.ha.enabled true yarn.resourcemanager.cluster-id cluster1 yarn.resourcemanager.ha.rm-ids rm1,rm2 yarn.resourcemanager.hostname.rm1 master1 yarn.resourcemanager.hostname.rm2 master2 yarn.resourcemanager.zk-address zk1:2181,zk2:2181,zk3:2181 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 yarn-site.xml:name value
mapreduce.framework.name yarn
MapReduce on yarn单机里配的在HA或集群的时候配置项不能丢!扩展出来的是下面的配置项:
name value
yarn.resourcemanager.ha.enabled true
在resource manager里已经集成了HA模块,但是这个模块默认是false关闭的,如果想搭建一个HA有两个resource manager的话,必须要开启成true,把模块激活,这时候是resource manager里的模块而不是单独的进程。
name value
yarn.resourcemanager.zk-address node02:2181,node03:2181,node04:2181
HA一定会需要zookeeper,开启为true之后要配置zookeeper的位置,要联系zookeeper。这里是关于zookeeper的配置,把这三个zookeeper的地址给他,某一个zookeeper挂了会从另外的选择一个去连接。
以上两个配置是激活HA,且使用zookeeper的连接信息。
name value
yarn.resourcemanager.cluster-id cluster1
yarn的resourcemanager集群id,参数是一个字符串。集群id起到什么作用?因为现在是要配一个HA(高可用)的集群,里面有两个resource manager,要用到zookeeper,而zookeeper是一个复用的技术,很多人都可以拿他去做选主或分布式协调。大家使用一套zookeeper往里写东西查东西的时候,会不会覆盖差错。zookeeper也是一个目录树结构,只要有前缀(集群id)就可以作区分了。在zookeeper当中会看到一个前缀路径,未来两个resource manager就在这个集群id的目录里去争抢锁,抢到的就是active,没抢到就是standby。未来nodemanager和resourcemanager的集群id相同的话,彼此之间可以建立通信,因为在公司物理网络当中,有两套hadoop集群,两个集群id不同,两个集群里的角色是不能互相通信的。隔离的,依靠id可以区分,使用id来标识。有点像hdfs当中的namespace,在2.x的时候yarn里还没有联邦的概念,3.x的时候有了。
name value
yarn.resourcemanager.ha.rm-ids rm1,rm2
曾经的hdfs也有一个id是namenode1和namenode2,挂在了namespace下,现在等于rm1,rm2挂在了cluster1这个集群id下,等于是1对多的映射,但这两个还是逻辑的,未来resource manager HA的时候需要两台,先起两个逻辑名称,每个resource manager会有相关的属性。
name value
yarn.resourcemanager.hostname.rm1 node03
yarn.resourcemanager.hostname.rm1 node04
这里只配了其中的一部分,resource manager的主机名,rm1和rm2的,逻辑到物理的映射,注意角色的划分,选择了node03和node04,要合理的规划
经过上面这些配置,已经搞定了最简单的配置项。最终是要开发MapReduce程序,但是目前搞定的是关于yarn这个角色启动的过程。
回到集群里去,如何让集群当中出现yarn的长服务,最终可以基于yarn来跑MapReduce?在第一台节点改配置文件,向后分发,使用管理命令把角色一起启动,也是配置->启动的过程。
流程:
我hdfs等所有的都用root用户来操作的,没有生产环境复杂的用户,正常来说应该使用一个yarn用户来启动yarn相关的进程,先不考虑那么复杂的。
在node01上:
去到hadoop配置文件所在的目录:
cd $HADOOP_HOME/etc/hadoop
1
改文件名称:拷贝mapred-site.xml.template变成mapred-site.xml把后面的扩展名删掉得到绝对的名称
cp mapred-site.xml.template mapred-site.xml
1
编辑mapred-site.xml
vi mapred-site.xml
1
yarn.nodemanager.aux-services
mapreduce_shuffle
1
2
3
4
编辑yarn-site.xml,注意一定要改成自己的主机名,不要有遗漏。
vi yarn-site.xml
1
mapreduce.framework.name
yarn
yarn.resourcemanager.ha.enabled
true
yarn.resourcemanager.zk-address
node02:2181,node03:2181,node04:2181
yarn.resourcemanager.cluster-id
cluster1
yarn.resourcemanager.ha.rm-ids
rm1,rm2
yarn.resourcemanager.hostname.rm1
node03
yarn.resourcemanager.hostname.rm2
node04
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
然后将配置文件分发到另外的节点。
scp mapred-site.xml yarn-site.xml node02:pwd
scp mapred-site.xml yarn-site.xml node03:pwd
scp mapred-site.xml yarn-site.xml node04:pwd
1
2
3
然后再去想,resource manager在哪里启动配置项已经给出来的,在node03和node04,那么nodemanager在哪里启动?
这个配置项里没有去定义node manager在哪里启动,一定要明白,datanode和nodemanager都是从角色,受制于slaves文件,只要在slaves文件里配置了node02,node03,node04,未来DataNode会在这里启动,nodemanager也会在这里启动,1:1都不需要手动去设计。
vi slaves //可以不用管,搭建hdfs时候已经改过了
1
配置完成,接下来准备启动
在启动hdfs时候的命令
start-dfs.sh
1
启动yarn的命令:
start-yarn.sh
1
在这里插入图片描述这个脚本是有问题的,规划的resource manager是在node03和node04节点启动,所以他只能很好的把nodemanager启动起来,resource manager还需要手动去启动,虽然start-yarn.sh这个脚本会误把resource manager在node01节点启动,但是每个程序启动的时候,都会去读自己的配置文件,它读取配置文件发现定义的是在node03和node04启动,当前节点启动是没有意义的,所以就把自己退出了。(配置文件第一可以给管理脚本读取启动角色,第二所有角色启动的时候都要参照配置文件)
注意:看日志文件的时候不要看out文件,要看日志目录下的log文件,哪个节点的进程有问题去那个节点的日志目录下看日志,
cd /opt/hadoop/logs
ll
vi yarn-root-resourcemanager-node01.log
1
2
3
按一下大写的G,或者shift+g会到文件的最后。
在这里插入图片描述resource manager不能被初始化,配置文件不能找到有效的RM_HA_ID,读取配置文件的时候发现与自己不符了,因为没有一个ID是和自己的名称挂钩的。最终把自己给shutdown了。
resource manager未在node03和node04节点启动,可以通过node03和node04节点用jps去验证:
在这里插入图片描述在node03和node04上都只有nodemanager没有resourcemanager,需要手动在node03和node04上单独启动resource manager。
yarn-daemon.sh start resourcemanager
1
注:在启动resource manager之前,可以在node02上开一个zookeeper的客户端
zkCli.sh
1
显示zookeeper的目录结构:
ls /
1
在这里插入图片描述可以看到hdfs的前置路径hadoop-ha
启动完成后:
在这里插入图片描述可以看到yarn的选举,ls /yarn-leader-election可以看到设置的集群id(标红处为集群id)
在这里插入图片描述注意:hdfs的端口号是50070,
yarn当中resource manager端口号是8088,
启动了两个resource manager可以在浏览器中去验证:
http://node03:8088
http://node04:8088
这两个resource manager会选出一个active的。
打开了关于resource manager的webui的界面
在这里插入图片描述访问另外一台节点会显示:
在这里插入图片描述然后会重定向跳转到http://node03:8088
只会对主页跳转,可以直接访问http://node04:8088/cluster/cluster查看
在这里插入图片描述确定了现在node03是active,node04是standby
这个时候还可以验证一下HA,现在node03节点是active的,可以强硬的杀死resource manager进程。
在这里插入图片描述另外一个节点自己集成了HA,发现节点被删除了,触发重新抢锁。
在这里插入图片描述现在rm2变成active了,zookeeper有个特征锁节点是临时节点,由3000c变成b0004了,由另外一个进程resource manager抢这把锁。这里面不需要元数据同步的事情。他们的临时工作数据会写到hdfs里,hdfs就间接是一个可靠的存储层。注意:yarn是资源层不是计算层,所以他的速度和延迟有一些也是无所谓的。
再去访问node04的8088就是active了,再把node3的resource manager启动起来,node03就是standby也不会发生抢锁的过程。
在这里插入图片描述
MapReduce官方案例使用:Wordcount
实战:MR ON YARN的运行方式:
先找到一个文件,假设这里是data.txt 里面有10w行hello hadoop
再任意节点执行命令,在hdfs系统中创建一个目录 /data/wc/input 准备这个路径
hdfs dfs -mkdir -p /data/wc/input
1
在有数据的节点把数据推送上去,以1M的大小为1个块,推送data.txt文件 到刚才准备的目录
hdfs dfs -D dfs.blocksize=1047576 -put data.txt /data/wc/input
1
最终去验证是否推送成功。
在这里插入图片描述程序怎么去启动?
去到hadoop的部署目录:
cd $HADOOP_HOME
1
当中有一个目录叫share,share目录下全是jar包
cd share/
cd hadoop/
cd mapreduce/
1
2
3
里面有一个jar包是287Kb,287kb来描述一系列的分布式程序,这个数是大了还是小了。
在这里插入图片描述在集群当中的每个节点都部署了hadoop,里面都有相关的不同jar包,相应的jar包都已经铺到集群里去了。就比如做一个web网站,如果打war包的时候,把依赖的第三方的jar包都放到了启动的calssHome,可以加载的classpath那些位置,war包也可以很小。所以这里只留下了业务逻辑,jar包在集群当中都已经准备好了。
最终我们移动的是计算,而并非是数据。计算程序小,移动起来才会快。
一会儿要运行的Wordcount也就只有2~3k的大小,287k因为里面有很多的案例程序。
这时已经找到程序了。
jar包就是程序,里面会有类,类里面会有逻辑,这就是一个分布式计算程序。
程序有了,输入的数据有了,怎么把程序跑起来?
hadoop jar jarFile [mainClass(写出类的全限定名,告诉程序哪个类里面有主方法)] args…
hadoop jar hadoop-mapreduce-examples-2.6.5.jar wordcount /data/wc/input /data/wc/output
1
在输出这个维度当中,最好是一个不存在的目录。如果有数据,这个程序直接会报错,不让你跑。为什么?在分布式文件系统当中有一个目录,目录里有很多的文件,跑一个程序也不打招呼万一把里面的数据覆盖了,等于企业当中很多有价值的数据就丢失了。所有输出路径必须为空。输入可以是一个或多个,可以是目录或文件。
在这里插入图片描述在这里插入图片描述跑完之后输出路径在data/wc/output
可以看一下那个目录:
hdfs dfs -ls /data/wc/output
1
会看到有2个文件,一个文件是_SUCCESS大小为0
这个文件叫做标志文件。不存数据,只是存放了当前计算程序的状态,跑成功了。
还有个文件叫做part-r-00000
这个文件的名字中间有一个-r也可以是-m如果你的计算程序是MapReduce有结果,结果是reduce输出的,所以-r代表的是reduce输出的文件。我们的MapReduce还可以是只有map没有reduce。比如只想过滤性别为男,只留性别为女的。这时候是不需要分组统计的,只是一个过滤,就不需要有分组统计reduce拉取的事情。map拉取把所有性别为男的过滤掉,直接map输出就可以了。
所有未来如果reduce为0没有reduce,这里会出现-m,即map的输出
00000是序号,如果有两个reduce,那么0号reduce是00000,1号reduce是00001
在这里插入图片描述data.txt文件里会有10w个helllo,10w个hadoop,10w个长得不一样的数字,从1到10w。
而且在上传的时候切割成两个块,会把hello切割开。基于这样的文件来看最终的内容
hdfs dfs -cat /data/wc/output/part-r-00000
1
前面都是数字,每个数字都只会出现一次,关键是最后,单词统计的hello出现了10w次,hadoop出现了10w次,曾经看块的时候,hello被切开了, 分别在两个块了。这时候会发现,hdfs虽然死死地按照字节去切,会把数据切开,但是计算层会还原数据的特征。
在这里插入图片描述要有两个能力:
1.会去看webUI
2.会去看命令行cli
hdfs dfs -ls /data/wc/output
能看到两个文件,success是标志成功的文件,下面才是真正的数据文件
在这里插入图片描述查看文件的两种方式:
1.直接使用cat查看
2.有put就有get,可以把这个文件,获取到本地的某个目录下
hdfs dfs -cat /data/wc/output/part-r-00000
hdfs dfs -get /data/wc/output/part-r-00000 ./
1
2
抛出一个问题:
曾经上传的一个文件是
hdfs dfs -D dfs.blocksize=1047576 -put data.txt /data/wc/input
data.txt上传会切割成2个block,计算完发现数据是对的。为什么呢?后边注意听源码分析。。。
以上是简单的搭建和使用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。