hadoop学习有一段时间了,但是缺乏练手的项目,老是学了又忘。想想该整理一个学习笔记啥的,这年头打字比写字方便。果断开博客,咩哈哈~~
开场白结束(木有文艺细胞)
默认的mapreduce作业
这些个默认设置都不需要显式的设置,但是需要知道默认设置的是啥,贴出来省的忘记了。要注意的是:
1) conf.setinputformat(textinputformat.class); 默认的输入格式;
2) conf.setmapoutputkeyclass(longwritable.class); conf.setmapoutputvalueclass(text.class); 默认的map输出格式,其实就是将原样输出而已;
3) conf.setpartitionerclass(hashpartitioner.class); 默认的分区函数,没有特殊操作都会使用这个了。具体算法是:return (key.hashcode()&integer.max_value)%numpartitions;
4) conf.setoutputkeyclass(longwritable.class); conf.setoutputvalueclass(text.class);还是原样输出的格式。
输入分片
一个输入分片(split)是指由单个map处理的输入块,每个map操作之处理一个输入分片。
包含一个一字节为单位的长度和一组存储位置(即一组主机名)。
inputsplit由inputformat创建。inputformat负责产生输入分片并将它们分割成记录。
fileinputformat类
所有使用文件作为其数据源的inputformat实现的基类。
提供两个功能: 1)定义哪些文件包含在一个作业的输入中;
2)未输入文件生成分片的实现。
输入分片大小: 由最小分片大小、最大分片大小、块大小决定。分片大小在[最小分片大小,最大分片大小]区间内,且取最接近块大小的值。
fileinputformat的子类:textinputformat(默认类型,键是longwritable类型,值为text类型,key为当前行在文件中的偏移量,value为当前行本身);
keyvaluetextinputformat(适合文件自带key,value的情况,只要指定分隔符即可,比较实用);
nlineinputformat(key为当前行在文件中的偏移量,value为当前行本身,和textinputformat不同的是这个类型会为每个mapper指定固定行数的输入分片,n为每个mapper收到的输入行数;
mapred.line.input.format.linespermap属性控制n的值);
sequencefileinputformat(使用sequencefile作为map的输入)。
dbinputformat类
数据库输入,在map中使用jdbc操作数据库,由于多个map将并发操作,故最好用于加载小量的数据集。操作数据库一般使用sqoop。
textoutputformat类
把每条记录写为文本行,每个键值使用制表符分割,(当然也可以使用mapred.textoutputformat.separator属性改变默认的分隔符)与textoutputformat对应的输入格式是keyvaluetextinputformat。可以用nullwritable来省略输出的键或者值(或者两个都省略,即相当于
nulloutputformat)
sequencefileoutputformat类
即以sequencefile的格式输出,如果输出需要作为后续mapreduce作业的输入,这是一种很好的输出格式。格式紧凑,容易被压缩。
(昨天弄到太晚了,代码写完直接睡了,今天上。。。)
multipleoutputformat类
这个类可以将数据写到多个文件中,比较实用。比如将输出的数据按一定的逻辑归类到不同文件中。(通常是按照输出的键或者值中的信息归类)
这个类有两个实体子类:multipletextoutputformat,属于textoutputformat的多版本文件;
multiplesequencefileoutputformat,属于sequencefileoutputformat的多版本文件。
关键点:: multipleoutputformat类提供了一些子类覆盖来控制输出文件名的protected方法(generatefilenameforkeyvalue()方法),这个方法的返回值将用来作为输出的文件名称
这里提到一点,我使用的时候开始继承的是multipletextoutputformat,但是怎么调试都无效,还是输出 part-00000文件。然后各种查资料,最后好像网上有人说hadoop0.20.0版本还是之前的版本中存在bug,必须继承multipleoutputformat类才有效。但是我装的是hadoop1.04,不过我用的仍然是老版本的api在写,不知道是否是这个原因,有大神看到的话帮忙解惑下,这里谢谢了!
下面是我继承multipleoutputformat类实现reducer输出到多个文件的代码:
这里面引用了两个帮助类:jobbuilder,ncdcrecordparser。之后的笔记中也会使用到,就一并在这里贴出来了。
jobbuilder:
ncdcrecordparser:
输出文件截个图吧:

截图中看到的是以getstationid()命名的子文件夹,在这些文件夹中是以getyear()命名的文件。
multipleoutputs类
这个类用于在原有输出基础上附加输出,输出是指定名称的,可以写到一个文件或者多个文件中。
使用这个类的静态方法addmultinamedoutput来设置输出名称,(其实是输出文件名的前缀了,后面都会加上其他数据)
需要注意的一点是,在这个静态方法中指定的名称,必须在reducer中的multipleoutputs类的实例方法 getcollector中接收,即作为这个方法的第一个参数传入,不对应的话我试了下会报错。这个报错是因为啥呢?(没找到,或者我还没理解到,以后补充吧,同时希望看到帖子的大神帮忙解惑,这里谢谢了!)
下面是实现的代码,同样使用到了上面贴出来的帮助类:
下面是运行结果截图:
截图中看到的是以"station"+getstationid()+partnum命名的文件。
上面主要介绍了mapreduce作业使用到的一些常用的输入格式,输出格式。(都是书本上的理论知识了,只能拿书本上的例子来练手,哎 苦于无项目实战,自己买机器配集群太不现实了,而且也搞不到实际需求和实际数据。悲催~~)