自定义hadoop map/reduce输入文件切割InputFormat 更改输入value的分隔符

MapReduce自定义行分隔符 编写mapreduce程序时,发现默认对文件的输入是采用每行(\n)进行分割,能不能实现采用自定义行分割符的方式比如采用“|-|\n”作为行分割符呢 来看看hadoop默认是怎样实现的: public class TextInputFormat extends FileInputFormat<LongWritable, Text> { @Override public RecordReader<LongWritable, Text> createRecord 阅读详情

本文转载自:http://hi.baidu.com/lzpsky/blog/item/99d58738b08a68e7b311c70d.html  


hadoop会对原始输入文件进行文件切割,然后把每个split传入mapper程序中进行处理,FileInputFormat是所有以文件作 为数据源的InputFormat实现的基类,FileInputFormat保存作为job输入的所有文件,并实现了对输入文件计算splits的方 法。至于获得记录的方法是有不同的子类进行实现的。

        那么,FileInputFormat是怎样将他们划分成splits的呢?FileInputFormat只划分比HDFS block大的文件,所以如果一个文件的大小比block小,将不会被划分,这也是Hadoop处理大文件的效率要比处理很多小文件的效率高的原因。 

       hadoop默认的InputFormat是TextInputFormat,重写了FileInputFormat中的createRecordReader和isSplitable方法。该类使用的reader是LineRecordReader,即以回车键(CR = 13)或换行符(LF = 10)为行分隔符。

    start += in.readLine(new Text(), 0,  
                                 (int)Math.min((long)Integer.MAX_VALUE, end - start));  
          } //这个按行读取就是响应的回车及换行  

      但大多数情况下,回车键或换行符作为输入文件的行分隔符并不能满足我们的需求,通常用户很有可能会输入回车键、换行符,所以通常我们会定义不可见字符(即用户无法输入的字符)为行分隔符,这种情况下,就需要新写一个InputFormat。

      又或者,一条记录的分隔符不是字符,而是字符串,这种情况相对麻烦;还有一种情况,输入文件的主键key已经是排好序的了,需要hadoop做的只是把相 同的key作为一个数据块进行逻辑处理,这种情况更麻烦,相当于免去了mapper的过程,直接进去reduce,那么InputFormat的逻辑就相 对较为复杂了,但并不是不能实现。

1、改变一条记录的分隔符,不用默认的回车或换行符作为记录分隔符,甚至可以采用字符串作为记录分隔符。
     1)自定义一个InputFormat,继承FileInputFormat,重写createRecordReader方法,如果不需要分片或者需要改变分片的方式,则重写isSplitable方法,具体代码如下:

  1. public class FileInputFormatB extends FileInputFormat<LongWritable, Text> {  
  2.    @Override  
  3.    public RecordReader<LongWritable, Text> createRecordReader( InputSplit split, TaskAttemptContext context) {  
  4.         <span style="color:#ff0000;">return new SearchRecordReader("\b");</span>  
  5.     }  
  6.     @Override  
  7.     protected boolean isSplitable(FileSystem fs, Path filename) {  
  8.         <span style="color:#ff6666;"> // 输入文件不分片  
  9.         return false;</span>  
  10.      }  
  11. }  
