Hadoop学习(3)-mapreduce快速入门加yarn的安装
mapreduce是一个运算框架,让多台机器进行并行进行运算,
他把所有的计算都分为两个阶段,一个是map阶段,一个是reduce阶段
map阶段:读取hdfs中的文件,分给多个机器上的maptask,分文件的时候是按照文件的大小分的
比如每个maptask都会处理128m的文件大小,然后有个500m的文件,就会启动ceil(500/128)个maptask
每读取文件的一行的处理,需要自己去写,注意每个maptask的处理逻辑都是一样的
处理出来的结果一定是一对key和value。
maptask里面的方法叫map(long k, string v, context); k是文件的起始偏移量,v是内容,
context是要把产生的key,value对放入的容器。
reduce阶段:每个机器上有reducetask,其作用是对maptask产生的key和value进行聚合
聚合的原则是key一样的一定分发给一个reducetask,这个操作叫做shuffle
然后把相同key的数据作为一组进行处理。最后会把结果写到hdfs里面
每有几个reducetask,就会生成几个part-r-xxxx文件
reducetask里面的方法reduce(k,value迭代器,context),k就是key,迭代器遍历每一个key相同的value,然后context就是写入hdfs里的,也是一个key和value
入门样例:wordcount
设计思路,每个maptask读取文件,
map里面k 起始偏移量没用,我们每读一行v,产生就是key是每一个单词,然后value就定为1就行,把这个key,value放入context里面
在reduce阶段,每个key相同的就会作为一组,也就是单词相同的作为一组,就统计出现几次就行。
开始在esclipe写mapreduce的业务逻辑,首先我们需要一些jar包,相关的jar包在解压出来的hadoop下的share/hadoop文件夹下
这几个文件夹下的jar包和这几个文件夹下的lib下的jar包都拷贝到esclipe再buildpath
首先编写mapper方法
package test; import java.io.ioexception; import org.apache.hadoop.io.intwritable; import org.apache.hadoop.io.longwritable; import org.apache.hadoop.io.text; import org.apache.hadoop.mapreduce.mapper; /** * keyin :是map task读取到的数据的key的类型,是一行的起始偏移量long * valuein:是map task读取到的数据的value的类型,是一行的内容string * * keyout:是用户的自定义map方法要返回的结果kv数据的key的类型,在wordcount逻辑中,我们需要返回的是单词string * valueout:是用户的自定义map方法要返回的结果kv数据的value的类型,在wordcount逻辑中,我们需要返回的是整数integer * * * 但是,在mapreduce中,map产生的数据需要传输给reduce,需要进行序列化和反序列化,而jdk中的原生序列化机制产生的数据量比较冗余,就会导致数据在mapreduce运行过程中传输效率低下 * 所以,hadoop专门设计了自己的序列化机制,那么,mapreduce中传输的数据类型就必须实现hadoop自己的序列化接口 * * hadoop为jdk中的常用基本类型long string integer float等数据类型封住了自己的实现了hadoop序列化接口的类型:longwritable,text,intwritable,floatwritable * * * * */ //第一个泛型为起始偏移量,没啥用,第二个为字符串,为读取到的一行内容,第三个,第四个为context中的key,和value,即发送给reduce的k,v对 public class wordcountmapper extends mapper<longwritable, text, text, intwritable>{ @override //重写map方法 protected void map(longwritable key, text value, context context) throws ioexception, interruptedexception { // 切单词 string line = value.tostring(); string[] words = line.split(" "); for(string word:words){ context.write(new text(word), new intwritable(1)); } } }
接下来是reduce类
package test; import java.io.ioexception; import java.util.iterator; import org.apache.hadoop.io.intwritable; import org.apache.hadoop.io.text; import org.apache.hadoop.mapreduce.reducer; //第一个,第二个为接收到的map的key,value,第三第四为写入到hdfs的key,value public class wordcountreducer extends reducer<text, intwritable, text, intwritable>{ @override //一个key,众多value的迭代器,一个context; protected void reduce(text key, iterable<intwritable> values,context context) throws ioexception, interruptedexception { int count = 0; iterator<intwritable> iterator = values.iterator(); while(iterator.hasnext()){ intwritable value = iterator.next(); count += value.get(); } context.write(key, new intwritable(count)); } }
然而我们写的程序需要提交给我们的hadoop集群去运行,而管理这个事情的就是我们的yarn
yarn是一个分布式程序的运行调度平台
yarn中有两大核心角色:
1、resource manager
接受用户提交的分布式计算程序,并为其划分资源
接收客户端要运行几个容器,进行任务调度
管理、监控各个node manager上的资源情况,以便于均衡负载
2、node manager
管理它所在机器的运算资源创建容器(cpu + 内存)
负责接受resource manager分配的任务,创建容器、回收资源
我们需要把我们的程序的jar包分发给每一个nodemanager,让他们去运行,
node manager在物理上应该跟data node部署在一起
resource manager在物理上应该独立部署在一台专门的机器上
yarn的安装
yarn我们不需要再下载了,在我们的hadoop里面已经有了yarn,我们只需要写一下配置文件就行
[root@hdp-04 ~]# vi apps/hadoop-2.8.1/etc/hadoop/yarn-site.xml
第一个指明哪一台机器当做resourcemanager,第二个指明nodemanager的任务是什么
<configuration> <!-- site specific yarn configuration properties --> <property> <name>yarn.resourcemanager.hostname</name> <value>hdp-01</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property> </configuration>
然后复制这个文件到你的其他机器上
在你的resourcemanager机器上敲 start-yarn.sh,(关闭时stop-yarn.sh)
hadoop就会启动resourcemanager,其他的nodemanager,hadoop是通过slave文件知道的(在/root/apps/hadoop-2.8.1/etc/hadoop/slaves),里面写入你的nodemanager的ip就行,一行一个。
启动之后可以敲jps看一下
或者看网页的形式,resourcemanager的端口号是8088.比如hdp-01:8088
然后安装完yarn之后嘞,我们就可以写一个java的提交任务的程序了
package test; import java.net.uri; import org.apache.hadoop.conf.configuration; import org.apache.hadoop.fs.filesystem; import org.apache.hadoop.fs.path; import org.apache.hadoop.io.intwritable; import org.apache.hadoop.io.text; import org.apache.hadoop.mapreduce.job; import org.apache.hadoop.mapreduce.lib.input.fileinputformat; import org.apache.hadoop.mapreduce.lib.output.fileoutputformat; public class jobsubmitter { public static void main(string[] args) throws exception { //在jvm中设置访问hdfs的用户身份为root,因为要对存在datanode节点的文件进行读写,不然可能会权限不够 // 构造一个访问指定hdfs系统的客户端对象: 参数1:——hdfs系统的uri,参数2:——客户端要特别指定的参数,参数3:客户端的身份(用户名) //filesystem fs = filesystem.get(new uri("hdfs://172.31.2.38:9000/"), conf, "root"); //如果是这样设置访问用户身份是不行的,因为不光是自己的客户端访问hdfs, //job还会创建自己的hdfs的对象filesystem去访问datanode,那么job创建的对象是从系统环境变量拿到的用户名,所以这样设置身份 system.setproperty("hadoop_user_name", "root"); //设置配置参数 configuration conf = new configuration(); //设置job运行时要访问的默认文件系统 conf.set("fs.defaultfs", "hdfs://172.31.2.38:9000"); //设置job要提交到那里去运行,可以是yarn,也可以是local conf.set("mapreduce.framework.name", "yarn"); //设置resourcemanager在哪 conf.set("yarn.resourcemanager.hostname", "172.31.2.38"); //如果从windows提交job,需要设置跨平台提交时,把windows中的命令,替换成linux的 //比如运行jar包中某个程序,在linux和windows是不一样的,这样可以自动转化 conf.set("mapreduce.app-submission.cross-platform","true"); //设置job job job = job.getinstance(conf); //封装jar包在windows下的位置 job.setjar("d:/wc.jar"); //设置本次job所要调用的mapper的class类和reduce的class类 job.setmapperclass(wordcountmapper.class); job.setreducerclass(wordcountreducer.class); //设置mapper实现类的产生结果的key,value类型 job.setmapoutputkeyclass(text.class); job.setmapoutputvalueclass(intwritable.class); //设置reduce实现类的产生结果的key,value类型 job.setoutputkeyclass(text.class); job.setoutputvalueclass(intwritable.class); //设置map时,job要处理的数据的路径,和产生的结果的路径在哪 fileinputformat.setinputpaths(job, new path("/wordcount/input")); //注意输出路径一定要不存在 fileoutputformat.setoutputpath(job, new path("/wordcount/output")); //设置想要启动reduce task的数量是多少 job.setnumreducetasks(2); //提交给yarn,等待这个job完成才退出 boolean res = job.waitforcompletion(true); system.exit(res?0:-1); } }
额外知识点:
maven创建报错说插件下载失败,右键项目
然后 右键属性maven,update project
把这个给点上就行了。或者进入到org/apache/maven,把里面的东西全删了,让他自己去下载。
在编程时的易错点:
注意自己写的路径file:\为windows,/为linux
注意改完源码之后,要注意重新生成一个jar包,不然提交到linux里,还是会报错
上一篇: 主DNS服务-正向解析