Hadoop自定义RecordReader
来源:互联网 发布:nginx非80端口配置 编辑:程序博客网 时间:2024/06/02 04:09
系统默认的LineRecordReader是按照每行的偏移量做为map输出时的key值,每行的内容作为map的value值,默认的分隔符是回车和换行。
现在要更改map对应的输入的<key,value>值,key对应的文件的路径(或者是文件名),value对应的是文件的内容(content)。
那么我们需要重写InputFormat和RecordReader,因为RecordReader是在InputFormat中调用的,当然重写RecordReader才是重点!
下面看代码InputFormat的重写:
[java] view plaincopy
- public class chDicInputFormat extends FileInputFormat<Text,Text>
- implements JobConfigurable{
- private CompressionCodecFactory compressionCodecs = null;
- public void configure(JobConf conf) {
- compressionCodecs = new CompressionCodecFactory(conf);
- }
- protected boolean isSplitable(FileSystem fs, Path file) {
- // CompressionCodec codec = compressionCodecs.getCode(file);
- return false;//以文件为单位,每个单位作为一个split,即使单个文件的大小超过了64M,也就是Hadoop一个块得大小,也不进行分片
- }
- public RecordReader<Text,Text> getRecordReader(InputSplit genericSplit,
- JobConf job, Reporter reporter) throws IOException{
- reporter.setStatus(genericSplit.toString());
- return new chDicRecordReader(job,(FileSplit)genericSplit);
- }
- }
下面来看RecordReader的重写:
[java] view plaincopy
- public class chDicRecordReader implements RecordReader<Text,Text> {
- private static final Log LOG = LogFactory.getLog(chDicRecordReader.class.getName());
- private CompressionCodecFactory compressionCodecs = null;
- private long start;
- private long pos;
- private long end;
- private byte[] buffer;
- private String keyName;
- private FSDataInputStream fileIn;
- public chDicRecordReader(Configuration job,FileSplit split) throws IOException{
- start = split.getStart(); //从中可以看出每个文件是作为一个split的
- end = split.getLength() + start;
- final Path path = split.getPath();
- keyName = path.toString();
- LOG.info("filename in hdfs is : " + keyName);
- final FileSystem fs = path.getFileSystem(job);
- fileIn = fs.open(path);
- fileIn.seek(start);
- buffer = new byte[(int)(end - start)];
- this.pos = start;
- }
- public Text createKey() {
- return new Text();
- }
- public Text createValue() {
- return new Text();
- }
- public long getPos() throws IOException{
- return pos;
- }
- public float getProgress() {
- if (start == end) {
- return 0.0f;
- } else {
- return Math.min(1.0f, (pos - start) / (float)(end - start));
- }
- }
- public boolean next(Text key, Text value) throws IOException{
- while(pos < end) {
- key.set(keyName);
- value.clear();
- fileIn.readFully(pos,buffer);
- value.set(buffer);
- // LOG.info("---内容: " + value.toString());
- pos += buffer.length;
- LOG.info("end is : " + end + " pos is : " + pos);
- return true;
- }
- return false;
- }
- public void close() throws IOException{
- if(fileIn != null) {
- fileIn.close();
- }
- }
- }
通过上面的代码,然后再在main函数中设置InputFormat对应的类,就可以使用这种新的读入格式了。
对于那些需要对整个文档进行处理的工作来说,还是比较有效的。
OK,下一次需要将输入文件进行split。
需求是这样的,一个文本中存放的是一些文件的路径和名称,每一行代表一个文件
如下所示:
/mkbootimg/mkbootimg.c
/logwrapper/logwrapper.c
/adb/log_service.c
/adb/adb_client.c
/adb/usb_windows.c
/adb/get_my_path_darwin.c
/adb/usb_osx.c
/adb/file_sync_service.c
/adb/file_sync_client.c
/adb/usb_linux.c
/adb/fdevent.c
/adb/usb_linux_client.c
/adb/commandline.c
/adb/remount_service.c
/adb/sockets.c
要对这些文件分别进行处理,但是整个文本中包含数十万个这种的文本,想对这些文本在处理的时候进行分布式处理。
大家有什么好的建议可以提出来:
现在的一个思路是控制分块的大小,但是这个也不是太好,想用更好的方式,例如每10000行作为一个split,这样可以通过hadoop平台实现分布式,正在做.....求指点啊!
- Hadoop自定义RecordReader
- Hadoop自定义RecordReader
- Hadoop RecordReader
- 自定义RecordReader
- Hadoop MapReduce处理海量小文件:自定义InputFormat和RecordReader
- MapReduce自定义RecordReader
- 自定义InputFormat /InputSplit/RecordReader
- Hadoop源码学习之-----Mapreduce输入流:InputFormat,InputSplit,RecordReader
- MR--RecordReader
- Hadoop内置的数据输入\输出格式与RecordReader\RecordWriter(九)
- hadoop 自定义
- InputFormat详解 -- RecordReader篇
- MapReduce之Recordreader组件
- MapReduce之RecordReader理解
- 自定义-Hadoop自定义分组Group
- Hadoop中自定义计数器
- Hadoop自定义读取文件
- Hadoop自定义InputFormat
- android UI进阶之实现listview的下拉加载
- 求1---n的阶乘之和(java)
- Android中ListView的下拉刷新
- Hadoop 自定义InputFormat实现自定义Split
- 服务器管理--安装篇
- Hadoop自定义RecordReader
- Hadoop开发常用的InputFormat和OutputFormat
- JavaScript学习笔记
- Oracle查询用户所有表的语句
- Hadoop OutputFormat浅析
- 如何学习Linux下C语言编程
- 查询SQL数据库中各表大小的存储过程
- sicily--1198. Substring
- 通过java程序打开网页接受原码并进行数据爬取(链接方式)