这里的“\b“应该就是指定的分隔符,并要求不对单个文件进行分片处理。
2)关键在于定义一个新的SearchRecordReader继承RecordReader,支持自定义的行分隔符,即一条记录的分隔符。标红的地方为与hadoop默认的LineRecordReader不同的地方。

  1. private CompressionCodecFactory compressionCodecs = null;  
  2.  private long start;  
  3.  private long pos;  
  4.  private long end;  
  5.  private LineReader in;  
  6.  private int maxLineLength;  
  7.  private LongWritable key = null;  
  8.  private Text value = null;  
  9. <span style="color:#ff0000;"> //行分隔符,即一条记录的分隔符  
  10.  private byte[] separator = {'\b'};  
  11.  private int sepLength = 1;  
  12. ‍ public IsearchRecordReader(){  
  13.  }  
  14.  public IsearchRecordReader(String seps){//赋值的分隔符  
  15.   this.separator = seps.getBytes();   
  16.   sepLength = separator.length;  
  17.  }</span>  
  18.  public void initialize(InputSplit genericSplit, TaskAttemptContext context) throws IOException {  
  19.   FileSplit split = (FileSplit) genericSplit;  
  20.   Configuration job = context.getConfiguration();<span style="color:#ff6666;">//获取对应的配置文件</span>  
  21.   this.maxLineLength = job.getInt("mapred.linerecordreader.maxlength", Integer.MAX_VALUE);  
  22.   this.start = split.getStart();<span style="color:#ff6666;">//分片的起始位置</span>  
  23.   this.end = (this.start + split.getLength());<span style="color:#ff6666;">//split的结尾</span>  
  24.   Path file = split.getPath();<span style="color:#ff6666;">//获得路径</span>  
  25.   this.compressionCodecs = new CompressionCodecFactory(job);  
  26.   CompressionCodec codec = this.compressionCodecs.getCodec(file);  
  27.   // open the file and seek to the start of the split  
  28.   FileSystem fs = file.getFileSystem(job);  
  29.   FSDataInputStream fileIn = fs.open(split.getPath())<span style="color:#ff6666;">;//打开分片数据</span>  
  30.   boolean skipFirstLine = false;  
  31.   if (codec != null) {  
  32.    this.in = new LineReader(codec.createInputStream(fileIn), job);  
  33.    this.end = Long.MAX_VALUE;  
  34.   } else {  
  35.    if (this.start != 0L) {  
  36.     skipFirstLine = true;  
  37.    <span style="color:#ff6666;"> this.start -= sepLength;//改变分隔符需要修改的地方</span>  
  38.     fileIn.seek(this.start);  
  39.    }  
  40.    this.in = new LineReader(fileIn, job);  
  41.   }  
  42.   if (skipFirstLine) { // skip first line and re-establish "start".  
  43.    int newSize = in.readLine(new Text(), 0, (int) Math.min( (long) Integer.MAX_VALUE, end - start));  
  44.      
  45.    if(newSize > 0){  
  46.     start += newSize;  
  47.    }  
  48.   }  
  49.   this.pos = this.start;  
  50.  }  
  51.  public boolean nextKeyValue() throws IOException {  
  52.   if (this.key == null) {  
  53.    this.key = new LongWritable();  
  54.   }  
  55.   this.key.set(this.pos);  
  56.   if (this.value == null) {  
  57.    this.value = new Text();  
  58.   }  
  59.   int newSize = 0;  
  60.   while (this.pos < this.end) {  
  61.    newSize = this.in.readLine(this.value, this.maxLineLength, Math.max(  
  62.  (int) Math.min(Integer.MAX_VALUE, this.end - this.pos), this.maxLineLength));  
  63.    if (newSize == 0) {  
  64.     break;  
  65.    }  
  66.    this.pos += newSize;  
  67.    if (newSize < this.maxLineLength) {  
  68.     break;  
  69.    }  
  70.    LOG.info("Skipped line of size " + newSize + " at pos " + (this.pos - newSize));  
  71.   }  
  72.   if (newSize == 0) {  
  73.    <span style="color:#ff6666;">//读下一个buffer</span>  
  74.    this.key = null;  
  75.    this.value = null;  
  76.    return false;  
  77.   }  
  78.   //读同一个buffer的下一个记录  
  79.   return true;  
  80.  }  
  81.  public LongWritable getCurrentKey() {  
  82.   return this.key;  
  83.  }  
  84.  public Text getCurrentValue() {  
  85.   return this.value;  
  86.  }  
  87.  public float getProgress() {  
  88.   if (this.start == this.end) {  
  89.    return 0.0F;  
  90.   }  
  91.   return Math.min(1.0F, (float) (this.pos - this.start) / (float) (this.end - this.start));  
  92.  }  
  93.  public synchronized void close() throws IOException {  
  94.   if (this.in != null)  
  95.    this.in.close();  
  96.  }  
  97. }  

 3)重写SearchRecordReader需要的LineReader,可作为SearchRecordReader内部类。特别需要注意的地方就 是,读取文件的方式是 按指定大小的buffer来读, 必定就会遇到一条完整的记录被切成两半,甚至如果分隔符大于1个字符时分隔符也会被切成两半的情况, 这种情况一定要加以拼接处理。

  1. public class LineReader {  
  2.   //回车键(hadoop默认)  
  3.   //private static final byte CR = 13;  
  4.   //换行符(hadoop默认)  
  5.   //private static final byte LF = 10;  
  6.       
  7.   //按buffer进行文件读取  
  8.   private static final int DEFAULT_BUFFER_SIZE = 32 * 1024 * 1024;<span style="color:#ff6666;">//32M</span>  
  9.   private int bufferSize = DEFAULT_BUFFER_SIZE;  
  10.   private InputStream in;  
  11.   private byte[] buffer;  
  12.   private int bufferLength = 0;  
  13.   private int bufferPosn = 0;  
  14.     
  15.   LineReader(InputStream in, int bufferSize) {  
  16.    this.bufferLength = 0;  
  17.     this.bufferPosn = 0;  
  18.         
  19.    this.in = in;  
  20.    this.bufferSize = bufferSize;  
  21.    this.buffer = new byte[this.bufferSize];  
  22.   }  
  23.   public LineReader(InputStream in, Configuration conf) throws IOException {  
  24.    this(in, conf.getInt("io.file.buffer.size", DEFAULT_BUFFER_SIZE));  
  25.   }  
  26.   public void close() throws IOException {  
  27.    in.close();  
  28.   }  
  29.  public int readLine(Text str, int maxLineLength) throws IOException {  
  30.    return readLine(str, maxLineLength, Integer.MAX_VALUE);  
  31.   }  
  32.   public int readLine(Text str) throws IOException {  
  33.    return readLine(str, Integer.MAX_VALUE, Integer.MAX_VALUE);  
  34.   }  
  35.   <span style="color:#ff6666;">//以下是需要改写的部分_start,核心代码</span>  
  36. <span style="color:#ff6666;">  public int readLine(Text str, int maxLineLength, int maxBytesToConsume) throws IOException{//map函数中使用到得readline</span>  
  37.    str.clear();  
  38.    Text record = new Text();  
  39.    int txtLength = 0;  
  40.    long bytesConsumed = 0L;  
  41.    boolean newline = false;  
  42.    int sepPosn = 0;  
  43.      
  44.    do {  
  45.     //已经读到buffer的末尾了,读下一个buffer  
  46.     if (this.bufferPosn >= this.bufferLength) {  
  47.      bufferPosn = 0;  
  48.      bufferLength = in.read(buffer);  
  49.        
  50.     <span style="color:#ff6666;"> //读到文件末尾了,则跳出,进行下一个文件的读取,</span><span style="color:#009900;">那这个时候算是新的splits吗?</span>  
  51.      if (bufferLength <= 0) {  
  52.       break;  
  53.      }  
  54.     }  
  55.       
  56.     int startPosn = this.bufferPosn;  
  57.     for (; bufferPosn < bufferLength; bufferPosn ++) {  
  58.     <span style="color:#ff6666;"> //处理上一个buffer的尾巴被切成了两半的分隔符(如果分隔符中重复字符过多在这里会有问题)</span>  
  59.      if(sepPosn > 0 && buffer[bufferPosn] != separator[sepPosn]){  
  60.       sepPosn = 0;  
  61.      }  
  62.        
  63.      //遇到行分隔符的第一个字符  
  64.      if (buffer[bufferPosn] == separator[sepPosn]) {  
  65.       bufferPosn ++;  
  66.       int i = 0;  
  67.         
  68.       //判断接下来的字符是否也是行分隔符中的字符  
  69.       for(++ sepPosn; sepPosn < sepLength; i ++, sepPosn ++){  
  70.          
  71.        //buffer的最后刚好是分隔符,且分隔符被不幸地切成了两半  
  72.        if(bufferPosn + i >= bufferLength){  
  73.         bufferPosn += i - 1;  
  74.         break;  
  75.        }  
  76.          
  77.        //一旦其中有一个字符不相同,就判定为不是分隔符  
  78.        if(this.buffer[this.bufferPosn + i] != separator[sepPosn]){  
  79.         sepPosn = 0;  
  80.         break;  
  81.        }  
  82.       }  
  83.         
  84.       //的确遇到了行分隔符  
  85.       if(sepPosn == sepLength){  
  86.        bufferPosn += i;  
  87.        newline = true;  
  88.        sepPosn = 0;  
  89.        break;  
  90.       }  
  91.      }  
  92.     }  
  93.       
  94.     int readLength = this.bufferPosn - startPosn;  
  95.     bytesConsumed += readLength;  
  96.     //行分隔符不放入块中  
  97.     //int appendLength = readLength - newlineLength;  
  98.     if (readLength > maxLineLength - txtLength) {  
  99.      readLength = maxLineLength - txtLength;  
  100.     }  
  101.     if (readLength > 0) {  
  102.      record.append(this.buffer, startPosn, readLength);  
  103.      txtLength += readLength;  
  104.        
  105.      //去掉记录的分隔符  
  106.      if(newline){  
  107.       str.set(record.getBytes(), 0, record.getLength() - sepLength);  
  108.      }  
  109.     }  
  110.    } while (!newline && (bytesConsumed < maxBytesToConsume));  
  111.    if (bytesConsumed > (long)Integer.MAX_VALUE) {  
  112.     throw new IOException("Too many bytes before newline: " + bytesConsumed);  
  113.    }  
  114.      
  115.    return (int) bytesConsumed;  
  116.   }  
  117.   //以下是需要改写的部分_end  
  118. //以下是hadoop-core中LineReader的源码_start  
  119. public int readLine(Text str, int maxLineLength, int maxBytesToConsume) throws IOException{  
  120.     str.clear();  
  121.     int txtLength = 0;  
  122.     int newlineLength = 0;  
  123.     boolean prevCharCR = false;  
  124.     long bytesConsumed = 0L;  
  125.     do {  
  126.       int startPosn = this.bufferPosn;  
  127.       if (this.bufferPosn >= this.bufferLength) {  
  128.         startPosn = this.bufferPosn = 0;  
  129.         if (prevCharCR)  bytesConsumed ++;  
  130.         this.bufferLength = this.in.read(this.buffer);  
  131.         if (this.bufferLength <= 0)  break;  
  132.       }  
  133.       for (; this.bufferPosn < this.bufferLength; this.bufferPosn ++) {  
  134.         if (this.buffer[this.bufferPosn] == LF) {  
  135.           newlineLength = (prevCharCR) ? 2 : 1;  
  136.           this.bufferPosn ++;  
  137.           break;  
  138.         }  
  139.         if (prevCharCR) {  
  140.           newlineLength = 1;  
  141.           break;  
  142.         }  
  143.         prevCharCR = this.buffer[this.bufferPosn] == CR;  
  144.       }  
  145.       int readLength = this.bufferPosn - startPosn;  
  146.       if ((prevCharCR) && (newlineLength == 0))  
  147.         --readLength;  
  148.       bytesConsumed += readLength;  
  149.       int appendLength = readLength - newlineLength;  
  150.       if (appendLength > maxLineLength - txtLength) {  
  151.         appendLength = maxLineLength - txtLength;  
  152.       }  
  153.       if (appendLength > 0) {  
  154.         str.append(this.buffer, startPosn, appendLength);  
  155.         txtLength += appendLength; }  
  156.     }  
  157.     while ((newlineLength == 0) && (bytesConsumed < maxBytesToConsume));  
  158.     if (bytesConsumed > (long)Integer.MAX_VALUE) throw new IOException("Too many bytes before newline: " + bytesConsumed);  
  159.     return (int)bytesConsumed;  
  160.   }  
  161. //以下是hadoop-core中LineReader的源码_end  
  162. }  

