首先交代一下背景:
通过spring消费RMQ的数据写到hdfs,从一开始就预料到直接写textfile会有错行乱行的问题,所以一开始的方案是写parquet,经过验证后发现写parquet会有很多小文件(parquet文件落地后不能修改,不能追加),会对name node造成额外的压力,所以最终妥协写textfile 加自定义行分割符
默认的TextInputFormat在hadoop-mapreduce-client-core包里面,主要代码:
public RecordReader<LongWritable, Text> getRecordReader(
InputSplit genericSplit, JobConf job,
Reporter reporter)
throws IOException {
reporter.setStatus(genericSplit.toString());
String delimiter = job.get("textinputformat.record.delimiter");
byte[] recordDelimiterBytes = null;
if (null != delimiter) {
recordDelimiterBytes = delimiter.getBytes(Charsets.UTF_8);
}
return new LineRecordReader(job, (FileSplit) genericSplit,
recordDelimiterBytes);
}
通过源码发现可以通过textinputformat.record.delimiter这个参数指定行分隔符,经过测试发现也能实现(至于为什么还要自定义inputformat,我们后面再说)
继续往下看LineRecordReader,主要代码
public LineRecordReader(Configuration job, FileSplit split,
byte[] recordDelimiter) throws IOException {
this.maxLineLength = job.getInt(org.apache.hadoop.mapreduce.lib.input.
LineRecordReader.MAX_LINE_LENGTH, Integer.MAX_VALUE);
start = split.getStart();
end = start + split.getLength();
final Path file = split.getPath();
compressionCodecs = new CompressionCodecFactory(job);
codec = compressionCodecs.getCodec(fil