2、已经按主键key排好序了,并保证相同主键key一定是在一起的,假设每条记录的第一个字段为主键,那么如 果沿用上面的LineReader,需要在核心方法readLine中对前后两条记录的id进行equals判断,如果不同才进行split,如果相同继 续下一条记录的判断。代码就不再贴了,但需要注意的地方,依旧是前后两个buffer进行交接的时候,非常有可能一条记录被切成了两半,一半在前一个buffer中,一半在后一个buffer中。

     这种方式的好处在于少去了reduce操作,会大大地提高效率,其实mapper的过程相当的快,费时的通常是reduce。

hadoop编程小技巧(5)---自定义输入文件格式类InputFormat Hadoop代码测试环境:Hadoop2.4应用:在对数据需要进行一定条件的过滤和简单处理的时候可以使用自定义输入文件格式类。Hadoop内置的输入文件格式类有:1)FileInputFormat这个是基本的父类,我们自定义就直接使用它作为父类;2)TextInputFormat这个是默认的数据格式类,我们一般编程,如果没有特别指定的话,一般都使用的是这个;key代表当前行数据距离文件开始的距离, 阅读详情

相关推荐

mapreduce 自定义分隔符源码

自定义分隔符读取源码,改编自LineRecordReader,主要处理格式复杂的日志

hadoop学习:各类key value分隔符参数

hadoop中的map-reduce是处理这样的键值对,故指定的分割符等参数可以分成三类:map输出时分割符分桶时的分隔符reduce输出时的分割符 下面分别叙述:1. map输出时分割符参数:stream.map.output.field.separator作用:指定map输出时的分割符stream.num.map.output.key.fields

snowzl的专栏 1960

MediaPipe实战:从零构建人脸关键点检测应用

本文详细介绍了如何使用Google的MediaPipe框架从零构建一个实时人脸关键点检测应用。文章深入剖析了MediaPipe的三段式检测流水线,提供了Android平台的完整实战教程,包括环境配置、模型加载、摄像头集成、关键点绘制以及性能调优指南,帮助开发者快速实现高效、跨平台的人脸AR特效与交互功能。

weixin_29100927的博客 341

bootstrap-tagsinput 修改分隔符. 修改css长度等

bootstrap-tagsinput 修改分隔符. 修改css长度等

qq_43114196的博客 456

CAN开发笔记(TI开发者推荐笔记)

查阅了很多资料没有查阅到关于5728芯片CAN模块寄存器的介绍,希望通过本文能给做CAN驱动的后来者有一点参考意义,我也是刚接触CAN模块有些不足请各位多多指正。 由下图所示是CAN模块初始化流程图 首先要开始初始化,设置CAN位时间,然后配置message objects, 完成初始化。 1.开始初始化 首先要控制DCAN_CTL 寄存器,该寄存器是CAN模块的总控制器,很多配置通过...

weixin_44316996的博客 3562

用STM32的SPI接口读取MT6835磁编码器,手把手教你避开数据读取的坑

本文详细介绍了如何使用STM32的SPI接口读取MT6835磁编码器,并提供了21个实战细节与避坑指南。从硬件连接、SPI配置到数据解析和实时调试,全面解析了读取位置信息过程中的常见问题及解决方案,帮助工程师在工业控制、伺服电机等场景中高效应用AMR技术。

weixin_30729609的博客 1441

Hadoop Job失败解决

现象:map 某个task始终实行失败,直到超时,attemp task重试四次,最后task失败 查看jobtracker发现每次都是固定的task,找到该task所在节点,查看log,搜索该taskid 如:   cat hadoop-hadoop-tasktracker-DB1221.log.2012-06-26 | grep attempt_201206081842_0456_m_...

hacker_zhb的博客 887

基于dify平台批量分析excel格式信息

如何以表格形式批量输入一些信息,然后让大模型以对话应用形式逐条进行推理分析?请逐行分析以下数据,给出推理结果:{{input}}这里提供一个分步解决方案,结合。

knightissocool的博客 8011

自定义 hadoop MapReduce InputFormat 切分输入文件

2019独角兽企业重金招聘Python工程师标准>>> ...

weixin_33966095的博客 264

【屠龙之术】SAP 欧洲公司 高级合规性报表 FEC

所谓FEC ,其实是法国税务局要求法国的公司,每年要向税务局进行提交的税务报告,这个报告有特殊的格式,进行加密,法国公司要在收到税务局通知以后,及时进行报送,如果不报送,或者报送不合格文件,将面临5000欧的罚款。-----------------------------------------------进入正文----------------------------------------------------------------------有专门的T-code,PPT我就不贴了,我直接截图。

竹大的博客 1960

ComfyUI-controlnet控制出图

提供加载预处理器节点。

Bu2n的博客 5494

Hadoop源码解析之: TextInputFormat如何处理跨split的行

我们知道hadoop将数据给到map进行处理前会使用InputFormat对数据进行两方面的预处理: 对输入数据进行切分,生成一组split,一个split会分发给一个mapper进行处理。 针对每个split,再创建一个RecordReader读取Split内的数据,并按照&lt;key,value&gt;的形式组织成一条record传给map函数进行处理。 最常见的FormatInput...

nayao-net 651

多智能体强化学习中的Trust Region技术:HATRPO与HAPPO深度解析

本文深度解析多智能体强化学习中的Trust Region技术,重点探讨HATRPO(异质智能体信任区域策略优化)与HAPPO(异质智能体近端策略优化)两种先进算法。通过数学架构与工程实现细节,揭示其在解决联合策略空间爆炸、信用分配等挑战中的优势,并分享实际部署中的优化技巧与前沿进展。

weixin_29072299的博客 191

hive报错 Too many bytes before newline: 2147483648

2.Too many bytes before newline ,这个报错可能是hive源码里有的报错信息,我们看下这个报错的具体位置,可能是有些属性需要我们额外去配置,或者其他问题,看源码总是好的。就和内存一样 hive的有些参数默认是比较保守的,可以适当调大点,就避免很多报错了。此时已经怀疑是最后一条数据有问题了,但是没证据咋办。但是如果是一个年迈的程序员,一眼就可以看出这个数字很熟悉,比如我 哈哈。看了下大概就是读取每一行的数据,并且获取大小,对大小有个判断。

cclovezbf的博客 1848

YOLO26引入ECA-Net的改进版变体:1D卷积在2026目标检测的极致压榨

摘要: 2026年发布的YOLO26通过移除DFL模块、支持无NMS推理等革新成为边缘计算新标杆。为进一步提升性能,研究聚焦轻量级通道注意力机制ECA-Net,其核心创新在于用1D卷积替代传统全连接层,仅需5个参数即可实现高效通道交互。数学分析表明,ECA模块在ResNet50上仅增加80个参数,却能带来2%以上的精度提升。这种"极致压榨"的设计理念与YOLO26的轻量化特性高度契合,为在几乎不增加计算开销的前提下提升模型性能提供了可行方案。技术验证显示,该组合在COCO数据集上实现了检测精度与推理效率的双

ZDQ58818的博客 262

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Hadoop MapReduce中如何处理跨行Block和UnputSplit

Hadoop的初学者经常会疑惑这样两个问题:1.Hadoop的一个Block默认是64M,那么对于一个记录行形式的文本,会不会造成一行记录被分到两个Block当中?2.在把文件从Block中读取出来进行切分时,会不会造成一行记录被分成两个InputSplit,如果被分成两个InputSplit,这样一个InputSplit里面就有一行不完整的数据,那么处理这个InputSplit的Mapper会...

olylakers的博客 270

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

旧版API的TextInputFormat源码分析

TextInputFormat类package org.apache.hadoop.mapred; import java.io.*; import org.apache.hadoop.fs.*; import org.apache.hadoop.io.LongWritable; import org.apache.hadoop.io.Text; import org.apache.h...

weixin_30480651的博客 136

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

自定义hadoop map/reduce输入文件切割InputFormat

        hadoop会对原始输入文件进行文件切割,然后把每个split传入mapper程序中进行处理,FileInputFormat是所有以文件作为数据源的InputFormat实现的基类,FileInputFormat保存作为job输入的所有文件,并实现了对输入文件计算splits的方法。至于获得记录的方法是有不同的子类进行实现的。         那么,FileInpu...

十万小时之旅 197

如何拓展Hadoop的InputFormat为其他分隔符

在Hadoop中,常用的TextInputFormat是以换行符作为Record分隔符的。 在实际应用中,我们经常会出现一条Record中包含多行的情况,例如: 123doc>..../doc>此时,需要拓展TextInputFormat以完成这个功能。先来看一下原始实现:Java

每天积累一点,一年后你会发现,自己变化很大 738

hadoop常见错误及解决办法!

1:Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-out  Answer: 程序里面需要打开多个文件,进行分析,系统一般默认数量是1024,(用ulimit -a可以看到)对于正常使用是够了,但是对于程序来讲,就太少了。 修改办法: 修改2个文件。        /etc/security/limits.

沉底的石头 1万+

mapreduce 自定义key/value 输出分隔符

mapreduce 默认情况下 key/value 分隔符为:“\t” 测试的输出如下: 我们可以在代码中进行设置来自定义 key/value 输出分隔符:在代码中添加如下一行代码: conf.set("mapred.textoutputformat.separator", ";"); //此处以”;“作为分割符,后边介绍为什么这么修改 修改代码后,测试修改结果:

静心 5926

hadoop2.6.0中自定义分割符

最近在学习hadoop,用的hadoop2.6.0 然后在学习编写mapreduce程序时,发现默认对文件的输入是采用每行进行分割,下面来分析下改变这个分割方式的办法: 来看看默认是怎样实现的: 如果不使用Job的setInputFormatClass()设置,默认的InputFormat类是使用TextInputFormat类 TextInputFormat类是继承自FileInpu...

weixin_30520015的博客 201

hadoop自定义InputFormat

本文转自:http://www.randyho.com/?p=41   接触hadoop一年多了,但是自己一直没有用hadoop写过什么程序。最近,由于项目需要,将一些文件转换成hadoop的MapFile。网上的例子基本是直接处理文本输入,自定义输入格式的见到两个,但是都是用的旧的API,用新API写的还没有,可能高手不屑于写这些。但是处理自定义输入是每个用hadoop的人都要学会才行的,因...

guoguoyang2008的专栏 191
上一篇: MapReduce 新旧API
下一篇: 复杂指针
codestinity
博客等级 码龄16年 29粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值